Back to index

cell-binutils  2.17cvs20070401
tc-tic30.c
Go to the documentation of this file.
00001 /* tc-c30.c -- Assembly code for the Texas Instruments TMS320C30
00002    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2006
00003    Free Software Foundation, Inc.
00004    Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
00005 
00006    This file is part of GAS, the GNU Assembler.
00007 
00008    GAS is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2, or (at your option)
00011    any later version.
00012 
00013    GAS is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with GAS; see the file COPYING.  If not, write to the Free
00020    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
00021    02110-1301, USA.  */
00022 
00023 /* Texas Instruments TMS320C30 machine specific gas.
00024    Written by Steven Haworth (steve@pm.cse.rmit.edu.au).
00025    Bugs & suggestions are completely welcome.  This is free software.
00026    Please help us make it better.  */
00027 
00028 #include "as.h"
00029 #include "safe-ctype.h"
00030 #include "opcode/tic30.h"
00031 
00032 /* Put here all non-digit non-letter characters that may occur in an
00033    operand.  */
00034 static char operand_special_chars[] = "%$-+(,)*._~/<>&^!:[@]";
00035 static char *ordinal_names[] =
00036 {
00037   "first", "second", "third", "fourth", "fifth"
00038 };
00039 
00040 const char comment_chars[]        = ";";
00041 const char line_comment_chars[]   = "*";
00042 const char line_separator_chars[] = "";
00043 
00044 const char *md_shortopts = "";
00045 struct option md_longopts[] =
00046 {
00047   {NULL, no_argument, NULL, 0}
00048 };
00049 
00050 size_t md_longopts_size = sizeof (md_longopts);
00051 
00052 /* Chars that mean this number is a floating point constant.
00053    As in 0f12.456
00054    or    0d1.2345e12.  */
00055 const char FLT_CHARS[] = "fFdDxX";
00056 
00057 /* Chars that can be used to separate mant from exp in floating point
00058    nums.  */
00059 const char EXP_CHARS[] = "eE";
00060 
00061 /* Tables for lexical analysis.  */
00062 static char opcode_chars[256];
00063 static char register_chars[256];
00064 static char operand_chars[256];
00065 static char space_chars[256];
00066 static char identifier_chars[256];
00067 static char digit_chars[256];
00068 
00069 /* Lexical macros.  */
00070 #define is_opcode_char(x)     (opcode_chars     [(unsigned char) x])
00071 #define is_operand_char(x)    (operand_chars    [(unsigned char) x])
00072 #define is_register_char(x)   (register_chars   [(unsigned char) x])
00073 #define is_space_char(x)      (space_chars      [(unsigned char) x])
00074 #define is_identifier_char(x) (identifier_chars [(unsigned char) x])
00075 #define is_digit_char(x)      (digit_chars      [(unsigned char) x])
00076 
00077 const pseudo_typeS md_pseudo_table[] =
00078 {
00079   {0, 0, 0}
00080 };
00081 
00082 static int ATTRIBUTE_PRINTF_1
00083 debug (const char *string, ...)
00084 {
00085   if (flag_debug)
00086     {
00087       char str[100];
00088 
00089       VA_OPEN (argptr, string);
00090       VA_FIXEDARG (argptr, const char *, string);
00091       vsprintf (str, string, argptr);
00092       VA_CLOSE (argptr);
00093       if (str[0] == '\0')
00094        return (0);
00095       fputs (str, USE_STDOUT ? stdout : stderr);
00096       return strlen (str);
00097     }
00098   else
00099     return 0;
00100 }
00101 
00102 /* Hash table for opcode lookup.  */
00103 static struct hash_control *op_hash;
00104 /* Hash table for parallel opcode lookup.  */
00105 static struct hash_control *parop_hash;
00106 /* Hash table for register lookup.  */
00107 static struct hash_control *reg_hash;
00108 /* Hash table for indirect addressing lookup.  */
00109 static struct hash_control *ind_hash;
00110 
00111 void
00112 md_begin (void)
00113 {
00114   const char *hash_err;
00115 
00116   debug ("In md_begin()\n");
00117   op_hash = hash_new ();
00118 
00119   {
00120     const template *current_optab = tic30_optab;
00121 
00122     for (; current_optab < tic30_optab_end; current_optab++)
00123       {
00124        hash_err = hash_insert (op_hash, current_optab->name,
00125                             (char *) current_optab);
00126        if (hash_err)
00127          as_fatal ("Internal Error: Can't Hash %s: %s",
00128                   current_optab->name, hash_err);
00129       }
00130   }
00131 
00132   parop_hash = hash_new ();
00133 
00134   {
00135     const partemplate *current_parop = tic30_paroptab;
00136 
00137     for (; current_parop < tic30_paroptab_end; current_parop++)
00138       {
00139        hash_err = hash_insert (parop_hash, current_parop->name,
00140                             (char *) current_parop);
00141        if (hash_err)
00142          as_fatal ("Internal Error: Can't Hash %s: %s",
00143                   current_parop->name, hash_err);
00144       }
00145   }
00146 
00147   reg_hash = hash_new ();
00148 
00149   {
00150     const reg *current_reg = tic30_regtab;
00151 
00152     for (; current_reg < tic30_regtab_end; current_reg++)
00153       {
00154        hash_err = hash_insert (reg_hash, current_reg->name,
00155                             (char *) current_reg);
00156        if (hash_err)
00157          as_fatal ("Internal Error: Can't Hash %s: %s",
00158                   current_reg->name, hash_err);
00159       }
00160   }
00161 
00162   ind_hash = hash_new ();
00163 
00164   {
00165     const ind_addr_type *current_ind = tic30_indaddr_tab;
00166 
00167     for (; current_ind < tic30_indaddrtab_end; current_ind++)
00168       {
00169        hash_err = hash_insert (ind_hash, current_ind->syntax,
00170                             (char *) current_ind);
00171        if (hash_err)
00172          as_fatal ("Internal Error: Can't Hash %s: %s",
00173                   current_ind->syntax, hash_err);
00174       }
00175   }
00176 
00177   /* Fill in lexical tables:  opcode_chars, operand_chars, space_chars.  */
00178   {
00179     int c;
00180     char *p;
00181 
00182     for (c = 0; c < 256; c++)
00183       {
00184        if (ISLOWER (c) || ISDIGIT (c))
00185          {
00186            opcode_chars[c] = c;
00187            register_chars[c] = c;
00188          }
00189        else if (ISUPPER (c))
00190          {
00191            opcode_chars[c] = TOLOWER (c);
00192            register_chars[c] = opcode_chars[c];
00193          }
00194        else if (c == ')' || c == '(')
00195          register_chars[c] = c;
00196 
00197        if (ISUPPER (c) || ISLOWER (c) || ISDIGIT (c))
00198          operand_chars[c] = c;
00199 
00200        if (ISDIGIT (c) || c == '-')
00201          digit_chars[c] = c;
00202 
00203        if (ISALPHA (c) || c == '_' || c == '.' || ISDIGIT (c))
00204          identifier_chars[c] = c;
00205 
00206        if (c == ' ' || c == '\t')
00207          space_chars[c] = c;
00208 
00209        if (c == '_')
00210          opcode_chars[c] = c;
00211       }
00212     for (p = operand_special_chars; *p != '\0'; p++)
00213       operand_chars[(unsigned char) *p] = *p;
00214   }
00215 }
00216 
00217 /* Address Mode OR values.  */
00218 #define AM_Register  0x00000000
00219 #define AM_Direct    0x00200000
00220 #define AM_Indirect  0x00400000
00221 #define AM_Immediate 0x00600000
00222 #define AM_NotReq    0xFFFFFFFF
00223 
00224 /* PC Relative OR values.  */
00225 #define PC_Register 0x00000000
00226 #define PC_Relative 0x02000000
00227 
00228 typedef struct
00229 {
00230   unsigned op_type;
00231   struct
00232   {
00233     int resolved;
00234     unsigned address;
00235     char *label;
00236     expressionS direct_expr;
00237   } direct;
00238   struct
00239   {
00240     unsigned mod;
00241     int ARnum;
00242     unsigned char disp;
00243   } indirect;
00244   struct
00245   {
00246     unsigned opcode;
00247   } reg;
00248   struct
00249   {
00250     int resolved;
00251     int decimal_found;
00252     float f_number;
00253     int s_number;
00254     unsigned int u_number;
00255     char *label;
00256     expressionS imm_expr;
00257   } immediate;
00258 } operand;
00259 
00260 template *opcode;
00261 
00262 struct tic30_insn
00263 {
00264   template *tm;                    /* Template of current instruction.  */
00265   unsigned opcode;          /* Final opcode.  */
00266   unsigned int operands;    /* Number of given operands.  */
00267   /* Type of operand given in instruction.  */
00268   operand *operand_type[MAX_OPERANDS];
00269   unsigned addressing_mode; /* Final addressing mode of instruction.  */
00270 };
00271 
00272 struct tic30_insn insn;
00273 static int found_parallel_insn;
00274 
00275 static char output_invalid_buf[sizeof (unsigned char) * 2 + 6];
00276 
00277 static char *
00278 output_invalid (char c)
00279 {
00280   if (ISPRINT (c))
00281     snprintf (output_invalid_buf, sizeof (output_invalid_buf),
00282              "'%c'", c);
00283   else
00284     snprintf (output_invalid_buf, sizeof (output_invalid_buf), 
00285              "(0x%x)", (unsigned char) c);
00286   return output_invalid_buf;
00287 }
00288 
00289 /* next_line points to the next line after the current instruction
00290    (current_line).  Search for the parallel bars, and if found, merge two
00291    lines into internal syntax for a parallel instruction:
00292      q_[INSN1]_[INSN2] [OPERANDS1] | [OPERANDS2]
00293    By this stage, all comments are scrubbed, and only the bare lines are
00294    given.  */
00295 
00296 #define NONE           0
00297 #define START_OPCODE   1
00298 #define END_OPCODE     2
00299 #define START_OPERANDS 3
00300 #define END_OPERANDS   4
00301 
00302 static char *
00303 tic30_find_parallel_insn (char *current_line, char *next_line)
00304 {
00305   int found_parallel = 0;
00306   char first_opcode[256];
00307   char second_opcode[256];
00308   char first_operands[256];
00309   char second_operands[256];
00310   char *parallel_insn;
00311 
00312   debug ("In tic30_find_parallel_insn()\n");
00313   while (!is_end_of_line[(unsigned char) *next_line])
00314     {
00315       if (*next_line == PARALLEL_SEPARATOR
00316          && *(next_line + 1) == PARALLEL_SEPARATOR)
00317        {
00318          found_parallel = 1;
00319          next_line++;
00320          break;
00321        }
00322       next_line++;
00323     }
00324   if (!found_parallel)
00325     return NULL;
00326   debug ("Found a parallel instruction\n");
00327 
00328   {
00329     int i;
00330     char *opcode, *operands, *line;
00331 
00332     for (i = 0; i < 2; i++)
00333       {
00334        if (i == 0)
00335          {
00336            opcode = &first_opcode[0];
00337            operands = &first_operands[0];
00338            line = current_line;
00339          }
00340        else
00341          {
00342            opcode = &second_opcode[0];
00343            operands = &second_operands[0];
00344            line = next_line;
00345          }
00346 
00347        {
00348          int search_status = NONE;
00349          int char_ptr = 0;
00350          char c;
00351 
00352          while (!is_end_of_line[(unsigned char) (c = *line)])
00353            {
00354              if (is_opcode_char (c) && search_status == NONE)
00355               {
00356                 opcode[char_ptr++] = TOLOWER (c);
00357                 search_status = START_OPCODE;
00358               }
00359              else if (is_opcode_char (c) && search_status == START_OPCODE)
00360               opcode[char_ptr++] = TOLOWER (c);
00361              else if (!is_opcode_char (c) && search_status == START_OPCODE)
00362               {
00363                 opcode[char_ptr] = '\0';
00364                 char_ptr = 0;
00365                 search_status = END_OPCODE;
00366               }
00367              else if (is_operand_char (c) && search_status == START_OPERANDS)
00368               operands[char_ptr++] = c;
00369 
00370              if (is_operand_char (c) && search_status == END_OPCODE)
00371               {
00372                 operands[char_ptr++] = c;
00373                 search_status = START_OPERANDS;
00374               }
00375 
00376              line++;
00377            }
00378          if (search_status != START_OPERANDS)
00379            return NULL;
00380          operands[char_ptr] = '\0';
00381        }
00382       }
00383   }
00384   parallel_insn = malloc (strlen (first_opcode) + strlen (first_operands)
00385                        + strlen (second_opcode) + strlen (second_operands) + 8);
00386   sprintf (parallel_insn, "q_%s_%s %s | %s",
00387           first_opcode, second_opcode,
00388           first_operands, second_operands);
00389   debug ("parallel insn = %s\n", parallel_insn);
00390   return parallel_insn;
00391 }
00392 
00393 #undef NONE
00394 #undef START_OPCODE
00395 #undef END_OPCODE
00396 #undef START_OPERANDS
00397 #undef END_OPERANDS
00398 
00399 static operand *
00400 tic30_operand (char *token)
00401 {
00402   unsigned int count;
00403   char ind_buffer[strlen (token)];
00404   operand *current_op;
00405 
00406   debug ("In tic30_operand with %s\n", token);
00407   current_op = malloc (sizeof (* current_op));
00408   memset (current_op, '\0', sizeof (operand));
00409 
00410   if (*token == DIRECT_REFERENCE)
00411     {
00412       char *token_posn = token + 1;
00413       int direct_label = 0;
00414 
00415       debug ("Found direct reference\n");
00416       while (*token_posn)
00417        {
00418          if (!is_digit_char (*token_posn))
00419            direct_label = 1;
00420          token_posn++;
00421        }
00422 
00423       if (direct_label)
00424        {
00425          char *save_input_line_pointer;
00426          segT retval;
00427 
00428          debug ("Direct reference is a label\n");
00429          current_op->direct.label = token + 1;
00430          save_input_line_pointer = input_line_pointer;
00431          input_line_pointer = token + 1;
00432          debug ("Current input_line_pointer: %s\n", input_line_pointer);
00433          retval = expression (&current_op->direct.direct_expr);
00434 
00435          debug ("Expression type: %d\n",
00436                current_op->direct.direct_expr.X_op);
00437          debug ("Expression addnum: %ld\n",
00438                (long) current_op->direct.direct_expr.X_add_number);
00439          debug ("Segment: %p\n", retval);
00440 
00441          input_line_pointer = save_input_line_pointer;
00442 
00443          if (current_op->direct.direct_expr.X_op == O_constant)
00444            {
00445              current_op->direct.address =
00446               current_op->direct.direct_expr.X_add_number;
00447              current_op->direct.resolved = 1;
00448            }
00449        }
00450       else
00451        {
00452          debug ("Direct reference is a number\n");
00453          current_op->direct.address = atoi (token + 1);
00454          current_op->direct.resolved = 1;
00455        }
00456       current_op->op_type = Direct;
00457     }
00458   else if (*token == INDIRECT_REFERENCE)
00459     {
00460       /* Indirect reference operand.  */
00461       int found_ar = 0;
00462       int found_disp = 0;
00463       int ar_number = -1;
00464       int disp_number = 0;
00465       int buffer_posn = 1;
00466       ind_addr_type *ind_addr_op;
00467 
00468       debug ("Found indirect reference\n");
00469       ind_buffer[0] = *token;
00470 
00471       for (count = 1; count < strlen (token); count++)
00472        {
00473          /* Strip operand.  */
00474          ind_buffer[buffer_posn] = TOLOWER (*(token + count));
00475 
00476          if ((*(token + count - 1) == 'a' || *(token + count - 1) == 'A')
00477              && (*(token + count) == 'r' || *(token + count) == 'R'))
00478            {
00479              /* AR reference is found, so get its number and remove
00480                it from the buffer so it can pass through hash_find().  */
00481              if (found_ar)
00482               {
00483                 as_bad ("More than one AR register found in indirect reference");
00484                 return NULL;
00485               }
00486              if (*(token + count + 1) < '0' || *(token + count + 1) > '7')
00487               {
00488                 as_bad ("Illegal AR register in indirect reference");
00489                 return NULL;
00490               }
00491              ar_number = *(token + count + 1) - '0';
00492              found_ar = 1;
00493              count++;
00494            }
00495 
00496          if (*(token + count) == '(')
00497            {
00498              /* Parenthesis found, so check if a displacement value is
00499                inside.  If so, get the value and remove it from the
00500                buffer.  */
00501              if (is_digit_char (*(token + count + 1)))
00502               {
00503                 char disp[10];
00504                 int disp_posn = 0;
00505 
00506                 if (found_disp)
00507                   {
00508                     as_bad ("More than one displacement found in indirect reference");
00509                     return NULL;
00510                   }
00511                 count++;
00512                 while (*(token + count) != ')')
00513                   {
00514                     if (!is_digit_char (*(token + count)))
00515                      {
00516                        as_bad ("Invalid displacement in indirect reference");
00517                        return NULL;
00518                      }
00519                     disp[disp_posn++] = *(token + (count++));
00520                   }
00521                 disp[disp_posn] = '\0';
00522                 disp_number = atoi (disp);
00523                 count--;
00524                 found_disp = 1;
00525               }
00526            }
00527          buffer_posn++;
00528        }
00529 
00530       ind_buffer[buffer_posn] = '\0';
00531       if (!found_ar)
00532        {
00533          as_bad ("AR register not found in indirect reference");
00534          return NULL;
00535        }
00536 
00537       ind_addr_op = (ind_addr_type *) hash_find (ind_hash, ind_buffer);
00538       if (ind_addr_op)
00539        {
00540          debug ("Found indirect reference: %s\n", ind_addr_op->syntax);
00541          if (ind_addr_op->displacement == IMPLIED_DISP)
00542            {
00543              found_disp = 1;
00544              disp_number = 1;
00545            }
00546          else if ((ind_addr_op->displacement == DISP_REQUIRED) && !found_disp)
00547            {
00548              /* Maybe an implied displacement of 1 again.  */
00549              as_bad ("required displacement wasn't given in indirect reference");
00550              return 0;
00551            }
00552        }
00553       else
00554        {
00555          as_bad ("illegal indirect reference");
00556          return NULL;
00557        }
00558 
00559       if (found_disp && (disp_number < 0 || disp_number > 255))
00560        {
00561          as_bad ("displacement must be an unsigned 8-bit number");
00562          return NULL;
00563        }
00564 
00565       current_op->indirect.mod = ind_addr_op->modfield;
00566       current_op->indirect.disp = disp_number;
00567       current_op->indirect.ARnum = ar_number;
00568       current_op->op_type = Indirect;
00569     }
00570   else
00571     {
00572       reg *regop = (reg *) hash_find (reg_hash, token);
00573 
00574       if (regop)
00575        {
00576          debug ("Found register operand: %s\n", regop->name);
00577          if (regop->regtype == REG_ARn)
00578            current_op->op_type = ARn;
00579          else if (regop->regtype == REG_Rn)
00580            current_op->op_type = Rn;
00581          else if (regop->regtype == REG_DP)
00582            current_op->op_type = DPReg;
00583          else
00584            current_op->op_type = OtherReg;
00585          current_op->reg.opcode = regop->opcode;
00586        }
00587       else
00588        {
00589          if (!is_digit_char (*token)
00590              || *(token + 1) == 'x'
00591              || strchr (token, 'h'))
00592            {
00593              char *save_input_line_pointer;
00594              segT retval;
00595 
00596              debug ("Probably a label: %s\n", token);
00597              current_op->immediate.label = malloc (strlen (token) + 1);
00598              strcpy (current_op->immediate.label, token);
00599              current_op->immediate.label[strlen (token)] = '\0';
00600              save_input_line_pointer = input_line_pointer;
00601              input_line_pointer = token;
00602 
00603              debug ("Current input_line_pointer: %s\n", input_line_pointer);
00604              retval = expression (&current_op->immediate.imm_expr);
00605              debug ("Expression type: %d\n",
00606                    current_op->immediate.imm_expr.X_op);
00607              debug ("Expression addnum: %ld\n",
00608                    (long) current_op->immediate.imm_expr.X_add_number);
00609              debug ("Segment: %p\n", retval);
00610              input_line_pointer = save_input_line_pointer;
00611 
00612              if (current_op->immediate.imm_expr.X_op == O_constant)
00613               {
00614                 current_op->immediate.s_number
00615                   = current_op->immediate.imm_expr.X_add_number;
00616                 current_op->immediate.u_number
00617                   = (unsigned int) current_op->immediate.imm_expr.X_add_number;
00618                 current_op->immediate.resolved = 1;
00619               }
00620            }
00621          else
00622            {
00623              unsigned count;
00624 
00625              debug ("Found a number or displacement\n");
00626              for (count = 0; count < strlen (token); count++)
00627               if (*(token + count) == '.')
00628                 current_op->immediate.decimal_found = 1;
00629              current_op->immediate.label = malloc (strlen (token) + 1);
00630              strcpy (current_op->immediate.label, token);
00631              current_op->immediate.label[strlen (token)] = '\0';
00632              current_op->immediate.f_number = (float) atof (token);
00633              current_op->immediate.s_number = (int) atoi (token);
00634              current_op->immediate.u_number = (unsigned int) atoi (token);
00635              current_op->immediate.resolved = 1;
00636            }
00637          current_op->op_type = Disp | Abs24 | Imm16 | Imm24;
00638          if (current_op->immediate.u_number <= 31)
00639            current_op->op_type |= IVector;
00640        }
00641     }
00642   return current_op;
00643 }
00644 
00645 struct tic30_par_insn
00646 {
00647   partemplate *tm;          /* Template of current parallel instruction.  */
00648   unsigned operands[2];            /* Number of given operands for each insn.  */
00649   /* Type of operand given in instruction.  */
00650   operand *operand_type[2][MAX_OPERANDS];
00651   int swap_operands;        /* Whether to swap operands around.  */
00652   unsigned p_field;         /* Value of p field in multiply add/sub instructions.  */
00653   unsigned opcode;          /* Final opcode.  */
00654 };
00655 
00656 struct tic30_par_insn p_insn;
00657 
00658 static int
00659 tic30_parallel_insn (char *token)
00660 {
00661   static partemplate *p_opcode;
00662   char *current_posn = token;
00663   char *token_start;
00664   char save_char;
00665 
00666   debug ("In tic30_parallel_insn with %s\n", token);
00667   memset (&p_insn, '\0', sizeof (p_insn));
00668 
00669   while (is_opcode_char (*current_posn))
00670     current_posn++;
00671   {
00672     /* Find instruction.  */
00673     save_char = *current_posn;
00674     *current_posn = '\0';
00675     p_opcode = (partemplate *) hash_find (parop_hash, token);
00676     if (p_opcode)
00677       {
00678        debug ("Found instruction %s\n", p_opcode->name);
00679        p_insn.tm = p_opcode;
00680       }
00681     else
00682       {
00683        char first_opcode[6] = {0};
00684        char second_opcode[6] = {0};
00685        unsigned int i;
00686        int current_opcode = -1;
00687        int char_ptr = 0;
00688 
00689        for (i = 0; i < strlen (token); i++)
00690          {
00691            char ch = *(token + i);
00692 
00693            if (ch == '_' && current_opcode == -1)
00694              {
00695               current_opcode = 0;
00696               continue;
00697              }
00698 
00699            if (ch == '_' && current_opcode == 0)
00700              {
00701               current_opcode = 1;
00702               char_ptr = 0;
00703               continue;
00704              }
00705 
00706            switch (current_opcode)
00707              {
00708              case 0:
00709               first_opcode[char_ptr++] = ch;
00710               break;
00711              case 1:
00712               second_opcode[char_ptr++] = ch;
00713               break;
00714              }
00715          }
00716 
00717        debug ("first_opcode = %s\n", first_opcode);
00718        debug ("second_opcode = %s\n", second_opcode);
00719        sprintf (token, "q_%s_%s", second_opcode, first_opcode);
00720        p_opcode = (partemplate *) hash_find (parop_hash, token);
00721 
00722        if (p_opcode)
00723          {
00724            debug ("Found instruction %s\n", p_opcode->name);
00725            p_insn.tm = p_opcode;
00726            p_insn.swap_operands = 1;
00727          }
00728        else
00729          return 0;
00730       }
00731     *current_posn = save_char;
00732   }
00733 
00734   {
00735     /* Find operands.  */
00736     int paren_not_balanced;
00737     int expecting_operand = 0;
00738     int found_separator = 0;
00739 
00740     do
00741       {
00742        /* Skip optional white space before operand.  */
00743        while (!is_operand_char (*current_posn)
00744               && *current_posn != END_OF_INSN)
00745          {
00746            if (!is_space_char (*current_posn)
00747               && *current_posn != PARALLEL_SEPARATOR)
00748              {
00749               as_bad ("Invalid character %s before %s operand",
00750                      output_invalid (*current_posn),
00751                      ordinal_names[insn.operands]);
00752               return 1;
00753              }
00754            if (*current_posn == PARALLEL_SEPARATOR)
00755              found_separator = 1;
00756            current_posn++;
00757          }
00758 
00759        token_start = current_posn;
00760        paren_not_balanced = 0;
00761 
00762        while (paren_not_balanced || *current_posn != ',')
00763          {
00764            if (*current_posn == END_OF_INSN)
00765              {
00766               if (paren_not_balanced)
00767                 {
00768                   as_bad ("Unbalanced parenthesis in %s operand.",
00769                          ordinal_names[insn.operands]);
00770                   return 1;
00771                 }
00772               else
00773                 break;
00774              }
00775            else if (*current_posn == PARALLEL_SEPARATOR)
00776              {
00777               while (is_space_char (*(current_posn - 1)))
00778                 current_posn--;
00779               break;
00780              }
00781            else if (!is_operand_char (*current_posn)
00782                    && !is_space_char (*current_posn))
00783              {
00784               as_bad ("Invalid character %s in %s operand",
00785                      output_invalid (*current_posn),
00786                      ordinal_names[insn.operands]);
00787               return 1;
00788              }
00789 
00790            if (*current_posn == '(')
00791              ++paren_not_balanced;
00792            if (*current_posn == ')')
00793              --paren_not_balanced;
00794            current_posn++;
00795          }
00796 
00797        if (current_posn != token_start)
00798          {
00799            /* Yes, we've read in another operand.  */
00800            p_insn.operands[found_separator]++;
00801            if (p_insn.operands[found_separator] > MAX_OPERANDS)
00802              {
00803               as_bad ("Spurious operands; (%d operands/instruction max)",
00804                      MAX_OPERANDS);
00805               return 1;
00806              }
00807 
00808            /* Now parse operand adding info to 'insn' as we go along.  */
00809            save_char = *current_posn;
00810            *current_posn = '\0';
00811            p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1] =
00812              tic30_operand (token_start);
00813            *current_posn = save_char;
00814            if (!p_insn.operand_type[found_separator][p_insn.operands[found_separator] - 1])
00815              return 1;
00816          }
00817        else
00818          {
00819            if (expecting_operand)
00820              {
00821               as_bad ("Expecting operand after ','; got nothing");
00822               return 1;
00823              }
00824            if (*current_posn == ',')
00825              {
00826               as_bad ("Expecting operand before ','; got nothing");
00827               return 1;
00828              }
00829          }
00830 
00831        /* Now *current_posn must be either ',' or END_OF_INSN.  */
00832        if (*current_posn == ',')
00833          {
00834            if (*++current_posn == END_OF_INSN)
00835              {
00836               /* Just skip it, if it's \n complain.  */
00837               as_bad ("Expecting operand after ','; got nothing");
00838               return 1;
00839              }
00840            expecting_operand = 1;
00841          }
00842       }
00843     while (*current_posn != END_OF_INSN);
00844   }
00845 
00846   if (p_insn.swap_operands)
00847     {
00848       int temp_num, i;
00849       operand *temp_op;
00850 
00851       temp_num = p_insn.operands[0];
00852       p_insn.operands[0] = p_insn.operands[1];
00853       p_insn.operands[1] = temp_num;
00854       for (i = 0; i < MAX_OPERANDS; i++)
00855        {
00856          temp_op = p_insn.operand_type[0][i];
00857          p_insn.operand_type[0][i] = p_insn.operand_type[1][i];
00858          p_insn.operand_type[1][i] = temp_op;
00859        }
00860     }
00861 
00862   if (p_insn.operands[0] != p_insn.tm->operands_1)
00863     {
00864       as_bad ("incorrect number of operands given in the first instruction");
00865       return 1;
00866     }
00867 
00868   if (p_insn.operands[1] != p_insn.tm->operands_2)
00869     {
00870       as_bad ("incorrect number of operands given in the second instruction");
00871       return 1;
00872     }
00873 
00874   debug ("Number of operands in first insn: %d\n", p_insn.operands[0]);
00875   debug ("Number of operands in second insn: %d\n", p_insn.operands[1]);
00876 
00877   {
00878     /* Now check if operands are correct.  */
00879     int count;
00880     int num_rn = 0;
00881     int num_ind = 0;
00882 
00883     for (count = 0; count < 2; count++)
00884       {
00885        unsigned int i;
00886        for (i = 0; i < p_insn.operands[count]; i++)
00887          {
00888            if ((p_insn.operand_type[count][i]->op_type &
00889                p_insn.tm->operand_types[count][i]) == 0)
00890              {
00891               as_bad ("%s instruction, operand %d doesn't match",
00892                      ordinal_names[count], i + 1);
00893               return 1;
00894              }
00895 
00896            /* Get number of R register and indirect reference contained
00897               within the first two operands of each instruction.  This is
00898               required for the multiply parallel instructions which require
00899               two R registers and two indirect references, but not in any
00900               particular place.  */
00901            if ((p_insn.operand_type[count][i]->op_type & Rn) && i < 2)
00902              num_rn++;
00903            else if ((p_insn.operand_type[count][i]->op_type & Indirect)
00904                    && i < 2)
00905              num_ind++;
00906          }
00907       }
00908 
00909     if ((p_insn.tm->operand_types[0][0] & (Indirect | Rn))
00910        == (Indirect | Rn))
00911       {
00912        /* Check for the multiply instructions.  */
00913        if (num_rn != 2)
00914          {
00915            as_bad ("incorrect format for multiply parallel instruction");
00916            return 1;
00917          }
00918 
00919        if (num_ind != 2)
00920          {
00921            /* Shouldn't get here.  */
00922            as_bad ("incorrect format for multiply parallel instruction");
00923            return 1;
00924          }
00925 
00926        if ((p_insn.operand_type[0][2]->reg.opcode != 0x00)
00927            && (p_insn.operand_type[0][2]->reg.opcode != 0x01))
00928          {
00929            as_bad ("destination for multiply can only be R0 or R1");
00930            return 1;
00931          }
00932 
00933        if ((p_insn.operand_type[1][2]->reg.opcode != 0x02)
00934            && (p_insn.operand_type[1][2]->reg.opcode != 0x03))
00935          {
00936            as_bad ("destination for add/subtract can only be R2 or R3");
00937            return 1;
00938          }
00939 
00940        /* Now determine the P field for the instruction.  */
00941        if (p_insn.operand_type[0][0]->op_type & Indirect)
00942          {
00943            if (p_insn.operand_type[0][1]->op_type & Indirect)
00944              p_insn.p_field = 0x00000000; /* Ind * Ind, Rn  +/- Rn.  */
00945            else if (p_insn.operand_type[1][0]->op_type & Indirect)
00946              p_insn.p_field = 0x01000000; /* Ind * Rn,  Ind +/- Rn.  */
00947            else
00948              p_insn.p_field = 0x03000000; /* Ind * Rn,  Rn  +/- Ind.  */
00949          }
00950        else
00951          {
00952            if (p_insn.operand_type[0][1]->op_type & Rn)
00953              p_insn.p_field = 0x02000000; /* Rn  * Rn,  Ind +/- Ind.  */
00954            else if (p_insn.operand_type[1][0]->op_type & Indirect)
00955              {
00956               operand *temp;
00957               p_insn.p_field = 0x01000000;       /* Rn  * Ind, Ind +/- Rn.  */
00958               /* Need to swap the two multiply operands around so that
00959                  everything is in its place for the opcode makeup.
00960                  ie so Ind * Rn, Ind +/- Rn.  */
00961               temp = p_insn.operand_type[0][0];
00962               p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
00963               p_insn.operand_type[0][1] = temp;
00964              }
00965            else
00966              {
00967               operand *temp;
00968               p_insn.p_field = 0x03000000;       /* Rn  * Ind, Rn  +/- Ind.  */
00969               temp = p_insn.operand_type[0][0];
00970               p_insn.operand_type[0][0] = p_insn.operand_type[0][1];
00971               p_insn.operand_type[0][1] = temp;
00972              }
00973          }
00974       }
00975   }
00976 
00977   debug ("P field: %08X\n", p_insn.p_field);
00978 
00979   /* Finalise opcode.  This is easier for parallel instructions as they have
00980      to be fully resolved, there are no memory addresses allowed, except
00981      through indirect addressing, so there are no labels to resolve.  */
00982   p_insn.opcode = p_insn.tm->base_opcode;
00983 
00984   switch (p_insn.tm->oporder)
00985     {
00986     case OO_4op1:
00987       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
00988       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
00989       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
00990       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
00991       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
00992       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
00993       break;
00994 
00995     case OO_4op2:
00996       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
00997       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
00998       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
00999       p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
01000       p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 19);
01001       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 22);
01002       if (p_insn.operand_type[1][1]->reg.opcode == p_insn.operand_type[0][1]->reg.opcode)
01003        as_warn ("loading the same register in parallel operation");
01004       break;
01005 
01006     case OO_4op3:
01007       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
01008       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
01009       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
01010       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
01011       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
01012       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 22);
01013       break;
01014 
01015     case OO_5op1:
01016       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum);
01017       p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 3);
01018       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
01019       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
01020       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
01021       p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
01022       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
01023       break;
01024 
01025     case OO_5op2:
01026       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
01027       p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
01028       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum << 8);
01029       p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 11);
01030       p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
01031       p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
01032       p_insn.opcode |= (p_insn.operand_type[0][2]->reg.opcode << 22);
01033       break;
01034 
01035     case OO_PField:
01036       p_insn.opcode |= p_insn.p_field;
01037       if (p_insn.operand_type[0][2]->reg.opcode == 0x01)
01038        p_insn.opcode |= 0x00800000;
01039       if (p_insn.operand_type[1][2]->reg.opcode == 0x03)
01040        p_insn.opcode |= 0x00400000;
01041 
01042       switch (p_insn.p_field)
01043        {
01044        case 0x00000000:
01045          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.ARnum);
01046          p_insn.opcode |= (p_insn.operand_type[0][1]->indirect.mod << 3);
01047          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
01048          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
01049          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
01050          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 19);
01051          break;
01052        case 0x01000000:
01053          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum);
01054          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 3);
01055          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
01056          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
01057          p_insn.opcode |= (p_insn.operand_type[1][1]->reg.opcode << 16);
01058          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
01059          break;
01060        case 0x02000000:
01061          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
01062          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
01063          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.ARnum << 8);
01064          p_insn.opcode |= (p_insn.operand_type[1][0]->indirect.mod << 11);
01065          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 16);
01066          p_insn.opcode |= (p_insn.operand_type[0][0]->reg.opcode << 19);
01067          break;
01068        case 0x03000000:
01069          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.ARnum);
01070          p_insn.opcode |= (p_insn.operand_type[1][1]->indirect.mod << 3);
01071          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.ARnum << 8);
01072          p_insn.opcode |= (p_insn.operand_type[0][0]->indirect.mod << 11);
01073          p_insn.opcode |= (p_insn.operand_type[1][0]->reg.opcode << 16);
01074          p_insn.opcode |= (p_insn.operand_type[0][1]->reg.opcode << 19);
01075          break;
01076        }
01077       break;
01078     }
01079 
01080   {
01081     char *p;
01082 
01083     p = frag_more (INSN_SIZE);
01084     md_number_to_chars (p, (valueT) p_insn.opcode, INSN_SIZE);
01085   }
01086 
01087   {
01088     unsigned int i, j;
01089 
01090     for (i = 0; i < 2; i++)
01091       for (j = 0; j < p_insn.operands[i]; j++)
01092        free (p_insn.operand_type[i][j]);
01093   }
01094 
01095   debug ("Final opcode: %08X\n", p_insn.opcode);
01096   debug ("\n");
01097 
01098   return 1;
01099 }
01100 
01101 /* In order to get gas to ignore any | chars at the start of a line,
01102    this function returns true if a | is found in a line.  */
01103 
01104 int
01105 tic30_unrecognized_line (int c)
01106 {
01107   debug ("In tc_unrecognized_line\n");
01108   return (c == PARALLEL_SEPARATOR);
01109 }
01110 
01111 int
01112 md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
01113                             segT segment ATTRIBUTE_UNUSED)
01114 {
01115   debug ("In md_estimate_size_before_relax()\n");
01116   return 0;
01117 }
01118 
01119 void
01120 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
01121                segT sec ATTRIBUTE_UNUSED,
01122                register fragS *fragP ATTRIBUTE_UNUSED)
01123 {
01124   debug ("In md_convert_frag()\n");
01125 }
01126 
01127 void
01128 md_apply_fix (fixS *fixP,
01129               valueT *valP,
01130               segT seg ATTRIBUTE_UNUSED)
01131 {
01132   valueT value = *valP;
01133 
01134   debug ("In md_apply_fix() with value = %ld\n", (long) value);
01135   debug ("Values in fixP\n");
01136   debug ("fx_size = %d\n", fixP->fx_size);
01137   debug ("fx_pcrel = %d\n", fixP->fx_pcrel);
01138   debug ("fx_where = %ld\n", fixP->fx_where);
01139   debug ("fx_offset = %d\n", (int) fixP->fx_offset);
01140   {
01141     char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
01142 
01143     value /= INSN_SIZE;
01144     if (fixP->fx_size == 1)
01145       /* Special fix for LDP instruction.  */
01146       value = (value & 0x00FF0000) >> 16;
01147 
01148     debug ("new value = %ld\n", (long) value);
01149     md_number_to_chars (buf, value, fixP->fx_size);
01150   }
01151 
01152   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
01153     fixP->fx_done = 1;
01154 }
01155 
01156 int
01157 md_parse_option (int c ATTRIBUTE_UNUSED,
01158                char *arg ATTRIBUTE_UNUSED)
01159 {
01160   debug ("In md_parse_option()\n");
01161   return 0;
01162 }
01163 
01164 void
01165 md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
01166 {
01167   debug ("In md_show_usage()\n");
01168 }
01169 
01170 symbolS *
01171 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
01172 {
01173   debug ("In md_undefined_symbol()\n");
01174   return (symbolS *) 0;
01175 }
01176 
01177 valueT
01178 md_section_align (segT segment, valueT size)
01179 {
01180   debug ("In md_section_align() segment = %p and size = %lu\n",
01181         segment, (unsigned long) size);
01182   size = (size + 3) / 4;
01183   size *= 4;
01184   debug ("New size value = %lu\n", (unsigned long) size);
01185   return size;
01186 }
01187 
01188 long
01189 md_pcrel_from (fixS *fixP)
01190 {
01191   int offset;
01192 
01193   debug ("In md_pcrel_from()\n");
01194   debug ("fx_where = %ld\n", fixP->fx_where);
01195   debug ("fx_size = %d\n", fixP->fx_size);
01196   /* Find the opcode that represents the current instruction in the
01197      fr_literal storage area, and check bit 21.  Bit 21 contains whether the
01198      current instruction is a delayed one or not, and then set the offset
01199      value appropriately.  */
01200   if (fixP->fx_frag->fr_literal[fixP->fx_where - fixP->fx_size + 1] & 0x20)
01201     offset = 3;
01202   else
01203     offset = 1;
01204   debug ("offset = %d\n", offset);
01205   /* PC Relative instructions have a format:
01206      displacement = Label - (PC + offset)
01207      This function returns PC + offset where:
01208      fx_where - fx_size = PC
01209      INSN_SIZE * offset = offset number of instructions.  */
01210   return fixP->fx_where - fixP->fx_size + (INSN_SIZE * offset);
01211 }
01212 
01213 char *
01214 md_atof (int what_statement_type,
01215         char *literalP,
01216         int *sizeP)
01217 {
01218   int prec;
01219   char *token;
01220   char keepval;
01221   unsigned long value;
01222   float float_value;
01223 
01224   debug ("In md_atof()\n");
01225   debug ("precision = %c\n", what_statement_type);
01226   debug ("literal = %s\n", literalP);
01227   debug ("line = ");
01228   token = input_line_pointer;
01229   while (!is_end_of_line[(unsigned char) *input_line_pointer]
01230         && (*input_line_pointer != ','))
01231     {
01232       debug ("%c", *input_line_pointer);
01233       input_line_pointer++;
01234     }
01235 
01236   keepval = *input_line_pointer;
01237   *input_line_pointer = '\0';
01238   debug ("\n");
01239   float_value = (float) atof (token);
01240   *input_line_pointer = keepval;
01241   debug ("float_value = %f\n", float_value);
01242 
01243   switch (what_statement_type)
01244     {
01245     case 'f':
01246     case 'F':
01247     case 's':
01248     case 'S':
01249       prec = 2;
01250       break;
01251 
01252     case 'd':
01253     case 'D':
01254     case 'r':
01255     case 'R':
01256       prec = 4;
01257       break;
01258 
01259     default:
01260       *sizeP = 0;
01261       return "Bad call to MD_ATOF()";
01262     }
01263 
01264   if (float_value == 0.0)
01265     value = (prec == 2) ? 0x00008000L : 0x80000000L;
01266   else
01267     {
01268       unsigned long exp, sign, mant, tmsfloat;
01269       union
01270       {
01271        float f;
01272        long  l;
01273       }
01274       converter;
01275 
01276       converter.f = float_value;
01277       tmsfloat = converter.l;
01278       sign = tmsfloat & 0x80000000;
01279       mant = tmsfloat & 0x007FFFFF;
01280       exp = tmsfloat & 0x7F800000;
01281       exp <<= 1;
01282       if (exp == 0xFF000000)
01283        {
01284          if (mant == 0)
01285            value = 0x7F7FFFFF;
01286          else if (sign == 0)
01287            value = 0x7F7FFFFF;
01288          else
01289            value = 0x7F800000;
01290        }
01291       else
01292        {
01293          exp -= 0x7F000000;
01294          if (sign)
01295            {
01296              mant = mant & 0x007FFFFF;
01297              mant = -mant;
01298              mant = mant & 0x00FFFFFF;
01299              if (mant == 0)
01300               {
01301                 mant |= 0x00800000;
01302                 exp = (long) exp - 0x01000000;
01303               }
01304            }
01305          tmsfloat = exp | mant;
01306          value = tmsfloat;
01307        }
01308       if (prec == 2)
01309        {
01310          long exp, mant;
01311 
01312          if (tmsfloat == 0x80000000)
01313            value = 0x8000;
01314          else
01315            {
01316              value = 0;
01317              exp = (tmsfloat & 0xFF000000);
01318              exp >>= 24;
01319              mant = tmsfloat & 0x007FFFFF;
01320              if (tmsfloat & 0x00800000)
01321               {
01322                 mant |= 0xFF000000;
01323                 mant += 0x00000800;
01324                 mant >>= 12;
01325                 mant |= 0x00000800;
01326                 mant &= 0x0FFF;
01327                 if (exp > 7)
01328                   value = 0x7800;
01329               }
01330              else
01331               {
01332                 mant |= 0x00800000;
01333                 mant += 0x00000800;
01334                 exp += (mant >> 24);
01335                 mant >>= 12;
01336                 mant &= 0x07FF;
01337                 if (exp > 7)
01338                   value = 0x77FF;
01339               }
01340              if (exp < -8)
01341               value = 0x8000;
01342              if (value == 0)
01343               {
01344                 mant = (exp << 12) | mant;
01345                 value = mant & 0xFFFF;
01346               }
01347            }
01348        }
01349     }
01350   md_number_to_chars (literalP, value, prec);
01351   *sizeP = prec;
01352   return 0;
01353 }
01354 
01355 void
01356 md_number_to_chars (char *buf, valueT val, int n)
01357 {
01358   debug ("In md_number_to_chars()\n");
01359   number_to_chars_bigendian (buf, val, n);
01360 }
01361 
01362 #define F(SZ,PCREL)         (((SZ) << 1) + (PCREL))
01363 #define MAP(SZ,PCREL,TYPE)  case F(SZ,PCREL): code = (TYPE); break
01364 
01365 arelent *
01366 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
01367 {
01368   arelent *rel;
01369   bfd_reloc_code_real_type code = 0;
01370 
01371   debug ("In tc_gen_reloc()\n");
01372   debug ("fixP.size = %d\n", fixP->fx_size);
01373   debug ("fixP.pcrel = %d\n", fixP->fx_pcrel);
01374   debug ("addsy.name = %s\n", S_GET_NAME (fixP->fx_addsy));
01375 
01376   switch (F (fixP->fx_size, fixP->fx_pcrel))
01377     {
01378       MAP (1, 0, BFD_RELOC_TIC30_LDP);
01379       MAP (2, 0, BFD_RELOC_16);
01380       MAP (3, 0, BFD_RELOC_24);
01381       MAP (2, 1, BFD_RELOC_16_PCREL);
01382       MAP (4, 0, BFD_RELOC_32);
01383     default:
01384       as_bad ("Can not do %d byte %srelocation", fixP->fx_size,
01385              fixP->fx_pcrel ? "pc-relative " : "");
01386     }
01387 #undef MAP
01388 #undef F
01389 
01390   rel = xmalloc (sizeof (* rel));
01391   assert (rel != 0);
01392   rel->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
01393   *rel->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
01394   rel->address = fixP->fx_frag->fr_address + fixP->fx_where;
01395   rel->addend = 0;
01396   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
01397   if (!rel->howto)
01398     {
01399       const char *name;
01400 
01401       name = S_GET_NAME (fixP->fx_addsy);
01402       if (name == NULL)
01403        name = "<unknown>";
01404       as_fatal ("Cannot generate relocation type for symbol %s, code %s",
01405               name, bfd_get_reloc_code_name (code));
01406     }
01407   return rel;
01408 }
01409 
01410 void
01411 md_operand (expressionS *expressionP ATTRIBUTE_UNUSED)
01412 {
01413   debug ("In md_operand()\n");
01414 }
01415 
01416 void
01417 md_assemble (char *line)
01418 {
01419   template *opcode;
01420   char *current_posn;
01421   char *token_start;
01422   char save_char;
01423   unsigned int count;
01424 
01425   debug ("In md_assemble() with argument %s\n", line);
01426   memset (&insn, '\0', sizeof (insn));
01427   if (found_parallel_insn)
01428     {
01429       debug ("Line is second part of parallel instruction\n\n");
01430       found_parallel_insn = 0;
01431       return;
01432     }
01433   if ((current_posn =
01434        tic30_find_parallel_insn (line, input_line_pointer + 1)) == NULL)
01435     current_posn = line;
01436   else
01437     found_parallel_insn = 1;
01438 
01439   while (is_space_char (*current_posn))
01440     current_posn++;
01441 
01442   token_start = current_posn;
01443 
01444   if (!is_opcode_char (*current_posn))
01445     {
01446       as_bad ("Invalid character %s in opcode",
01447              output_invalid (*current_posn));
01448       return;
01449     }
01450   /* Check if instruction is a parallel instruction
01451      by seeing if the first character is a q.  */
01452   if (*token_start == 'q')
01453     {
01454       if (tic30_parallel_insn (token_start))
01455        {
01456          if (found_parallel_insn)
01457            free (token_start);
01458          return;
01459        }
01460     }
01461   while (is_opcode_char (*current_posn))
01462     current_posn++;
01463   {
01464     /* Find instruction.  */
01465     save_char = *current_posn;
01466     *current_posn = '\0';
01467     opcode = (template *) hash_find (op_hash, token_start);
01468     if (opcode)
01469       {
01470        debug ("Found instruction %s\n", opcode->name);
01471        insn.tm = opcode;
01472       }
01473     else
01474       {
01475        debug ("Didn't find insn\n");
01476        as_bad ("Unknown TMS320C30 instruction: %s", token_start);
01477        return;
01478       }
01479     *current_posn = save_char;
01480   }
01481 
01482   if (*current_posn != END_OF_INSN)
01483     {
01484       /* Find operands.  */
01485       int paren_not_balanced;
01486       int expecting_operand = 0;
01487       int this_operand;
01488       do
01489        {
01490          /* Skip optional white space before operand.  */
01491          while (!is_operand_char (*current_posn)
01492                && *current_posn != END_OF_INSN)
01493            {
01494              if (!is_space_char (*current_posn))
01495               {
01496                 as_bad ("Invalid character %s before %s operand",
01497                        output_invalid (*current_posn),
01498                        ordinal_names[insn.operands]);
01499                 return;
01500               }
01501              current_posn++;
01502            }
01503          token_start = current_posn;
01504          paren_not_balanced = 0;
01505          while (paren_not_balanced || *current_posn != ',')
01506            {
01507              if (*current_posn == END_OF_INSN)
01508               {
01509                 if (paren_not_balanced)
01510                   {
01511                     as_bad ("Unbalanced parenthesis in %s operand.",
01512                            ordinal_names[insn.operands]);
01513                     return;
01514                   }
01515                 else
01516                   break;
01517               }
01518              else if (!is_operand_char (*current_posn)
01519                      && !is_space_char (*current_posn))
01520               {
01521                 as_bad ("Invalid character %s in %s operand",
01522                        output_invalid (*current_posn),
01523                        ordinal_names[insn.operands]);
01524                 return;
01525               }
01526              if (*current_posn == '(')
01527               ++paren_not_balanced;
01528              if (*current_posn == ')')
01529               --paren_not_balanced;
01530              current_posn++;
01531            }
01532          if (current_posn != token_start)
01533            {
01534              /* Yes, we've read in another operand.  */
01535              this_operand = insn.operands++;
01536              if (insn.operands > MAX_OPERANDS)
01537               {
01538                 as_bad ("Spurious operands; (%d operands/instruction max)",
01539                        MAX_OPERANDS);
01540                 return;
01541               }
01542 
01543              /* Now parse operand adding info to 'insn' as we go along.  */
01544              save_char = *current_posn;
01545              *current_posn = '\0';
01546              insn.operand_type[this_operand] = tic30_operand (token_start);
01547              *current_posn = save_char;
01548              if (insn.operand_type[this_operand] == NULL)
01549               return;
01550            }
01551          else
01552            {
01553              if (expecting_operand)
01554               {
01555                 as_bad ("Expecting operand after ','; got nothing");
01556                 return;
01557               }
01558              if (*current_posn == ',')
01559               {
01560                 as_bad ("Expecting operand before ','; got nothing");
01561                 return;
01562               }
01563            }
01564 
01565          /* Now *current_posn must be either ',' or END_OF_INSN.  */
01566          if (*current_posn == ',')
01567            {
01568              if (*++current_posn == END_OF_INSN)
01569               {
01570                 /* Just skip it, if it's \n complain.  */
01571                 as_bad ("Expecting operand after ','; got nothing");
01572                 return;
01573               }
01574              expecting_operand = 1;
01575            }
01576        }
01577       while (*current_posn != END_OF_INSN);
01578     }
01579 
01580   debug ("Number of operands found: %d\n", insn.operands);
01581 
01582   /* Check that number of operands is correct.  */
01583   if (insn.operands != insn.tm->operands)
01584     {
01585       unsigned int i;
01586       unsigned int numops = insn.tm->operands;
01587 
01588       /* If operands are not the same, then see if any of the operands are
01589         not required.  Then recheck with number of given operands.  If they
01590         are still not the same, then give an error, otherwise carry on.  */
01591       for (i = 0; i < insn.tm->operands; i++)
01592        if (insn.tm->operand_types[i] & NotReq)
01593          numops--;
01594       if (insn.operands != numops)
01595        {
01596          as_bad ("Incorrect number of operands given");
01597          return;
01598        }
01599     }
01600   insn.addressing_mode = AM_NotReq;
01601   for (count = 0; count < insn.operands; count++)
01602     {
01603       if (insn.operand_type[count]->op_type & insn.tm->operand_types[count])
01604        {
01605          debug ("Operand %d matches\n", count + 1);
01606          /* If instruction has two operands and has an AddressMode
01607             modifier then set addressing mode type for instruction.  */
01608          if (insn.tm->opcode_modifier == AddressMode)
01609            {
01610              int addr_insn = 0;
01611              /* Store instruction uses the second
01612                operand for the address mode.  */
01613              if ((insn.tm->operand_types[1] & (Indirect | Direct))
01614                 == (Indirect | Direct))
01615               addr_insn = 1;
01616 
01617              if (insn.operand_type[addr_insn]->op_type & (AllReg))
01618               insn.addressing_mode = AM_Register;
01619              else if (insn.operand_type[addr_insn]->op_type & Direct)
01620               insn.addressing_mode = AM_Direct;
01621              else if (insn.operand_type[addr_insn]->op_type & Indirect)
01622               insn.addressing_mode = AM_Indirect;
01623              else
01624               insn.addressing_mode = AM_Immediate;
01625            }
01626        }
01627       else
01628        {
01629          as_bad ("The %s operand doesn't match", ordinal_names[count]);
01630          return;
01631        }
01632     }
01633 
01634   /* Now set the addressing mode for 3 operand instructions.  */
01635   if ((insn.tm->operand_types[0] & op3T1)
01636       && (insn.tm->operand_types[1] & op3T2))
01637     {
01638       /* Set the addressing mode to the values used for 2 operand
01639         instructions in the  G addressing field of the opcode.  */
01640       char *p;
01641       switch (insn.operand_type[0]->op_type)
01642        {
01643        case Rn:
01644        case ARn:
01645        case DPReg:
01646        case OtherReg:
01647          if (insn.operand_type[1]->op_type & (AllReg))
01648            insn.addressing_mode = AM_Register;
01649          else if (insn.operand_type[1]->op_type & Indirect)
01650            insn.addressing_mode = AM_Direct;
01651          else
01652            {
01653              /* Shouldn't make it to this stage.  */
01654              as_bad ("Incompatible first and second operands in instruction");
01655              return;
01656            }
01657          break;
01658        case Indirect:
01659          if (insn.operand_type[1]->op_type & (AllReg))
01660            insn.addressing_mode = AM_Indirect;
01661          else if (insn.operand_type[1]->op_type & Indirect)
01662            insn.addressing_mode = AM_Immediate;
01663          else
01664            {
01665              /* Shouldn't make it to this stage.  */
01666              as_bad ("Incompatible first and second operands in instruction");
01667              return;
01668            }
01669          break;
01670        }
01671       /* Now make up the opcode for the 3 operand instructions.  As in
01672         parallel instructions, there will be no unresolved values, so they
01673         can be fully formed and added to the frag table.  */
01674       insn.opcode = insn.tm->base_opcode;
01675       if (insn.operand_type[0]->op_type & Indirect)
01676        {
01677          insn.opcode |= (insn.operand_type[0]->indirect.ARnum);
01678          insn.opcode |= (insn.operand_type[0]->indirect.mod << 3);
01679        }
01680       else
01681        insn.opcode |= (insn.operand_type[0]->reg.opcode);
01682 
01683       if (insn.operand_type[1]->op_type & Indirect)
01684        {
01685          insn.opcode |= (insn.operand_type[1]->indirect.ARnum << 8);
01686          insn.opcode |= (insn.operand_type[1]->indirect.mod << 11);
01687        }
01688       else
01689        insn.opcode |= (insn.operand_type[1]->reg.opcode << 8);
01690 
01691       if (insn.operands == 3)
01692        insn.opcode |= (insn.operand_type[2]->reg.opcode << 16);
01693 
01694       insn.opcode |= insn.addressing_mode;
01695       p = frag_more (INSN_SIZE);
01696       md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01697     }
01698   else
01699     {
01700       /* Not a three operand instruction.  */
01701       char *p;
01702       int am_insn = -1;
01703       insn.opcode = insn.tm->base_opcode;
01704       /* Create frag for instruction - all instructions are 4 bytes long.  */
01705       p = frag_more (INSN_SIZE);
01706       if ((insn.operands > 0) && (insn.tm->opcode_modifier == AddressMode))
01707        {
01708          insn.opcode |= insn.addressing_mode;
01709          if (insn.addressing_mode == AM_Indirect)
01710            {
01711              /* Determine which operand gives the addressing mode.  */
01712              if (insn.operand_type[0]->op_type & Indirect)
01713               am_insn = 0;
01714              if ((insn.operands > 1)
01715                 && (insn.operand_type[1]->op_type & Indirect))
01716               am_insn = 1;
01717              insn.opcode |= (insn.operand_type[am_insn]->indirect.disp);
01718              insn.opcode |= (insn.operand_type[am_insn]->indirect.ARnum << 8);
01719              insn.opcode |= (insn.operand_type[am_insn]->indirect.mod << 11);
01720              if (insn.operands > 1)
01721               insn.opcode |= (insn.operand_type[!am_insn]->reg.opcode << 16);
01722              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01723            }
01724          else if (insn.addressing_mode == AM_Register)
01725            {
01726              insn.opcode |= (insn.operand_type[0]->reg.opcode);
01727              if (insn.operands > 1)
01728               insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
01729              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01730            }
01731          else if (insn.addressing_mode == AM_Direct)
01732            {
01733              if (insn.operand_type[0]->op_type & Direct)
01734               am_insn = 0;
01735              if ((insn.operands > 1)
01736                 && (insn.operand_type[1]->op_type & Direct))
01737               am_insn = 1;
01738              if (insn.operands > 1)
01739               insn.opcode |=
01740                 (insn.operand_type[! am_insn]->reg.opcode << 16);
01741              if (insn.operand_type[am_insn]->direct.resolved == 1)
01742               {
01743                 /* Resolved values can be placed straight
01744                    into instruction word, and output.  */
01745                 insn.opcode |=
01746                   (insn.operand_type[am_insn]->direct.address & 0x0000FFFF);
01747                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01748               }
01749              else
01750               {
01751                 /* Unresolved direct addressing mode instruction.  */
01752                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01753                 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
01754                             & insn.operand_type[am_insn]->direct.direct_expr,
01755                             0, 0);
01756               }
01757            }
01758          else if (insn.addressing_mode == AM_Immediate)
01759            {
01760              if (insn.operand_type[0]->immediate.resolved == 1)
01761               {
01762                 char *keeploc;
01763                 int size;
01764 
01765                 if (insn.operands > 1)
01766                   insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
01767 
01768                 switch (insn.tm->imm_arg_type)
01769                   {
01770                   case Imm_Float:
01771                     debug ("Floating point first operand\n");
01772                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01773 
01774                     keeploc = input_line_pointer;
01775                     input_line_pointer =
01776                      insn.operand_type[0]->immediate.label;
01777 
01778                     if (md_atof ('f', p + 2, & size) != 0)
01779                      {
01780                        as_bad ("invalid short form floating point immediate operand");
01781                        return;
01782                      }
01783 
01784                     input_line_pointer = keeploc;
01785                     break;
01786 
01787                   case Imm_UInt:
01788                     debug ("Unsigned int first operand\n");
01789                     if (insn.operand_type[0]->immediate.decimal_found)
01790                      as_warn ("rounding down first operand float to unsigned int");
01791                     if (insn.operand_type[0]->immediate.u_number > 0xFFFF)
01792                      as_warn ("only lower 16-bits of first operand are used");
01793                     insn.opcode |=
01794                      (insn.operand_type[0]->immediate.u_number & 0x0000FFFFL);
01795                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01796                     break;
01797 
01798                   case Imm_SInt:
01799                     debug ("Int first operand\n");
01800 
01801                     if (insn.operand_type[0]->immediate.decimal_found)
01802                      as_warn ("rounding down first operand float to signed int");
01803 
01804                     if (insn.operand_type[0]->immediate.s_number < -32768 ||
01805                        insn.operand_type[0]->immediate.s_number > 32767)
01806                      {
01807                        as_bad ("first operand is too large for 16-bit signed int");
01808                        return;
01809                      }
01810                     insn.opcode |=
01811                      (insn.operand_type[0]->immediate.s_number & 0x0000FFFFL);
01812                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01813                     break;
01814                   }
01815               }
01816              else
01817               {
01818                 /* Unresolved immediate label.  */
01819                 if (insn.operands > 1)
01820                   insn.opcode |= (insn.operand_type[1]->reg.opcode << 16);
01821                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01822                 fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal), 2,
01823                             & insn.operand_type[0]->immediate.imm_expr,
01824                             0, 0);
01825               }
01826            }
01827        }
01828       else if (insn.tm->opcode_modifier == PCRel)
01829        {
01830          /* Conditional Branch and Call instructions.  */
01831          if ((insn.tm->operand_types[0] & (AllReg | Disp))
01832              == (AllReg | Disp))
01833            {
01834              if (insn.operand_type[0]->op_type & (AllReg))
01835               {
01836                 insn.opcode |= (insn.operand_type[0]->reg.opcode);
01837                 insn.opcode |= PC_Register;
01838                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01839               }
01840              else
01841               {
01842                 insn.opcode |= PC_Relative;
01843                 if (insn.operand_type[0]->immediate.resolved == 1)
01844                   {
01845                     insn.opcode |=
01846                      (insn.operand_type[0]->immediate.s_number & 0x0000FFFF);
01847                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01848                   }
01849                 else
01850                   {
01851                     md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01852                     fix_new_exp (frag_now, p + 2 - (frag_now->fr_literal),
01853                                2, & insn.operand_type[0]->immediate.imm_expr,
01854                                1, 0);
01855                   }
01856               }
01857            }
01858          else if ((insn.tm->operand_types[0] & ARn) == ARn)
01859            {
01860              /* Decrement and Branch instructions.  */
01861              insn.opcode |= ((insn.operand_type[0]->reg.opcode - 0x08) << 22);
01862              if (insn.operand_type[1]->op_type & (AllReg))
01863               {
01864                 insn.opcode |= (insn.operand_type[1]->reg.opcode);
01865                 insn.opcode |= PC_Register;
01866                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01867               }
01868              else if (insn.operand_type[1]->immediate.resolved == 1)
01869               {
01870                 if (insn.operand_type[0]->immediate.decimal_found)
01871                   {
01872                     as_bad ("first operand is floating point");
01873                     return;
01874                   }
01875                 if (insn.operand_type[0]->immediate.s_number < -32768 ||
01876                     insn.operand_type[0]->immediate.s_number > 32767)
01877                   {
01878                     as_bad ("first operand is too large for 16-bit signed int");
01879                     return;
01880                   }
01881                 insn.opcode |= (insn.operand_type[1]->immediate.s_number);
01882                 insn.opcode |= PC_Relative;
01883                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01884               }
01885              else
01886               {
01887                 insn.opcode |= PC_Relative;
01888                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01889                 fix_new_exp (frag_now, p + 2 - frag_now->fr_literal, 2,
01890                             & insn.operand_type[1]->immediate.imm_expr,
01891                             1, 0);
01892               }
01893            }
01894        }
01895       else if (insn.tm->operand_types[0] == IVector)
01896        {
01897          /* Trap instructions.  */
01898          if (insn.operand_type[0]->op_type & IVector)
01899            insn.opcode |= (insn.operand_type[0]->immediate.u_number);
01900          else
01901            {
01902              /* Shouldn't get here.  */
01903              as_bad ("interrupt vector for trap instruction out of range");
01904              return;
01905            }
01906          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01907        }
01908       else if (insn.tm->opcode_modifier == StackOp
01909               || insn.tm->opcode_modifier == Rotate)
01910        {
01911          /* Push, Pop and Rotate instructions.  */
01912          insn.opcode |= (insn.operand_type[0]->reg.opcode << 16);
01913          md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01914        }
01915       else if ((insn.tm->operand_types[0] & (Abs24 | Direct))
01916               == (Abs24 | Direct))
01917        {
01918          /* LDP Instruction needs to be tested
01919             for before the next section.  */
01920          if (insn.operand_type[0]->op_type & Direct)
01921            {
01922              if (insn.operand_type[0]->direct.resolved == 1)
01923               {
01924                 /* Direct addressing uses lower 8 bits of direct address.  */
01925                 insn.opcode |=
01926                   (insn.operand_type[0]->direct.address & 0x00FF0000) >> 16;
01927                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01928               }
01929              else
01930               {
01931                 fixS *fix;
01932 
01933                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01934                 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
01935                                  1, &insn.operand_type[0]->direct.direct_expr, 0, 0);
01936                 /* Ensure that the assembler doesn't complain
01937                    about fitting a 24-bit address into 8 bits.  */
01938                 fix->fx_no_overflow = 1;
01939               }
01940            }
01941          else
01942            {
01943              if (insn.operand_type[0]->immediate.resolved == 1)
01944               {
01945                 /* Immediate addressing uses upper 8 bits of address.  */
01946                 if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
01947                   {
01948                     as_bad ("LDP instruction needs a 24-bit operand");
01949                     return;
01950                   }
01951                 insn.opcode |=
01952                   ((insn.operand_type[0]->immediate.u_number & 0x00FF0000) >> 16);
01953                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01954               }
01955              else
01956               {
01957                 fixS *fix;
01958                 md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01959                 fix = fix_new_exp (frag_now, p + 3 - (frag_now->fr_literal),
01960                                  1, &insn.operand_type[0]->immediate.imm_expr,
01961                                  0, 0);
01962                 fix->fx_no_overflow = 1;
01963               }
01964            }
01965        }
01966       else if (insn.tm->operand_types[0] & (Imm24))
01967        {
01968          /* Unconditional Branch and Call instructions.  */
01969          if (insn.operand_type[0]->immediate.resolved == 1)
01970            {
01971              if (insn.operand_type[0]->immediate.u_number > 0x00FFFFFF)
01972               as_warn ("first operand is too large for a 24-bit displacement");
01973              insn.opcode |=
01974               (insn.operand_type[0]->immediate.u_number & 0x00FFFFFF);
01975              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01976            }
01977          else
01978            {
01979              md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01980              fix_new_exp (frag_now, p + 1 - (frag_now->fr_literal), 3,
01981                         & insn.operand_type[0]->immediate.imm_expr, 0, 0);
01982            }
01983        }
01984       else if (insn.tm->operand_types[0] & NotReq)
01985        /* Check for NOP instruction without arguments.  */
01986        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01987 
01988       else if (insn.tm->operands == 0)
01989        /* Check for instructions without operands.  */
01990        md_number_to_chars (p, (valueT) insn.opcode, INSN_SIZE);
01991     }
01992   debug ("Addressing mode: %08X\n", insn.addressing_mode);
01993   {
01994     unsigned int i;
01995 
01996     for (i = 0; i < insn.operands; i++)
01997       {
01998        if (insn.operand_type[i]->immediate.label)
01999          free (insn.operand_type[i]->immediate.label);
02000        free (insn.operand_type[i]);
02001       }
02002   }
02003   debug ("Final opcode: %08X\n", insn.opcode);
02004   debug ("\n");
02005 }
02006