[BACK]Return to tc-tic30.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils.old / dist / gas / config

Annotation of src/external/gpl3/binutils.old/dist/gas/config/tc-tic30.c, Revision 1.1.1.4

1.1       christos    1: /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
1.1.1.4 ! christos    2:    Copyright (C) 1998-2018 Free Software Foundation, Inc.
1.1       christos    3:    Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
                      4:
                      5:    This file is part of GAS, the GNU Assembler.
                      6:
                      7:    GAS is free software; you can redistribute it and/or modify
                      8:    it under the terms of the GNU General Public License as published by
                      9:    the Free Software Foundation; either version 3, or (at your option)
                     10:    any later version.
                     11:
                     12:    GAS is distributed in the hope that it will be useful,
                     13:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15:    GNU General Public License for more details.
                     16:
                     17:    You should have received a copy of the GNU General Public License
                     18:    along with GAS; see the file COPYING.  If not, write to the Free
                     19:    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
                     20:    02110-1301, USA.  */
                     21:
                     22: /* Texas Instruments TMS320C30 machine specific gas.
                     23:    Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
                     24:    Bugs & suggestions are completely welcome.  This is free software.
                     25:    Please help us make it better.  */
                     26:
                     27: #include "as.h"
                     28: #include "safe-ctype.h"
                     29: #include "opcode/tic30.h"
                     30:
                     31: /* Put here all non-digit non-letter characters that may occur in an
                     32:    operand.  */
                     33: static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
1.1.1.3   christos   34: static const char *ordinal_names[] =
1.1       christos   35: {
                     36:   N_("first"), N_("second"), N_("third"), N_("fourth"), N_("fifth")
                     37: };
                     38:
                     39: const char comment_chars[]        = ";";
                     40: const char line_comment_chars[]   = "*";
                     41: const char line_separator_chars[] = "";
                     42:
                     43: const char *md_shortopts = "";
                     44: struct option md_longopts[] =
                     45: {
                     46:   {NULL, no_argument, NULL, 0}
                     47: };
                     48:
                     49: size_t md_longopts_size = sizeof (md_longopts);
                     50:
                     51: /* Chars that mean this number is a floating point constant.
                     52:    As in 0f12.456
                     53:    or    0d1.2345e12.  */
                     54: const char FLT_CHARS[] = "fFdDxX";
                     55:
                     56: /* Chars that can be used to separate mant from exp in floating point
                     57:    nums.  */
                     58: const char EXP_CHARS[] = "eE";
                     59:
                     60: /* Tables for lexical analysis.  */
                     61: static char opcode_chars[256];
                     62: static char register_chars[256];
                     63: static char operand_chars[256];
                     64: static char space_chars[256];
                     65: static char identifier_chars[256];
                     66: static char digit_chars[256];
                     67:
                     68: /* Lexical macros.  */
                     69: #define is_opcode_char(x)     (opcode_chars     [(unsigned char) x])
                     70: #define is_operand_char(x)    (operand_chars    [(unsigned char) x])
                     71: #define is_register_char(x)   (register_chars   [(unsigned char) x])
                     72: #define is_space_char(x)      (space_chars      [(unsigned char) x])
                     73: #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
                     74: #define is_digit_char(x)      (digit_chars      [(unsigned char) x])
                     75:
                     76: const pseudo_typeS md_pseudo_table[] =
                     77: {
                     78:   {0, 0, 0}
                     79: };
                     80:
                     81: static int ATTRIBUTE_PRINTF_1
                     82: debug (const char *string, ...)
                     83: {
                     84:   if (flag_debug)
                     85:     {
                     86:       char str[100];
1.1.1.2   christos   87:       va_list argptr;
1.1       christos   88:
1.1.1.2   christos   89:       va_start (argptr, string);
1.1       christos   90:       vsprintf (str, string, argptr);
1.1.1.2   christos   91:       va_end (argptr);
1.1       christos   92:       if (str[0] == '\0')
                     93:        return (0);
                     94:       fputs (str, USE_STDOUT ? stdout : stderr);
                     95:       return strlen (str);
                     96:     }
                     97:   else
                     98:     return 0;
                     99: }
                    100:
                    101: /* Hash table for opcode lookup.  */
                    102: static struct hash_control *op_hash;
                    103: /* Hash table for parallel opcode lookup.  */
                    104: static struct hash_control *parop_hash;
                    105: /* Hash table for register lookup.  */
                    106: static struct hash_control *reg_hash;
                    107: /* Hash table for indirect addressing lookup.  */
                    108: static struct hash_control *ind_hash;
                    109:
                    110: void
                    111: md_begin (void)
                    112: {
                    113:   const char *hash_err;
                    114:
                    115:   debug ("In md_begin()\n");
                    116:   op_hash = hash_new ();
                    117:
                    118:   {
                    119:     const insn_template *current_optab = tic30_optab;
                    120:
                    121:     for (; current_optab < tic30_optab_end; current_optab++)
                    122:       {
                    123:        hash_err = hash_insert (op_hash, current_optab->name,
                    124:                                (char *) current_optab);
                    125:        if (hash_err)
                    126:          as_fatal ("Internal Error: Can't Hash %s: %s",
                    127:                    current_optab->name, hash_err);
                    128:       }
                    129:   }
                    130:
                    131:   parop_hash = hash_new ();
                    132:
                    133:   {
                    134:     const partemplate *current_parop = tic30_paroptab;
                    135:
                    136:     for (; current_parop < tic30_paroptab_end; current_parop++)
                    137:       {
                    138:        hash_err = hash_insert (parop_hash, current_parop->name,
                    139:                                (char *) current_parop);
                    140:        if (hash_err)
                    141:          as_fatal ("Internal Error: Can't Hash %s: %s",
                    142:                    current_parop->name, hash_err);
                    143:       }
                    144:   }
                    145:
                    146:   reg_hash = hash_new ();
                    147:
                    148:   {
                    149:     const reg *current_reg = tic30_regtab;
                    150:
                    151:     for (; current_reg < tic30_regtab_end; current_reg++)
                    152:       {
                    153:        hash_err = hash_insert (reg_hash, current_reg->name,
                    154:                                (char *) current_reg);
                    155:        if (hash_err)
                    156:          as_fatal ("Internal Error: Can't Hash %s: %s",
                    157:                    current_reg->name, hash_err);
                    158:       }
                    159:   }
                    160:
                    161:   ind_hash = hash_new ();
                    162:
                    163:   {
                    164:     const ind_addr_type *current_ind = tic30_indaddr_tab;
                    165:
                    166:     for (; current_ind < tic30_indaddrtab_end; current_ind++)
                    167:       {
                    168:        hash_err = hash_insert (ind_hash, current_ind->syntax,
                    169:                                (char *) current_ind);
                    170:        if (hash_err)
                    171:          as_fatal ("Internal Error: Can't Hash %s: %s",
                    172:                    current_ind->syntax, hash_err);
                    173:       }
                    174:   }
                    175:
                    176:   /* Fill in lexical tables:  opcode_chars, operand_chars, space_chars.  */
                    177:   {
                    178:     int c;
                    179:     char *p;
                    180:
                    181:     for (c = 0; c < 256; c++)
                    182:       {
                    183:        if (ISLOWER (c) || ISDIGIT (c))
                    184:          {
                    185:            opcode_chars[c] = c;
                    186:            register_chars[c] = c;
                    187:          }
                    188:        else if (ISUPPER (c))
                    189:          {
                    190:            opcode_chars[c] = TOLOWER (c);
                    191:            register_chars[c] = opcode_chars[c];
                    192:          }
                    193:        else if (c == ')' || c == '(')
                    194:          register_chars[c] = c;
                    195:
                    196:        if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
                    197:          operand_chars[c] = c;
                    198:
                    199:        if (ISDIGIT (c) || c == '-')
                    200:          digit_chars[c] = c;
                    201:
                    202:        if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
                    203:          identifier_chars[c] = c;
                    204:
                    205:        if (c == ' ' || c == '\t')
                    206:          space_chars[c] = c;
                    207:
                    208:        if (c == '_')
                    209:          opcode_chars[c] = c;
                    210:       }
                    211:     for (p = operand_special_chars; *p != '\0'; p++)
                    212:       operand_chars[(unsigned char) *p] = *p;
                    213:   }
                    214: }
                    215:
                    216: /* Address Mode OR values.  */
                    217: #define AM_Register  0x00000000
                    218: #define AM_Direct    0x00200000
                    219: #define AM_Indirect  0x00400000
                    220: #define AM_Immediate 0x00600000
                    221: #define AM_NotReq    0xFFFFFFFF
                    222:
                    223: /* PC Relative OR values.  */
                    224: #define PC_Register 0x00000000
                    225: #define PC_Relative 0x02000000
                    226:
                    227: typedef struct
                    228: {
                    229:   unsigned op_type;
                    230:   struct
                    231:   {
                    232:     int resolved;
                    233:     unsigned address;
                    234:     char *label;
                    235:     expressionS direct_expr;
                    236:   } direct;
                    237:   struct
                    238:   {
                    239:     unsigned mod;
                    240:     int ARnum;
                    241:     unsigned char disp;
                    242:   } indirect;
                    243:   struct
                    244:   {
                    245:     unsigned opcode;
                    246:   } reg;
                    247:   struct
                    248:   {
                    249:     int resolved;
                    250:     int decimal_found;
                    251:     float f_number;
                    252:     int s_number;
                    253:     unsigned int u_number;
                    254:     char *label;
                    255:     expressionS imm_expr;
                    256:   } immediate;
                    257: } operand;
                    258:
                    259: insn_template *opcode;
                    260:
                    261: struct tic30_insn
                    262: {
                    263:   insn_template *tm;           /* Template of current instruction.  */
                    264:   unsigned opcode;             /* Final opcode.  */
                    265:   unsigned int operands;       /* Number of given operands.  */
                    266:   /* Type of operand given in instruction.  */
                    267:   operand *operand_type[MAX_OPERANDS];
                    268:   unsigned addressing_mode;    /* Final addressing mode of instruction.  */
                    269: };
                    270:
                    271: struct tic30_insn insn;
                    272: static int found_parallel_insn;
                    273:
                    274: static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
                    275:
                    276: static char *
                    277: output_invalid (char c)
                    278: {
                    279:   if (ISPRINT (c))
                    280:     snprintf (output_invalid_buf, sizeof (output_invalid_buf),
                    281:              "'%c'", c);
                    282:   else
1.1.1.2   christos  283:     snprintf (output_invalid_buf, sizeof (output_invalid_buf),
1.1       christos  284:              "(0x%x)", (unsigned char) c);
                    285:   return output_invalid_buf;
                    286: }
                    287:
                    288: /* next_line points to the next line after the current instruction
                    289:    (current_line).  Search for the parallel bars, and if found, merge two
                    290:    lines into internal syntax for a parallel instruction:
                    291:      q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
                    292:    By this stage, all comments are scrubbed, and only the bare lines are
                    293:    given.  */
                    294:
                    295: #define NONE           0
                    296: #define START_OPCODE   1
                    297: #define END_OPCODE     2
                    298: #define START_OPERANDS 3
                    299: #define END_OPERANDS   4
                    300:
                    301: static char *
                    302: tic30_find_parallel_insn (char *current_line, char *next_line)
                    303: {
                    304:   int found_parallel = 0;
                    305:   char first_opcode[256];
                    306:   char second_opcode[256];
                    307:   char first_operands[256];
                    308:   char second_operands[256];
                    309:   char *parallel_insn;
                    310:
                    311:   debug ("In tic30_find_parallel_insn()\n");
                    312:   while (!is_end_of_line[(unsigned char) *next_line])
                    313:     {
                    314:       if (*next_line == PARALLEL_SEPARATOR
                    315:          && *(next_line + 1) == PARALLEL_SEPARATOR)
                    316:        {
                    317:          found_parallel = 1;
                    318:          next_line++;
                    319:          break;
                    320:        }
                    321:       next_line++;
                    322:     }
                    323:   if (!found_parallel)
                    324:     return NULL;
                    325:   debug ("Found a parallel instruction\n");
                    326:
                    327:   {
                    328:     int i;
                    329:     char *op, *operands, *line;
                    330:
                    331:     for (i = 0; i < 2; i++)
                    332:       {
                    333:        if (i == 0)
                    334:          {
                    335:            op = &first_opcode[0];
                    336:            operands = &first_operands[0];
                    337:            line = current_line;
                    338:          }
                    339:        else
                    340:          {
                    341:            op = &second_opcode[0];
                    342:            operands = &second_operands[0];
                    343:            line = next_line;
                    344:          }
                    345:
                    346:        {
                    347:          int search_status = NONE;
                    348:          int char_ptr = 0;
                    349:          char c;
                    350:
                    351:          while (!is_end_of_line[(unsigned char) (c = *line)])
                    352:            {
                    353:              if (is_opcode_char (c) && search_status == NONE)
                    354:                {
                    355:                  op[char_ptr++] = TOLOWER (c);
                    356:                  search_status = START_OPCODE;
                    357:                }
                    358:              else if (is_opcode_char (c) && search_status == START_OPCODE)
                    359:                op[char_ptr++] = TOLOWER (c);
                    360:              else if (!is_opcode_char (c) && search_status == START_OPCODE)
                    361:                {
                    362:                  op[char_ptr] = '\0';
                    363:                  char_ptr = 0;
                    364:                  search_status = END_OPCODE;
                    365:                }
                    366:              else if (is_operand_char (c) && search_status == START_OPERANDS)
                    367:                operands[char_ptr++] = c;
                    368:
                    369:              if (is_operand_char (c) && search_status == END_OPCODE)
                    370:                {
                    371:                  operands[char_ptr++] = c;
                    372:                  search_status = START_OPERANDS;
                    373:                }
                    374:
                    375:              line++;
                    376:            }
                    377:          if (search_status != START_OPERANDS)
                    378:            return NULL;
                    379:          operands[char_ptr] = '\0';
                    380:        }
                    381:       }
                    382:   }
1.1.1.3   christos  383:
                    384:   parallel_insn = concat ("q_", first_opcode, "_", second_opcode, " ",
                    385:                          first_operands, " | ", second_operands,
                    386:                          (char *) NULL);
1.1       christos  387:   debug ("parallel insn = %s\n", parallel_insn);
                    388:   return parallel_insn;
                    389: }
                    390:
                    391: #undef NONE
                    392: #undef START_OPCODE
                    393: #undef END_OPCODE
                    394: #undef START_OPERANDS
                    395: #undef END_OPERANDS
                    396:
                    397: static operand *
                    398: tic30_operand (char *token)
                    399: {
                    400:   unsigned int count;
                    401:   operand *current_op;
                    402:
                    403:   debug ("In tic30_operand with %s\n", token);
1.1.1.3   christos  404:   current_op = XCNEW (operand);
1.1       christos  405:
                    406:   if (*token == DIRECT_REFERENCE)
                    407:     {
                    408:       char *token_posn = token + 1;
                    409:       int direct_label = 0;
                    410:
                    411:       debug ("Found direct reference\n");
                    412:       while (*token_posn)
                    413:        {
                    414:          if (!is_digit_char (*token_posn))
                    415:            direct_label = 1;
                    416:          token_posn++;
                    417:        }
                    418:
                    419:       if (direct_label)
                    420:        {
                    421:          char *save_input_line_pointer;
                    422:          segT retval;
                    423:
                    424:          debug ("Direct reference is a label\n");
                    425:          current_op->direct.label = token + 1;
                    426:          save_input_line_pointer = input_line_pointer;
                    427:          input_line_pointer = token + 1;
                    428:          debug ("Current input_line_pointer: %s\n", input_line_pointer);
                    429:          retval = expression (&current_op->direct.direct_expr);
                    430:
                    431:          debug ("Expression type: %d\n",
                    432:                 current_op->direct.direct_expr.X_op);
                    433:          debug ("Expression addnum: %ld\n",
                    434:                 (long) current_op->direct.direct_expr.X_add_number);
                    435:          debug ("Segment: %p\n", retval);
                    436:
                    437:          input_line_pointer = save_input_line_pointer;
                    438:
                    439:          if (current_op->direct.direct_expr.X_op == O_constant)
                    440:            {
                    441:              current_op->direct.address =
                    442:                current_op->direct.direct_expr.X_add_number;
                    443:              current_op->direct.resolved = 1;
                    444:            }
                    445:        }
                    446:       else
                    447:        {
                    448:          debug ("Direct reference is a number\n");
                    449:          current_op->direct.address = atoi (token + 1);
                    450:          current_op->direct.resolved = 1;
                    451:        }
                    452:       current_op->op_type = Direct;
                    453:     }
                    454:   else if (*token == INDIRECT_REFERENCE)
                    455:     {
                    456:       /* Indirect reference operand.  */
                    457:       int found_ar = 0;
                    458:       int found_disp = 0;
                    459:       int ar_number = -1;
                    460:       int disp_number = 0;
                    461:       int buffer_posn = 1;
                    462:       ind_addr_type *ind_addr_op;
1.1.1.3   christos  463:       char * ind_buffer;
                    464:
                    465:       ind_buffer = XNEWVEC (char, strlen (token));
1.1       christos  466:
                    467:       debug ("Found indirect reference\n");
                    468:       ind_buffer[0] = *token;
                    469:
                    470:       for (count = 1; count < strlen (token); count++)
                    471:        {
                    472:          /* Strip operand.  */
                    473:          ind_buffer[buffer_posn] = TOLOWER (*(token + count));
                    474:
                    475:          if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
                    476:              && (*(token + count) == 'r' || *(token + count) == 'R'))
                    477:            {
                    478:              /* AR reference is found, so get its number and remove
                    479:                 it from the buffer so it can pass through hash_find().  */
                    480:              if (found_ar)
                    481:                {
                    482:                  as_bad (_("More than one AR register found in indirect reference"));
1.1.1.3   christos  483:                  free (ind_buffer);
1.1       christos  484:                  return NULL;
                    485:                }
                    486:              if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
                    487:                {
                    488:                  as_bad (_("Illegal AR register in indirect reference"));
1.1.1.3   christos  489:                  free (ind_buffer);
1.1       christos  490:                  return NULL;
                    491:                }
                    492:              ar_number = *(token + count + 1) - '0';
                    493:              found_ar = 1;
                    494:              count++;
                    495:            }
                    496:
                    497:          if (*(token + count) == '(')
                    498:            {
                    499:              /* Parenthesis found, so check if a displacement value is
                    500:                 inside.  If so, get the value and remove it from the
                    501:                 buffer.  */
                    502:              if (is_digit_char (*(token + count + 1)))
                    503:                {
                    504:                  char disp[10];
                    505:                  int disp_posn = 0;
                    506:
                    507:                  if (found_disp)
                    508:                    {
                    509:                      as_bad (_("More than one displacement found in indirect reference"));
1.1.1.3   christos  510:                      free (ind_buffer);
1.1       christos  511:                      return NULL;
                    512:                    }
                    513:                  count++;
                    514:                  while (*(token + count) != ')')
                    515:                    {
                    516:                      if (!is_digit_char (*(token + count)))
                    517:                        {
                    518:                          as_bad (_("Invalid displacement in indirect reference"));
1.1.1.3   christos  519:                          free (ind_buffer);
1.1       christos  520:                          return NULL;
                    521:                        }
                    522:                      disp[disp_posn++] = *(token + (count++));
                    523:                    }
                    524:                  disp[disp_posn] = '\0';
                    525:                  disp_number = atoi (disp);
                    526:                  count--;
                    527:                  found_disp = 1;
                    528:                }
                    529:            }
                    530:          buffer_posn++;
                    531:        }
                    532:
                    533:       ind_buffer[buffer_posn] = '\0';
                    534:       if (!found_ar)
                    535:        {
                    536:          as_bad (_("AR register not found in indirect reference"));
1.1.1.3   christos  537:          free (ind_buffer);
1.1       christos  538:          return NULL;
                    539:        }
                    540:
                    541:       ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
                    542:       if (ind_addr_op)
                    543:        {
                    544:          debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
                    545:          if (ind_addr_op->displacement == IMPLIED_DISP)
                    546:            {
                    547:              found_disp = 1;
                    548:              disp_number = 1;
                    549:            }
                    550:          else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
                    551:            {
                    552:              /* Maybe an implied displacement of 1 again.  */
                    553:              as_bad (_("required displacement wasn't given in indirect reference"));
1.1.1.3   christos  554:              free (ind_buffer);
                    555:              return NULL;
1.1       christos  556:            }
                    557:        }
                    558:       else
                    559:        {
                    560:          as_bad (_("illegal indirect reference"));
1.1.1.3   christos  561:          free (ind_buffer);
1.1       christos  562:          return NULL;
                    563:        }
                    564:
                    565:       if (found_disp && (disp_number < 0 || disp_number > 255))
                    566:        {
                    567:          as_bad (_("displacement must be an unsigned 8-bit number"));
1.1.1.3   christos  568:          free (ind_buffer);
1.1       christos  569:          return NULL;
                    570:        }
                    571:
                    572:       current_op->indirect.mod = ind_addr_op->modfield;
                    573:       current_op->indirect.disp = disp_number;
                    574:       current_op->indirect.ARnum = ar_number;
                    575:       current_op->op_type = Indirect;
1.1.1.3   christos  576:       free (ind_buffer);
1.1       christos  577:     }
                    578:   else
                    579:     {
                    580:       reg *regop = (reg *) hash_find (reg_hash, token);
                    581:
                    582:       if (regop)
                    583:        {
                    584:          debug ("Found register operand: %s\n", regop->name);
                    585:          if (regop->regtype == REG_ARn)
                    586:            current_op->op_type = ARn;
                    587:          else if (regop->regtype == REG_Rn)
                    588:            current_op->op_type = Rn;
                    589:          else if (regop->regtype == REG_DP)
                    590:            current_op->op_type = DPReg;
                    591:          else
                    592:            current_op->op_type = OtherReg;
                    593:          current_op->reg.opcode = regop->opcode;
                    594:        }
                    595:       else
                    596:        {
                    597:          if (!is_digit_char (*token)
                    598:              || *(token + 1) == 'x'
                    599:              || strchr (token, 'h'))
                    600:            {
                    601:              char *save_input_line_pointer;
                    602:              segT retval;
                    603:
                    604:              debug ("Probably a label: %s\n", token);
1.1.1.3   christos  605:              current_op->immediate.label = xstrdup (token);
1.1       christos  606:              save_input_line_pointer = input_line_pointer;
                    607:              input_line_pointer = token;
                    608:
                    609:              debug ("Current input_line_pointer: %s\n", input_line_pointer);
                    610:              retval = expression (&current_op->immediate.imm_expr);
                    611:              debug ("Expression type: %d\n",
                    612:                     current_op->immediate.imm_expr.X_op);
                    613:              debug ("Expression addnum: %ld\n",
                    614:                     (long) current_op->immediate.imm_expr.X_add_number);
                    615:              debug ("Segment: %p\n", retval);
                    616:              input_line_pointer = save_input_line_pointer;
                    617:
                    618:              if (current_op->immediate.imm_expr.X_op == O_constant)
                    619:                {
                    620:                  current_op->immediate.s_number
                    621:                    = current_op->immediate.imm_expr.X_add_number;
                    622:                  current_op->immediate.u_number
                    623:                    = (unsigned int) current_op->immediate.imm_expr.X_add_number;
                    624:                  current_op->immediate.resolved = 1;
                    625:                }
                    626:            }
                    627:          else
                    628:            {
                    629:              debug ("Found a number or displacement\n");
                    630:              for (count = 0; count < strlen (token); count++)
                    631:                if (*(token + count) == '.')
                    632:                  current_op->immediate.decimal_found = 1;
1.1.1.3   christos  633:              current_op->immediate.label = xstrdup (token);
1.1       christos  634:              current_op->immediate.f_number = (float) atof (token);
                    635:              current_op->immediate.s_number = (int) atoi (token);
                    636:              current_op->immediate.u_number = (unsigned int) atoi (token);
                    637:              current_op->immediate.resolved = 1;
                    638:            }
                    639:          current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
                    640:          if (current_op->immediate.u_number <= 31)
                    641:            current_op->op_type |= IVector;
                    642:        }
                    643:     }
                    644:   return current_op;
                    645: }
                    646:
                    647: struct tic30_par_insn
                    648: {
                    649:   partemplate *tm;             /* Template of current parallel instruction.  */
                    650:   unsigned operands[2];                /* Number of given operands for each insn.  */
                    651:   /* Type of operand given in instruction.  */
                    652:   operand *operand_type[2][MAX_OPERANDS];
                    653:   int swap_operands;           /* Whether to swap operands around.  */
                    654:   unsigned p_field;            /* Value of p field in multiply add/sub instructions.  */
                    655:   unsigned opcode;             /* Final opcode.  */
                    656: };
                    657:
                    658: struct tic30_par_insn p_insn;
                    659:
                    660: static int
                    661: tic30_parallel_insn (char *token)
                    662: {
                    663:   static partemplate *p_opcode;
                    664:   char *current_posn = token;
                    665:   char *token_start;
                    666:   char save_char;
                    667:
                    668:   debug ("In tic30_parallel_insn with %s\n", token);
                    669:   memset (&p_insn, '\0', sizeof (p_insn));
                    670:
                    671:   while (is_opcode_char (*current_posn))
                    672:     current_posn++;
                    673:   {
                    674:     /* Find instruction.  */
                    675:     save_char = *current_posn;
                    676:     *current_posn = '\0';
                    677:     p_opcode = (partemplate *) hash_find (parop_hash, token);
                    678:     if (p_opcode)
                    679:       {
                    680:        debug ("Found instruction %s\n", p_opcode->name);
                    681:        p_insn.tm = p_opcode;
                    682:       }
                    683:     else
                    684:       {
                    685:        char first_opcode[6] = {0};
                    686:        char second_opcode[6] = {0};
                    687:        unsigned int i;
                    688:        int current_opcode = -1;
                    689:        int char_ptr = 0;
                    690:
                    691:        for (i = 0; i < strlen (token); i++)
                    692:          {
                    693:            char ch = *(token + i);
                    694:
                    695:            if (ch == '_' && current_opcode == -1)
                    696:              {
                    697:                current_opcode = 0;
                    698:                continue;
                    699:              }
                    700:
                    701:            if (ch == '_' && current_opcode == 0)
                    702:              {
                    703:                current_opcode = 1;
                    704:                char_ptr = 0;
                    705:                continue;
                    706:              }
                    707:
                    708:            switch (current_opcode)
                    709:              {
                    710:              case 0:
                    711:                first_opcode[char_ptr++] = ch;
                    712:                break;
                    713:              case 1:
                    714:                second_opcode[char_ptr++] = ch;
                    715:                break;
                    716:              }
                    717:          }
                    718:
                    719:        debug ("first_opcode = %s\n", first_opcode);
                    720:        debug ("second_opcode = %s\n", second_opcode);
                    721:        sprintf (token, "q_%s_%s", second_opcode, first_opcode);
                    722:        p_opcode = (partemplate *) hash_find (parop_hash, token);
                    723:
                    724:        if (p_opcode)
                    725:          {
                    726:            debug ("Found instruction %s\n", p_opcode->name);
                    727:            p_insn.tm = p_opcode;
                    728:            p_insn.swap_operands = 1;
                    729:          }
                    730:        else
                    731:          return 0;
                    732:       }
                    733:     *current_posn = save_char;
                    734:   }
                    735:
                    736:   {
                    737:     /* Find operands.  */
                    738:     int paren_not_balanced;
                    739:     int expecting_operand = 0;
                    740:     int found_separator = 0;
                    741:
                    742:     do
                    743:       {
                    744:        /* Skip optional white space before operand.  */
                    745:        while (!is_operand_char (*current_posn)
                    746:               && *current_posn != END_OF_INSN)
                    747:          {
                    748:            if (!is_space_char (*current_posn)
                    749:                && *current_posn != PARALLEL_SEPARATOR)
                    750:              {
                    751:                as_bad (_("Invalid character %s before %s operand"),
                    752:                        output_invalid (*current_posn),
                    753:                        ordinal_names[insn.operands]);
                    754:                return 1;
                    755:              }
                    756:            if (*current_posn == PARALLEL_SEPARATOR)
                    757:              found_separator = 1;
                    758:            current_posn++;
                    759:          }
                    760:
                    761:        token_start = current_posn;
                    762:        paren_not_balanced = 0;
                    763:
                    764:        while (paren_not_balanced || *current_posn != ',')
                    765:          {
                    766:            if (*current_posn == END_OF_INSN)
                    767:              {
                    768:                if (paren_not_balanced)
                    769:                  {
                    770:                    as_bad (_("Unbalanced parenthesis in %s operand."),
                    771:                            ordinal_names[insn.operands]);
                    772:                    return 1;
                    773:                  }
                    774:                else
                    775:                  break;
                    776:              }
                    777:            else if (*current_posn == PARALLEL_SEPARATOR)
                    778:              {
                    779:                while (is_space_char (*(current_posn - 1)))
                    780:                  current_posn--;
                    781:                break;
                    782:              }
                    783:            else if (!is_operand_char (*current_posn)
                    784:                     && !is_space_char (*current_posn))
                    785:              {
                    786:                as_bad (_("Invalid character %s in %s operand"),
                    787:                        output_invalid (*current_posn),
                    788:                        ordinal_names[insn.operands]);
                    789:                return 1;
                    790:              }
                    791:
                    792:            if (*current_posn == '(')
                    793:              ++paren_not_balanced;
                    794:            if (*current_posn == ')')
                    795:              --paren_not_balanced;
                    796:            current_posn++;
                    797:          }
                    798:
                    799:        if (current_posn != token_start)
                    800:          {
                    801:            /* Yes, we've read in another operand.  */
                    802:            p_insn.operands[found_separator]++;
                    803:            if (p_insn.operands[found_separator] > MAX_OPERANDS)
                    804:              {
                    805:                as_bad (_("Spurious operands; (%d operands/instruction max)"),
                    806:                        MAX_OPERANDS);
                    807:                return 1;
                    808:              }
                    809:
                    810:            /* Now parse operand adding info to 'insn' as we go along.  */
                    811:            save_char = *current_posn;
                    812:            *current_posn = '\0';
                    813:            p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
                    814:              tic30_operand (token_start);
                    815:            *current_posn = save_char;
                    816:            if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
                    817:              return 1;
                    818:          }
                    819:        else
                    820:          {
                    821:            if (expecting_operand)
                    822:              {
                    823:                as_bad (_("Expecting operand after ','; got nothing"));
                    824:                return 1;
                    825:              }
                    826:            if (*current_posn == ',')
                    827:              {
                    828:                as_bad (_("Expecting operand before ','; got nothing"));
                    829:                return 1;
                    830:              }
                    831:          }
                    832:
                    833:        /* Now *current_posn must be either ',' or END_OF_INSN.  */
                    834:        if (*current_posn == ',')
                    835:          {
                    836:            if (*++current_posn == END_OF_INSN)
                    837:              {
                    838:                /* Just skip it, if it's \n complain.  */
                    839:                as_bad (_("Expecting operand after ','; got nothing"));
                    840:                return 1;
                    841:              }
                    842:            expecting_operand = 1;
                    843:          }
                    844:       }
                    845:     while (*current_posn != END_OF_INSN);
                    846:   }
                    847:
                    848:   if (p_insn.swap_operands)
                    849:     {
                    850:       int temp_num, i;
                    851:       operand *temp_op;
                    852:
                    853:       temp_num = p_insn.operands[0];
                    854:       p_insn.operands[0] = p_insn.operands[1];
                    855:       p_insn.operands[1] = temp_num;
                    856:       for (i = 0; i < MAX_OPERANDS; i++)
                    857:        {
                    858:          temp_op = p_insn.operand_type[0][i];
                    859:          p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
                    860:          p_insn.operand_type[1][i] = temp_op;
                    861:        }
                    862:     }
                    863:
                    864:   if (p_insn.operands[0] != p_insn.tm->operands_1)
                    865:     {
                    866:       as_bad (_("incorrect number of operands given in the first instruction"));
                    867:       return 1;
                    868:     }
                    869:
                    870:   if (p_insn.operands[1] != p_insn.tm->operands_2)
                    871:     {
                    872:       as_bad (_("incorrect number of operands given in the second instruction"));
                    873:       return 1;
                    874:     }
                    875:
                    876:   debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
                    877:   debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
                    878:
                    879:   {
                    880:     /* Now check if operands are correct.  */
                    881:     int count;
                    882:     int num_rn = 0;
                    883:     int num_ind = 0;
                    884:
                    885:     for (count = 0; count < 2; count++)
                    886:       {
                    887:        unsigned int i;
                    888:        for (i = 0; i < p_insn.operands[count]; i++)
                    889:          {
                    890:            if ((p_insn.operand_type[count][i]->op_type &
                    891:                 p_insn.tm->operand_types[count][i]) == 0)
                    892:              {
                    893:                as_bad (_("%s instruction, operand %d doesn't match"),
                    894:                        ordinal_names[count], i + 1);
                    895:                return 1;
                    896:              }
                    897:
                    898:            /* Get number of R register and indirect reference contained
                    899:               within the first two operands of each instruction.  This is
                    900:               required for the multiply parallel instructions which require
                    901:               two R registers and two indirect references, but not in any
                    902:               particular place.  */
                    903:            if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
                    904:              num_rn++;
                    905:            else if ((p_insn.operand_type[count][i]->op_type & Indirect)
                    906:                     && i < 2)
                    907:              num_ind++;
                    908:          }
                    909:       }
                    910:
                    911:     if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
                    912:        == (Indirect | Rn))
                    913:       {
                    914:        /* Check for the multiply instructions.  */
                    915:        if (num_rn != 2)
                    916:          {
                    917:            as_bad (_("incorrect format for multiply parallel instruction"));
                    918:            return 1;
                    919:          }
                    920:
                    921:        if (num_ind != 2)
                    922:          {
                    923:            /* Shouldn't get here.  */
                    924:            as_bad (_("incorrect format for multiply parallel instruction"));
                    925:            return 1;
                    926:          }
                    927:
                    928:        if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
                    929:            && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
                    930:          {
                    931:            as_bad (_("destination for multiply can only be R0 or R1"));
                    932:            return 1;
                    933:          }
                    934:
                    935:        if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
                    936:            && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
                    937:          {
                    938:            as_bad (_("destination for add/subtract can only be R2 or R3"));
                    939:            return 1;
                    940:          }
                    941:
                    942:        /* Now determine the P field for the instruction.  */
                    943:        if (p_insn.operand_type[0][0]->op_type & Indirect)
                    944:          {
                    945:            if (p_insn.operand_type[0][1]->op_type & Indirect)
                    946:              p_insn.p_field = 0x00000000;      /* Ind * Ind, Rn  +/- Rn.  */
                    947:            else if (p_insn.operand_type[1][0]->op_type & Indirect)
                    948:              p_insn.p_field = 0x01000000;      /* Ind * Rn,  Ind +/- Rn.  */
                    949:            else
                    950:              p_insn.p_field = 0x03000000;      /* Ind * Rn,  Rn  +/- Ind.  */
                    951:          }
                    952:        else
                    953:          {
                    954:            if (p_insn.operand_type[0][1]->op_type & Rn)
                    955:              p_insn.p_field = 0x02000000;      /* Rn  * Rn,  Ind +/- Ind.  */
                    956:            else if (p_insn.operand_type[1][0]->op_type & Indirect)
                    957:              {
                    958:                operand *temp;
                    959:                p_insn.p_field = 0x01000000;    /* Rn  * Ind, Ind +/- Rn.  */
                    960:                /* Need to swap the two multiply operands around so that
                    961:                   everything is in its place for the opcode makeup.
                    962:                   ie so Ind * Rn, Ind +/- Rn.  */
                    963:                temp = p_insn.operand_type[0][0];
                    964:                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
                    965:                p_insn.operand_type[0][1] = temp;
                    966:              }
                    967:            else
                    968:              {
                    969:                operand *temp;
                    970:                p_insn.p_field = 0x03000000;    /* Rn  * Ind, Rn  +/- Ind.  */
                    971:                temp = p_insn.operand_type[0][0];
                    972:                p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
                    973:                p_insn.operand_type[0][1] = temp;
                    974:              }
                    975:          }
                    976:       }
                    977:   }
                    978:
                    979:   debug ("P field: %08X\n", p_insn.p_field);
                    980:
                    981:   /* Finalise opcode.  This is easier for parallel instructions as they have
                    982:      to be fully resolved, there are no memory addresses allowed, except
                    983:      through indirect addressing, so there are no labels to resolve.  */
                    984:   p_insn.opcode = p_insn.tm->base_opcode;
                    985:
                    986:   switch (p_insn.tm->oporder)
                    987:     {
                    988:     case OO_4op1:
                    989:       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
                    990:       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
                    991:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
                    992:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
                    993:       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
                    994:       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
                    995:       break;
                    996:
                    997:     case OO_4op2:
                    998:       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
                    999:       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
                   1000:       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
                   1001:       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
                   1002:       p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
                   1003:       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
                   1004:       if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
                   1005:        as_warn (_("loading the same register in parallel operation"));
                   1006:       break;
                   1007:
                   1008:     case OO_4op3:
                   1009:       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
                   1010:       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
                   1011:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
                   1012:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
                   1013:       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
                   1014:       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
                   1015:       break;
                   1016:
                   1017:     case OO_5op1:
                   1018:       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
                   1019:       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
                   1020:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
                   1021:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
                   1022:       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
                   1023:       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
                   1024:       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
                   1025:       break;
                   1026:
                   1027:     case OO_5op2:
                   1028:       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
                   1029:       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
                   1030:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
                   1031:       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
                   1032:       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
                   1033:       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
                   1034:       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
                   1035:       break;
                   1036:
                   1037:     case OO_PField:
                   1038:       p_insn.opcode |= p_insn.p_field;
                   1039:       if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
                   1040:        p_insn.opcode |= 0x00800000;
                   1041:       if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
                   1042:        p_insn.opcode |= 0x00400000;
                   1043:
                   1044:       switch (p_insn.p_field)
                   1045:        {
                   1046:        case 0x00000000:
                   1047:          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
                   1048:          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
                   1049:          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
                   1050:          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
                   1051:          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
                   1052:          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
                   1053:          break;
                   1054:        case 0x01000000:
                   1055:          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
                   1056:          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
                   1057:          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
                   1058:          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
                   1059:          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
                   1060:          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
                   1061:          break;
                   1062:        case 0x02000000:
                   1063:          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
                   1064:          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
                   1065:          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
                   1066:          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
                   1067:          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
                   1068:          p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
                   1069:          break;
                   1070:        case 0x03000000:
                   1071:          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
                   1072:          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
                   1073:          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
                   1074:          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
                   1075:          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
                   1076:          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
                   1077:          break;
                   1078:        }
                   1079:       break;
                   1080:     }
                   1081:
                   1082:   {
                   1083:     char *p;
                   1084:
                   1085:     p = frag_more (INSN_SIZE);
                   1086:     md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
                   1087:   }
                   1088:
                   1089:   {
                   1090:     unsigned int i, j;
                   1091:
                   1092:     for (i = 0; i < 2; i++)
                   1093:       for (j = 0; j < p_insn.operands[i]; j++)
                   1094:        free (p_insn.operand_type[i][j]);
                   1095:   }
                   1096:
                   1097:   debug ("Final opcode: %08X\n", p_insn.opcode);
                   1098:   debug ("\n");
                   1099:
                   1100:   return 1;
                   1101: }
                   1102:
                   1103: /* In order to get gas to ignore any | chars at the start of a line,
                   1104:    this function returns true if a | is found in a line.  */
                   1105:
                   1106: int
                   1107: tic30_unrecognized_line (int c)
                   1108: {
                   1109:   debug ("In tc_unrecognized_line\n");
                   1110:   return (c == PARALLEL_SEPARATOR);
                   1111: }
                   1112:
                   1113: int
                   1114: md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
                   1115:                               segT segment ATTRIBUTE_UNUSED)
                   1116: {
                   1117:   debug ("In md_estimate_size_before_relax()\n");
                   1118:   return 0;
                   1119: }
                   1120:
                   1121: void
                   1122: md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
                   1123:                 segT sec ATTRIBUTE_UNUSED,
1.1.1.2   christos 1124:                 fragS *fragP ATTRIBUTE_UNUSED)
1.1       christos 1125: {
                   1126:   debug ("In md_convert_frag()\n");
                   1127: }
                   1128:
                   1129: void
                   1130: md_apply_fix (fixS *fixP,
                   1131:               valueT *valP,
                   1132:               segT seg ATTRIBUTE_UNUSED)
                   1133: {
                   1134:   valueT value = *valP;
                   1135:
                   1136:   debug ("In md_apply_fix() with value = %ld\n", (long) value);
                   1137:   debug ("Values in fixP\n");
                   1138:   debug ("fx_size = %d\n", fixP->fx_size);
                   1139:   debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
                   1140:   debug ("fx_where = %ld\n", fixP->fx_where);
                   1141:   debug ("fx_offset = %d\n", (int) fixP->fx_offset);
                   1142:   {
                   1143:     char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
                   1144:
                   1145:     value /= INSN_SIZE;
                   1146:     if (fixP->fx_size == 1)
                   1147:       /* Special fix for LDP instruction.  */
                   1148:       value = (value & 0x00FF0000) >> 16;
                   1149:
                   1150:     debug ("new value = %ld\n", (long) value);
                   1151:     md_number_to_chars (buf, value, fixP->fx_size);
                   1152:   }
                   1153:
                   1154:   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
                   1155:     fixP->fx_done = 1;
                   1156: }
                   1157:
                   1158: int
                   1159: md_parse_option (int c ATTRIBUTE_UNUSED,
1.1.1.3   christos 1160:                 const char *arg ATTRIBUTE_UNUSED)
1.1       christos 1161: {
                   1162:   debug ("In md_parse_option()\n");
                   1163:   return 0;
                   1164: }
                   1165:
                   1166: void
                   1167: md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
                   1168: {
                   1169:   debug ("In md_show_usage()\n");
                   1170: }
                   1171:
                   1172: symbolS *
                   1173: md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
                   1174: {
                   1175:   debug ("In md_undefined_symbol()\n");
                   1176:   return (symbolS *) 0;
                   1177: }
                   1178:
                   1179: valueT
                   1180: md_section_align (segT segment, valueT size)
                   1181: {
                   1182:   debug ("In md_section_align() segment = %p and size = %lu\n",
                   1183:         segment, (unsigned long) size);
                   1184:   size = (size + 3) / 4;
                   1185:   size *= 4;
                   1186:   debug ("New size value = %lu\n", (unsigned long) size);
                   1187:   return size;
                   1188: }
                   1189:
                   1190: long
                   1191: md_pcrel_from (fixS *fixP)
                   1192: {
                   1193:   int offset;
                   1194:
                   1195:   debug ("In md_pcrel_from()\n");
                   1196:   debug ("fx_where = %ld\n", fixP->fx_where);
                   1197:   debug ("fx_size = %d\n", fixP->fx_size);
                   1198:   /* Find the opcode that represents the current instruction in the
                   1199:      fr_literal storage area, and check bit 21.  Bit 21 contains whether the
                   1200:      current instruction is a delayed one or not, and then set the offset
                   1201:      value appropriately.  */
                   1202:   if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
                   1203:     offset = 3;
                   1204:   else
                   1205:     offset = 1;
                   1206:   debug ("offset = %d\n", offset);
                   1207:   /* PC Relative instructions have a format:
                   1208:      displacement = Label - (PC + offset)
                   1209:      This function returns PC + offset where:
                   1210:      fx_where - fx_size = PC
                   1211:      INSN_SIZE * offset = offset number of instructions.  */
                   1212:   return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
                   1213: }
                   1214:
1.1.1.3   christos 1215: const char *
1.1       christos 1216: md_atof (int what_statement_type,
                   1217:         char *literalP,
                   1218:         int *sizeP)
                   1219: {
                   1220:   int prec;
                   1221:   char *token;
                   1222:   char keepval;
                   1223:   unsigned long value;
                   1224:   float float_value;
                   1225:
                   1226:   debug ("In md_atof()\n");
                   1227:   debug ("precision = %c\n", what_statement_type);
                   1228:   debug ("literal = %s\n", literalP);
                   1229:   debug ("line = ");
                   1230:   token = input_line_pointer;
                   1231:   while (!is_end_of_line[(unsigned char) *input_line_pointer]
                   1232:         && (*input_line_pointer != ','))
                   1233:     {
                   1234:       debug ("%c", *input_line_pointer);
                   1235:       input_line_pointer++;
                   1236:     }
                   1237:
                   1238:   keepval = *input_line_pointer;
                   1239:   *input_line_pointer = '\0';
                   1240:   debug ("\n");
                   1241:   float_value = (float) atof (token);
                   1242:   *input_line_pointer = keepval;
                   1243:   debug ("float_value = %f\n", float_value);
                   1244:
                   1245:   switch (what_statement_type)
                   1246:     {
                   1247:     case 'f':
                   1248:     case 'F':
                   1249:     case 's':
                   1250:     case 'S':
                   1251:       prec = 2;
                   1252:       break;
                   1253:
                   1254:     case 'd':
                   1255:     case 'D':
                   1256:     case 'r':
                   1257:     case 'R':
                   1258:       prec = 4;
                   1259:       break;
                   1260:
                   1261:     default:
                   1262:       *sizeP = 0;
                   1263:       return _("Unrecognized or unsupported floating point constant");
                   1264:     }
                   1265:
                   1266:   if (float_value == 0.0)
                   1267:     value = (prec == 2) ? 0x00008000L : 0x80000000L;
                   1268:   else
                   1269:     {
                   1270:       unsigned long exp, sign, mant, tmsfloat;
                   1271:       union
                   1272:       {
                   1273:        float f;
                   1274:        long  l;
                   1275:       }
                   1276:       converter;
                   1277:
                   1278:       converter.f = float_value;
                   1279:       tmsfloat = converter.l;
                   1280:       sign = tmsfloat & 0x80000000;
                   1281:       mant = tmsfloat & 0x007FFFFF;
                   1282:       exp = tmsfloat & 0x7F800000;
                   1283:       exp <<= 1;
                   1284:       if (exp == 0xFF000000)
                   1285:        {
                   1286:          if (mant == 0)
                   1287:            value = 0x7F7FFFFF;
                   1288:          else if (sign == 0)
                   1289:            value = 0x7F7FFFFF;
                   1290:          else
                   1291:            value = 0x7F800000;
                   1292:        }
                   1293:       else
                   1294:        {
                   1295:          exp -= 0x7F000000;
                   1296:          if (sign)
                   1297:            {
                   1298:              mant = mant & 0x007FFFFF;
                   1299:              mant = -mant;
                   1300:              mant = mant & 0x00FFFFFF;
                   1301:              if (mant == 0)
                   1302:                {
                   1303:                  mant |= 0x00800000;
                   1304:                  exp = (long) exp - 0x01000000;
                   1305:                }
                   1306:            }
                   1307:          tmsfloat = exp | mant;
                   1308:          value = tmsfloat;
                   1309:        }
                   1310:       if (prec == 2)
                   1311:        {
                   1312:          long expon, mantis;
                   1313:
                   1314:          if (tmsfloat == 0x80000000)
                   1315:            value = 0x8000;
                   1316:          else
                   1317:            {
                   1318:              value = 0;
                   1319:              expon = (tmsfloat & 0xFF000000);
                   1320:              expon >>= 24;
                   1321:              mantis = tmsfloat & 0x007FFFFF;
                   1322:              if (tmsfloat & 0x00800000)
                   1323:                {
                   1324:                  mantis |= 0xFF000000;
                   1325:                  mantis += 0x00000800;
                   1326:                  mantis >>= 12;
                   1327:                  mantis |= 0x00000800;
                   1328:                  mantis &= 0x0FFF;
                   1329:                  if (expon > 7)
                   1330:                    value = 0x7800;
                   1331:                }
                   1332:              else
                   1333:                {
                   1334:                  mantis |= 0x00800000;
                   1335:                  mantis += 0x00000800;
                   1336:                  expon += (mantis >> 24);
                   1337:                  mantis >>= 12;
                   1338:                  mantis &= 0x07FF;
                   1339:                  if (expon > 7)
                   1340:                    value = 0x77FF;
                   1341:                }
                   1342:              if (expon < -8)
                   1343:                value = 0x8000;
                   1344:              if (value == 0)
                   1345:                {
                   1346:                  mantis = (expon << 12) | mantis;
                   1347:                  value = mantis & 0xFFFF;
                   1348:                }
                   1349:            }
                   1350:        }
                   1351:     }
                   1352:   md_number_to_chars (literalP, value, prec);
                   1353:   *sizeP = prec;
                   1354:   return NULL;
                   1355: }
                   1356:
                   1357: void
                   1358: md_number_to_chars (char *buf, valueT val, int n)
                   1359: {
                   1360:   debug ("In md_number_to_chars()\n");
                   1361:   number_to_chars_bigendian (buf, val, n);
                   1362: }
                   1363:
                   1364: #define F(SZ,PCREL)            (((SZ) << 1) + (PCREL))
                   1365: #define MAP(SZ,PCREL,TYPE)     case F(SZ,PCREL): code = (TYPE); break
                   1366:
                   1367: arelent *
                   1368: tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
                   1369: {
                   1370:   arelent *rel;
                   1371:   bfd_reloc_code_real_type code = 0;
                   1372:
                   1373:   debug ("In tc_gen_reloc()\n");
                   1374:   debug ("fixP.size = %d\n", fixP->fx_size);
                   1375:   debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
                   1376:   debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
                   1377:
                   1378:   switch (F (fixP->fx_size, fixP->fx_pcrel))
                   1379:     {
                   1380:       MAP (1, 0, BFD_RELOC_TIC30_LDP);
                   1381:       MAP (2, 0, BFD_RELOC_16);
                   1382:       MAP (3, 0, BFD_RELOC_24);
                   1383:       MAP (2, 1, BFD_RELOC_16_PCREL);
                   1384:       MAP (4, 0, BFD_RELOC_32);
                   1385:     default:
                   1386:       as_bad (_("Can not do %d byte %srelocation"), fixP->fx_size,
                   1387:              fixP->fx_pcrel ? _("pc-relative ") : "");
                   1388:     }
                   1389: #undef MAP
                   1390: #undef F
                   1391:
1.1.1.3   christos 1392:   rel = XNEW (arelent);
1.1       christos 1393:   gas_assert (rel != 0);
1.1.1.3   christos 1394:   rel->sym_ptr_ptr = XNEW (asymbol *);
1.1       christos 1395:   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
                   1396:   rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
                   1397:   rel->addend = 0;
                   1398:   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
                   1399:   if (!rel->howto)
                   1400:     {
                   1401:       const char *name;
                   1402:
                   1403:       name = S_GET_NAME (fixP->fx_addsy);
                   1404:       if (name == NULL)
                   1405:        name = "<unknown>";
                   1406:       as_fatal ("Cannot generate relocation type for symbol %s, code %s",
                   1407:                name, bfd_get_reloc_code_name (code));
                   1408:     }
                   1409:   return rel;
                   1410: }
                   1411:
                   1412: void
                   1413: md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
                   1414: {
                   1415:   debug ("In md_operand()\n");
                   1416: }
                   1417:
                   1418: void
                   1419: md_assemble (char *line)
                   1420: {
                   1421:   insn_template *op;
                   1422:   char *current_posn;
                   1423:   char *token_start;
                   1424:   char save_char;
                   1425:   unsigned int count;
                   1426:
                   1427:   debug ("In md_assemble() with argument %s\n", line);
                   1428:   memset (&insn, '\0', sizeof (insn));
                   1429:   if (found_parallel_insn)
                   1430:     {
                   1431:       debug ("Line is second part of parallel instruction\n\n");
                   1432:       found_parallel_insn = 0;
                   1433:       return;
                   1434:     }
                   1435:   if ((current_posn =
                   1436:        tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
                   1437:     current_posn = line;
                   1438:   else
                   1439:     found_parallel_insn = 1;
                   1440:
                   1441:   while (is_space_char (*current_posn))
                   1442:     current_posn++;
                   1443:
                   1444:   token_start = current_posn;
                   1445:
                   1446:   if (!is_opcode_char (*current_posn))
                   1447:     {
                   1448:       as_bad (_("Invalid character %s in opcode"),
                   1449:              output_invalid (*current_posn));
                   1450:       return;
                   1451:     }
                   1452:   /* Check if instruction is a parallel instruction
                   1453:      by seeing if the first character is a q.  */
                   1454:   if (*token_start == 'q')
                   1455:     {
                   1456:       if (tic30_parallel_insn (token_start))
                   1457:        {
                   1458:          if (found_parallel_insn)
                   1459:            free (token_start);
                   1460:          return;
                   1461:        }
                   1462:     }
                   1463:   while (is_opcode_char (*current_posn))
                   1464:     current_posn++;
                   1465:   {
                   1466:     /* Find instruction.  */
                   1467:     save_char = *current_posn;
                   1468:     *current_posn = '\0';
                   1469:     op = (insn_template *) hash_find (op_hash, token_start);
                   1470:     if (op)
                   1471:       {
                   1472:        debug ("Found instruction %s\n", op->name);
                   1473:        insn.tm = op;
                   1474:       }
                   1475:     else
                   1476:       {
                   1477:        debug ("Didn't find insn\n");
                   1478:        as_bad (_("Unknown TMS320C30 instruction: %s"), token_start);
                   1479:        return;
                   1480:       }
                   1481:     *current_posn = save_char;
                   1482:   }
                   1483:
                   1484:   if (*current_posn != END_OF_INSN)
                   1485:     {
                   1486:       /* Find operands.  */
                   1487:       int paren_not_balanced;
                   1488:       int expecting_operand = 0;
                   1489:       int this_operand;
                   1490:       do
                   1491:        {
                   1492:          /* Skip optional white space before operand.  */
                   1493:          while (!is_operand_char (*current_posn)
                   1494:                 && *current_posn != END_OF_INSN)
                   1495:            {
                   1496:              if (!is_space_char (*current_posn))
                   1497:                {
                   1498:                  as_bad (_("Invalid character %s before %s operand"),
                   1499:                          output_invalid (*current_posn),
                   1500:                          ordinal_names[insn.operands]);
                   1501:                  return;
                   1502:                }
                   1503:              current_posn++;
                   1504:            }
                   1505:          token_start = current_posn;
                   1506:          paren_not_balanced = 0;
                   1507:          while (paren_not_balanced || *current_posn != ',')
                   1508:            {
                   1509:              if (*current_posn == END_OF_INSN)
                   1510:                {
                   1511:                  if (paren_not_balanced)
                   1512:                    {
                   1513:                      as_bad (_("Unbalanced parenthesis in %s operand."),
                   1514:                              ordinal_names[insn.operands]);
                   1515:                      return;
                   1516:                    }
                   1517:                  else
                   1518:                    break;
                   1519:                }
                   1520:              else if (!is_operand_char (*current_posn)
                   1521:                       && !is_space_char (*current_posn))
                   1522:                {
                   1523:                  as_bad (_("Invalid character %s in %s operand"),
                   1524:                          output_invalid (*current_posn),
                   1525:                          ordinal_names[insn.operands]);
                   1526:                  return;
                   1527:                }
                   1528:              if (*current_posn == '(')
                   1529:                ++paren_not_balanced;
                   1530:              if (*current_posn == ')')
                   1531:                --paren_not_balanced;
                   1532:              current_posn++;
                   1533:            }
                   1534:          if (current_posn != token_start)
                   1535:            {
                   1536:              /* Yes, we've read in another operand.  */
                   1537:              this_operand = insn.operands++;
                   1538:              if (insn.operands > MAX_OPERANDS)
                   1539:                {
                   1540:                  as_bad (_("Spurious operands; (%d operands/instruction max)"),
                   1541:                          MAX_OPERANDS);
                   1542:                  return;
                   1543:                }
                   1544:
                   1545:              /* Now parse operand adding info to 'insn' as we go along.  */
                   1546:              save_char = *current_posn;
                   1547:              *current_posn = '\0';
                   1548:              insn.operand_type[this_operand] = tic30_operand (token_start);
                   1549:              *current_posn = save_char;
                   1550:              if (insn.operand_type[this_operand] == NULL)
                   1551:                return;
                   1552:            }
                   1553:          else
                   1554:            {
                   1555:              if (expecting_operand)
                   1556:                {
                   1557:                  as_bad (_("Expecting operand after ','; got nothing"));
                   1558:                  return;
                   1559:                }
                   1560:              if (*current_posn == ',')
                   1561:                {
                   1562:                  as_bad (_("Expecting operand before ','; got nothing"));
                   1563:                  return;
                   1564:                }
                   1565:            }
                   1566:
                   1567:          /* Now *current_posn must be either ',' or END_OF_INSN.  */
                   1568:          if (*current_posn == ',')
                   1569:            {
                   1570:              if (*++current_posn == END_OF_INSN)
                   1571:                {
                   1572:                  /* Just skip it, if it's \n complain.  */
                   1573:                  as_bad (_("Expecting operand after ','; got nothing"));
                   1574:                  return;
                   1575:                }
                   1576:              expecting_operand = 1;
                   1577:            }
                   1578:        }
                   1579:       while (*current_posn != END_OF_INSN);
                   1580:     }
                   1581:
                   1582:   debug ("Number of operands found: %d\n", insn.operands);
                   1583:
                   1584:   /* Check that number of operands is correct.  */
                   1585:   if (insn.operands != insn.tm->operands)
                   1586:     {
                   1587:       unsigned int i;
                   1588:       unsigned int numops = insn.tm->operands;
                   1589:
                   1590:       /* If operands are not the same, then see if any of the operands are
                   1591:         not required.  Then recheck with number of given operands.  If they
                   1592:         are still not the same, then give an error, otherwise carry on.  */
                   1593:       for (i = 0; i < insn.tm->operands; i++)
                   1594:        if (insn.tm->operand_types[i] & NotReq)
                   1595:          numops--;
                   1596:       if (insn.operands != numops)
                   1597:        {
                   1598:          as_bad (_("Incorrect number of operands given"));
                   1599:          return;
                   1600:        }
                   1601:     }
                   1602:   insn.addressing_mode = AM_NotReq;
                   1603:   for (count = 0; count < insn.operands; count++)
                   1604:     {
                   1605:       if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
                   1606:        {
                   1607:          debug ("Operand %d matches\n", count + 1);
                   1608:          /* If instruction has two operands and has an AddressMode
                   1609:             modifier then set addressing mode type for instruction.  */
                   1610:          if (insn.tm->opcode_modifier == AddressMode)
                   1611:            {
                   1612:              int addr_insn = 0;
                   1613:              /* Store instruction uses the second
                   1614:                 operand for the address mode.  */
                   1615:              if ((insn.tm->operand_types[1] & (Indirect | Direct))
                   1616:                  == (Indirect | Direct))
                   1617:                addr_insn = 1;
                   1618:
                   1619:              if (insn.operand_type[addr_insn]->op_type & (AllReg))
                   1620:                insn.addressing_mode = AM_Register;
                   1621:              else if (insn.operand_type[addr_insn]->op_type & Direct)
                   1622:                insn.addressing_mode = AM_Direct;
                   1623:              else if (insn.operand_type[addr_insn]->op_type & Indirect)
                   1624:                insn.addressing_mode = AM_Indirect;
                   1625:              else
                   1626:                insn.addressing_mode = AM_Immediate;
                   1627:            }
                   1628:        }
                   1629:       else
                   1630:        {
                   1631:          as_bad (_("The %s operand doesn't match"), ordinal_names[count]);
                   1632:          return;
                   1633:        }
                   1634:     }
                   1635:
                   1636:   /* Now set the addressing mode for 3 operand instructions.  */
                   1637:   if ((insn.tm->operand_types[0] & op3T1)
                   1638:       && (insn.tm->operand_types[1] & op3T2))
                   1639:     {
                   1640:       /* Set the addressing mode to the values used for 2 operand
                   1641:         instructions in the  G addressing field of the opcode.  */
                   1642:       char *p;
                   1643:       switch (insn.operand_type[0]->op_type)
                   1644:        {
                   1645:        case Rn:
                   1646:        case ARn:
                   1647:        case DPReg:
                   1648:        case OtherReg:
                   1649:          if (insn.operand_type[1]->op_type & (AllReg))
                   1650:            insn.addressing_mode = AM_Register;
                   1651:          else if (insn.operand_type[1]->op_type & Indirect)
                   1652:            insn.addressing_mode = AM_Direct;
                   1653:          else
                   1654:            {
                   1655:              /* Shouldn't make it to this stage.  */
                   1656:              as_bad (_("Incompatible first and second operands in instruction"));
                   1657:              return;
                   1658:            }
                   1659:          break;
                   1660:        case Indirect:
                   1661:          if (insn.operand_type[1]->op_type & (AllReg))
                   1662:            insn.addressing_mode = AM_Indirect;
                   1663:          else if (insn.operand_type[1]->op_type & Indirect)
                   1664:            insn.addressing_mode = AM_Immediate;
                   1665:          else
                   1666:            {
                   1667:              /* Shouldn't make it to this stage.  */
                   1668:              as_bad (_("Incompatible first and second operands in instruction"));
                   1669:              return;
                   1670:            }
                   1671:          break;
                   1672:        }
                   1673:       /* Now make up the opcode for the 3 operand instructions.  As in
                   1674:         parallel instructions, there will be no unresolved values, so they
                   1675:         can be fully formed and added to the frag table.  */
                   1676:       insn.opcode = insn.tm->base_opcode;
                   1677:       if (insn.operand_type[0]->op_type & Indirect)
                   1678:        {
                   1679:          insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
                   1680:          insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
                   1681:        }
                   1682:       else
                   1683:        insn.opcode |= (insn.operand_type[0]->reg.opcode);
                   1684:
                   1685:       if (insn.operand_type[1]->op_type & Indirect)
                   1686:        {
                   1687:          insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
                   1688:          insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
                   1689:        }
                   1690:       else
                   1691:        insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
                   1692:
                   1693:       if (insn.operands == 3)
                   1694:        insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
                   1695:
                   1696:       insn.opcode |= insn.addressing_mode;
                   1697:       p = frag_more (INSN_SIZE);
                   1698:       md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1699:     }
                   1700:   else
                   1701:     {
                   1702:       /* Not a three operand instruction.  */
                   1703:       char *p;
                   1704:       int am_insn = -1;
                   1705:       insn.opcode = insn.tm->base_opcode;
                   1706:       /* Create frag for instruction - all instructions are 4 bytes long.  */
                   1707:       p = frag_more (INSN_SIZE);
                   1708:       if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
                   1709:        {
                   1710:          insn.opcode |= insn.addressing_mode;
                   1711:          if (insn.addressing_mode == AM_Indirect)
                   1712:            {
                   1713:              /* Determine which operand gives the addressing mode.  */
                   1714:              if (insn.operand_type[0]->op_type & Indirect)
                   1715:                am_insn = 0;
                   1716:              if ((insn.operands > 1)
                   1717:                  && (insn.operand_type[1]->op_type & Indirect))
                   1718:                am_insn = 1;
                   1719:              insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
                   1720:              insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
                   1721:              insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
                   1722:              if (insn.operands > 1)
                   1723:                insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
                   1724:              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1725:            }
                   1726:          else if (insn.addressing_mode == AM_Register)
                   1727:            {
                   1728:              insn.opcode |= (insn.operand_type[0]->reg.opcode);
                   1729:              if (insn.operands > 1)
                   1730:                insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
                   1731:              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1732:            }
                   1733:          else if (insn.addressing_mode == AM_Direct)
                   1734:            {
                   1735:              if (insn.operand_type[0]->op_type & Direct)
                   1736:                am_insn = 0;
                   1737:              if ((insn.operands > 1)
                   1738:                  && (insn.operand_type[1]->op_type & Direct))
                   1739:                am_insn = 1;
                   1740:              if (insn.operands > 1)
                   1741:                insn.opcode |=
                   1742:                  (insn.operand_type[! am_insn]->reg.opcode << 16);
                   1743:              if (insn.operand_type[am_insn]->direct.resolved == 1)
                   1744:                {
                   1745:                  /* Resolved values can be placed straight
                   1746:                     into instruction word, and output.  */
                   1747:                  insn.opcode |=
                   1748:                    (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
                   1749:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1750:                }
                   1751:              else
                   1752:                {
                   1753:                  /* Unresolved direct addressing mode instruction.  */
                   1754:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1755:                  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
                   1756:                               & insn.operand_type[am_insn]->direct.direct_expr,
                   1757:                               0, 0);
                   1758:                }
                   1759:            }
                   1760:          else if (insn.addressing_mode == AM_Immediate)
                   1761:            {
                   1762:              if (insn.operand_type[0]->immediate.resolved == 1)
                   1763:                {
                   1764:                  char *keeploc;
                   1765:                  int size;
                   1766:
                   1767:                  if (insn.operands > 1)
                   1768:                    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
                   1769:
                   1770:                  switch (insn.tm->imm_arg_type)
                   1771:                    {
                   1772:                    case Imm_Float:
                   1773:                      debug ("Floating point first operand\n");
                   1774:                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1775:
                   1776:                      keeploc = input_line_pointer;
                   1777:                      input_line_pointer =
                   1778:                        insn.operand_type[0]->immediate.label;
                   1779:
                   1780:                      if (md_atof ('f', p + 2, & size) != 0)
                   1781:                        {
                   1782:                          as_bad (_("invalid short form floating point immediate operand"));
                   1783:                          return;
                   1784:                        }
                   1785:
                   1786:                      input_line_pointer = keeploc;
                   1787:                      break;
                   1788:
                   1789:                    case Imm_UInt:
                   1790:                      debug ("Unsigned int first operand\n");
                   1791:                      if (insn.operand_type[0]->immediate.decimal_found)
                   1792:                        as_warn (_("rounding down first operand float to unsigned int"));
                   1793:                      if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
                   1794:                        as_warn (_("only lower 16-bits of first operand are used"));
                   1795:                      insn.opcode |=
                   1796:                        (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
                   1797:                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1798:                      break;
                   1799:
                   1800:                    case Imm_SInt:
                   1801:                      debug ("Int first operand\n");
                   1802:
                   1803:                      if (insn.operand_type[0]->immediate.decimal_found)
                   1804:                        as_warn (_("rounding down first operand float to signed int"));
                   1805:
                   1806:                      if (insn.operand_type[0]->immediate.s_number < -32768 ||
                   1807:                          insn.operand_type[0]->immediate.s_number > 32767)
                   1808:                        {
                   1809:                          as_bad (_("first operand is too large for 16-bit signed int"));
                   1810:                          return;
                   1811:                        }
                   1812:                      insn.opcode |=
                   1813:                        (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
                   1814:                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1815:                      break;
                   1816:                    }
                   1817:                }
                   1818:              else
                   1819:                {
                   1820:                  /* Unresolved immediate label.  */
                   1821:                  if (insn.operands > 1)
                   1822:                    insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
                   1823:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1824:                  fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
                   1825:                               & insn.operand_type[0]->immediate.imm_expr,
                   1826:                               0, 0);
                   1827:                }
                   1828:            }
                   1829:        }
                   1830:       else if (insn.tm->opcode_modifier == PCRel)
                   1831:        {
                   1832:          /* Conditional Branch and Call instructions.  */
                   1833:          if ((insn.tm->operand_types[0] & (AllReg | Disp))
                   1834:              == (AllReg | Disp))
                   1835:            {
                   1836:              if (insn.operand_type[0]->op_type & (AllReg))
                   1837:                {
                   1838:                  insn.opcode |= (insn.operand_type[0]->reg.opcode);
                   1839:                  insn.opcode |= PC_Register;
                   1840:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1841:                }
                   1842:              else
                   1843:                {
                   1844:                  insn.opcode |= PC_Relative;
                   1845:                  if (insn.operand_type[0]->immediate.resolved == 1)
                   1846:                    {
                   1847:                      insn.opcode |=
                   1848:                        (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
                   1849:                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1850:                    }
                   1851:                  else
                   1852:                    {
                   1853:                      md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1854:                      fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
                   1855:                                   2, & insn.operand_type[0]->immediate.imm_expr,
                   1856:                                   1, 0);
                   1857:                    }
                   1858:                }
                   1859:            }
                   1860:          else if ((insn.tm->operand_types[0] & ARn) == ARn)
                   1861:            {
                   1862:              /* Decrement and Branch instructions.  */
                   1863:              insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
                   1864:              if (insn.operand_type[1]->op_type & (AllReg))
                   1865:                {
                   1866:                  insn.opcode |= (insn.operand_type[1]->reg.opcode);
                   1867:                  insn.opcode |= PC_Register;
                   1868:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1869:                }
                   1870:              else if (insn.operand_type[1]->immediate.resolved == 1)
                   1871:                {
                   1872:                  if (insn.operand_type[0]->immediate.decimal_found)
                   1873:                    {
                   1874:                      as_bad (_("first operand is floating point"));
                   1875:                      return;
                   1876:                    }
                   1877:                  if (insn.operand_type[0]->immediate.s_number < -32768 ||
                   1878:                      insn.operand_type[0]->immediate.s_number > 32767)
                   1879:                    {
                   1880:                      as_bad (_("first operand is too large for 16-bit signed int"));
                   1881:                      return;
                   1882:                    }
                   1883:                  insn.opcode |= (insn.operand_type[1]->immediate.s_number);
                   1884:                  insn.opcode |= PC_Relative;
                   1885:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1886:                }
                   1887:              else
                   1888:                {
                   1889:                  insn.opcode |= PC_Relative;
                   1890:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1891:                  fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
                   1892:                               & insn.operand_type[1]->immediate.imm_expr,
                   1893:                               1, 0);
                   1894:                }
                   1895:            }
                   1896:        }
                   1897:       else if (insn.tm->operand_types[0] == IVector)
                   1898:        {
                   1899:          /* Trap instructions.  */
                   1900:          if (insn.operand_type[0]->op_type & IVector)
                   1901:            insn.opcode |= (insn.operand_type[0]->immediate.u_number);
                   1902:          else
                   1903:            {
                   1904:              /* Shouldn't get here.  */
                   1905:              as_bad (_("interrupt vector for trap instruction out of range"));
                   1906:              return;
                   1907:            }
                   1908:          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1909:        }
                   1910:       else if (insn.tm->opcode_modifier == StackOp
                   1911:               || insn.tm->opcode_modifier == Rotate)
                   1912:        {
                   1913:          /* Push, Pop and Rotate instructions.  */
                   1914:          insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
                   1915:          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1916:        }
                   1917:       else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
                   1918:               == (Abs24 | Direct))
                   1919:        {
                   1920:          /* LDP Instruction needs to be tested
                   1921:             for before the next section.  */
                   1922:          if (insn.operand_type[0]->op_type & Direct)
                   1923:            {
                   1924:              if (insn.operand_type[0]->direct.resolved == 1)
                   1925:                {
                   1926:                  /* Direct addressing uses lower 8 bits of direct address.  */
                   1927:                  insn.opcode |=
                   1928:                    (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
                   1929:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1930:                }
                   1931:              else
                   1932:                {
                   1933:                  fixS *fix;
                   1934:
                   1935:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1936:                  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
                   1937:                                     1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
                   1938:                  /* Ensure that the assembler doesn't complain
                   1939:                     about fitting a 24-bit address into 8 bits.  */
                   1940:                  fix->fx_no_overflow = 1;
                   1941:                }
                   1942:            }
                   1943:          else
                   1944:            {
                   1945:              if (insn.operand_type[0]->immediate.resolved == 1)
                   1946:                {
                   1947:                  /* Immediate addressing uses upper 8 bits of address.  */
                   1948:                  if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
                   1949:                    {
                   1950:                      as_bad (_("LDP instruction needs a 24-bit operand"));
                   1951:                      return;
                   1952:                    }
                   1953:                  insn.opcode |=
                   1954:                    ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
                   1955:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1956:                }
                   1957:              else
                   1958:                {
                   1959:                  fixS *fix;
                   1960:                  md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1961:                  fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
                   1962:                                     1, &insn.operand_type[0]->immediate.imm_expr,
                   1963:                                     0, 0);
                   1964:                  fix->fx_no_overflow = 1;
                   1965:                }
                   1966:            }
                   1967:        }
                   1968:       else if (insn.tm->operand_types[0] & (Imm24))
                   1969:        {
                   1970:          /* Unconditional Branch and Call instructions.  */
                   1971:          if (insn.operand_type[0]->immediate.resolved == 1)
                   1972:            {
                   1973:              if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
                   1974:                as_warn (_("first operand is too large for a 24-bit displacement"));
                   1975:              insn.opcode |=
                   1976:                (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
                   1977:              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1978:            }
                   1979:          else
                   1980:            {
                   1981:              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1982:              fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
                   1983:                           & insn.operand_type[0]->immediate.imm_expr, 0, 0);
                   1984:            }
                   1985:        }
                   1986:       else if (insn.tm->operand_types[0] & NotReq)
                   1987:        /* Check for NOP instruction without arguments.  */
                   1988:        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1989:
                   1990:       else if (insn.tm->operands == 0)
                   1991:        /* Check for instructions without operands.  */
                   1992:        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
                   1993:     }
                   1994:   debug ("Addressing mode: %08X\n", insn.addressing_mode);
                   1995:   {
                   1996:     unsigned int i;
                   1997:
                   1998:     for (i = 0; i < insn.operands; i++)
                   1999:       {
                   2000:        if (insn.operand_type[i]->immediate.label)
                   2001:          free (insn.operand_type[i]->immediate.label);
                   2002:        free (insn.operand_type[i]);
                   2003:       }
                   2004:   }
                   2005:   debug ("Final opcode: %08X\n", insn.opcode);
                   2006:   debug ("\n");
                   2007: }

CVSweb <webmaster@jp.NetBSD.org>