Correct opcode generated for RX indirect MOVs without an offset.
[deliverable/binutils-gdb.git] / gas / config / tc-tic54x.c
index 7fd970652751557bbd2c42fd061112fd68061804..1ff204be283c9f90546ba2eb0053ad2b18df5f0d 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-tic54x.c -- Assembly code for the Texas Instruments TMS320C54X
-   Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009  Free Software Foundation, Inc.
+   Copyright (C) 1999-2016 Free Software Foundation, Inc.
    Contributed by Timothy Wall (twall@cygnus.com)
 
    This file is part of GAS, the GNU Assembler.
@@ -45,8 +44,8 @@
    COFF1 limits section names to 8 characters.
    Some of the default behavior changed from COFF1 to COFF2.  */
 
-#include <limits.h>
 #include "as.h"
+#include <limits.h>
 #include "safe-ctype.h"
 #include "sb.h"
 #include "macro.h"
@@ -81,7 +80,7 @@ static struct stag
 
 typedef struct _tic54x_insn
 {
-  const template *tm;          /* Opcode template.  */
+  const insn_template *tm;     /* Opcode template.  */
 
   char mnemonic[MAX_LINE];     /* Opcode name/mnemonic.  */
   char parmnemonic[MAX_LINE];   /* 2nd mnemonic of parallel insn.  */
@@ -243,11 +242,11 @@ md_show_usage (FILE *stream)
 static void
 tic54x_emit_char (char c)
 {
-  expressionS exp;
+  expressionS expn;
 
-  exp.X_op = O_constant;
-  exp.X_add_number = c;
-  emit_expr (&exp, 2);
+  expn.X_op = O_constant;
+  expn.X_add_number = c;
+  emit_expr (&expn, 2);
 }
 
 /* Walk backwards in the frag chain.  */
@@ -298,14 +297,14 @@ frag_bit_offset (fragS *frag, segT seg)
    expression.  */
 
 static char *
-parse_expression (char *str, expressionS *exp)
+parse_expression (char *str, expressionS *expn)
 {
   char *s;
   char *tmp;
 
   tmp = input_line_pointer;    /* Save line pointer.  */
   input_line_pointer = str;
-  expression (exp);
+  expression (expn);
   s = input_line_pointer;
   input_line_pointer = tmp;    /* Restore line pointer.  */
   return s;                    /* Return pointer to where parsing stopped.  */
@@ -352,8 +351,8 @@ tic54x_asg (int x ATTRIBUTE_UNUSED)
       return;
     }
 
-  name = ++input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
+  ++input_line_pointer;
+  c = get_symbol_name (&name); /* Get terminator.  */
   if (!ISALPHA (*name))
     {
       as_bad (_("symbols assigned with .asg must begin with a letter"));
@@ -368,7 +367,7 @@ tic54x_asg (int x ATTRIBUTE_UNUSED)
   strcpy (tmp, name);
   name = tmp;
   subsym_create_or_replace (name, str);
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
   demand_empty_rest_of_line ();
 }
 
@@ -412,11 +411,10 @@ tic54x_eval (int x ATTRIBUTE_UNUSED)
       ignore_rest_of_line ();
       return;
     }
-  name = input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
+  c = get_symbol_name (&name); /* Get terminator.  */
   tmp = xmalloc (strlen (name) + 1);
   name = strcpy (tmp, name);
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
 
   if (!ISALPHA (*name))
     {
@@ -472,8 +470,9 @@ tic54x_bss (int x ATTRIBUTE_UNUSED)
   current_seg = now_seg;       /* Save current seg.  */
   current_subseg = now_subseg; /* Save current subseg.  */
 
-  name = input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
+  c = get_symbol_name (&name); /* Get terminator.  */
+  if (c == '"')
+    c = * ++ input_line_pointer;
   if (c != ',')
     {
       as_bad (_(".bss size argument missing\n"));
@@ -783,8 +782,8 @@ tic54x_endstruct (int is_union)
 static void
 tic54x_tag (int ignore ATTRIBUTE_UNUSED)
 {
-  char *name = input_line_pointer;
-  int c = get_symbol_end ();
+  char *name;
+  int c = get_symbol_name (&name);
   struct stag *stag = (struct stag *) hash_find (stag_hash, name);
 
   if (!stag)
@@ -830,7 +829,7 @@ tic54x_tag (int ignore ATTRIBUTE_UNUSED)
   if (current_stag != NULL && !current_stag->is_union)
     abs_section_offset += stag->size;
 
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
   demand_empty_rest_of_line ();
   line_label = NULL;
 }
@@ -1018,12 +1017,12 @@ tic54x_cons (int type)
        }
       else
        {
-         expressionS exp;
+         expressionS expn;
 
-         input_line_pointer = parse_expression (input_line_pointer, &exp);
-         if (exp.X_op == O_constant)
+         input_line_pointer = parse_expression (input_line_pointer, &expn);
+         if (expn.X_op == O_constant)
            {
-             offsetT value = exp.X_add_number;
+             offsetT value = expn.X_add_number;
              /* Truncate overflows.  */
              switch (octets)
                {
@@ -1039,7 +1038,7 @@ tic54x_cons (int type)
                  break;
                }
            }
-         if (exp.X_op != O_constant && octets < 2)
+         if (expn.X_op != O_constant && octets < 2)
            {
              /* Disallow .byte with a non constant expression that will
                 require relocation.  */
@@ -1048,7 +1047,7 @@ tic54x_cons (int type)
              return;
            }
 
-         if (exp.X_op != O_constant
+         if (expn.X_op != O_constant
              && amode == c_mode
              && octets == 4)
            {
@@ -1059,14 +1058,14 @@ tic54x_cons (int type)
                 totally ignored in the latest tools).  */
              amode = far_mode;
              emitting_long = 1;
-             emit_expr (&exp, 4);
+             emit_expr (&expn, 4);
              emitting_long = 0;
              amode = c_mode;
            }
          else
            {
              emitting_long = octets == 4;
-             emit_expr (&exp, (octets == 1) ? 2 : octets);
+             emit_expr (&expn, (octets == 1) ? 2 : octets);
              emitting_long = 0;
            }
        }
@@ -1110,11 +1109,10 @@ tic54x_global (int type)
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       symbolP = symbol_find_or_make (name);
+      c = restore_line_pointer (c);
 
-      *input_line_pointer = c;
       S_SET_STORAGE_CLASS (symbolP, C_EXT);
       if (c == ',')
        {
@@ -1185,13 +1183,14 @@ tic54x_sect (int arg)
       else
        {
          int c;
-         name = input_line_pointer;
-         c = get_symbol_end ();
+
+         c = get_symbol_name (&name);
           len = strlen(name);
          name = strcpy (xmalloc (len + 10), name);
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
          demand_empty_rest_of_line ();
        }
+
       /* Make sure all named initialized sections flagged properly.  If we
          encounter instructions, we'll flag it with SEC_CODE as well.  */
       strcat (name, ",\"w\"\n");
@@ -1222,7 +1221,7 @@ tic54x_sect (int arg)
 static void
 tic54x_space (int arg)
 {
-  expressionS exp;
+  expressionS expn;
   char *p = 0;
   int octets = 0;
   long words;
@@ -1238,22 +1237,21 @@ tic54x_space (int arg)
 #endif
 
   /* Read the bit count.  */
-  expression (&exp);
+  expression (&expn);
 
   /* Some expressions are unresolvable until later in the assembly pass;
      postpone until relaxation/fixup.  we also have to postpone if a previous
      partial allocation has not been completed yet.  */
-  if (exp.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
+  if (expn.X_op != O_constant || frag_bit_offset (frag_now, now_seg) == -1)
     {
       struct bit_info *bi = xmalloc (sizeof (struct bit_info));
-      char *p;
 
       bi->seg = now_seg;
       bi->type = bes;
       bi->sym = label;
       p = frag_var (rs_machine_dependent,
                    65536 * 2, 1, (relax_substateT) 0,
-                   make_expr_symbol (&exp), (offsetT) 0,
+                   make_expr_symbol (&expn), (offsetT) 0,
                    (char *) bi);
       if (p)
        *p = 0;
@@ -1268,7 +1266,7 @@ tic54x_space (int arg)
     {
       int spare_bits = bits_per_byte - bit_offset;
 
-      if (spare_bits >= exp.X_add_number)
+      if (spare_bits >= expn.X_add_number)
        {
          /* Don't have to do anything; sufficient bits have already been
             allocated; just point the label to the right place.  */
@@ -1278,10 +1276,10 @@ tic54x_space (int arg)
              S_SET_VALUE (label, frag_now_fix () - 1);
              label = NULL;
            }
-         frag_now->tc_frag_data += exp.X_add_number;
+         frag_now->tc_frag_data += expn.X_add_number;
          goto getout;
        }
-      exp.X_add_number -= spare_bits;
+      expn.X_add_number -= spare_bits;
       /* Set the label to point to the first word allocated, which in this
         case is the previous word, which was only partially filled.  */
       if (!bes && label != NULL)
@@ -1292,9 +1290,9 @@ tic54x_space (int arg)
        }
     }
   /* Convert bits to bytes/words and octets, rounding up.  */
-  words = ((exp.X_add_number + bits_per_byte - 1) / bits_per_byte);
+  words = ((expn.X_add_number + bits_per_byte - 1) / bits_per_byte);
   /* How many do we have left over?  */
-  bit_offset = exp.X_add_number % bits_per_byte;
+  bit_offset = expn.X_add_number % bits_per_byte;
   octets = words * OCTETS_PER_BYTE;
   if (octets < 0)
     {
@@ -1368,17 +1366,14 @@ tic54x_usect (int x ATTRIBUTE_UNUSED)
   current_seg = now_seg;       /* Save current seg.  */
   current_subseg = now_subseg; /* Save current subseg.  */
 
-  if (*input_line_pointer == '"')
-    input_line_pointer++;
-  section_name = input_line_pointer;
-  c = get_symbol_end ();       /* Get terminator.  */
-  input_line_pointer++;                /* Skip null symbol terminator.  */
+  c = get_symbol_name (&section_name); /* Get terminator.  */
   name = xmalloc (input_line_pointer - section_name + 1);
   strcpy (name, section_name);
-
-  if (*input_line_pointer == ',')
+  c = restore_line_pointer (c);
+  
+  if (c == ',')
     ++input_line_pointer;
-  else if (c != ',')
+  else
     {
       as_bad (_("Missing size argument"));
       ignore_rest_of_line ();
@@ -1571,7 +1566,6 @@ static void
 tic54x_stringer (int type)
 {
   unsigned int c;
-  char *start;
   int append_zero = type == 'S' || type == 'P';
   int packed = type == 'p' || type == 'P';
   int last_char = -1; /* Packed strings need two bytes at a time to encode.  */
@@ -1601,7 +1595,6 @@ tic54x_stringer (int type)
          }
        case '\"':
          ++input_line_pointer; /* -> 1st char of string.  */
-         start = input_line_pointer;
          while (is_a_char (c = next_char_of_string ()))
            {
              if (!packed)
@@ -1695,7 +1688,7 @@ tic54x_align_words (int arg)
 static void
 tic54x_field (int ignore ATTRIBUTE_UNUSED)
 {
-  expressionS exp;
+  expressionS expn;
   int size = 16;
   char *p;
   valueT value;
@@ -1707,7 +1700,7 @@ tic54x_field (int ignore ATTRIBUTE_UNUSED)
       return;
     }
 
-  input_line_pointer = parse_expression (input_line_pointer, &exp);
+  input_line_pointer = parse_expression (input_line_pointer, &expn);
 
   if (*input_line_pointer == ',')
     {
@@ -1722,7 +1715,7 @@ tic54x_field (int ignore ATTRIBUTE_UNUSED)
     }
 
   /* Truncate values to the field width.  */
-  if (exp.X_op != O_constant)
+  if (expn.X_op != O_constant)
     {
       /* If the expression value is relocatable, the field size *must*
          be 16.  */
@@ -1734,17 +1727,17 @@ tic54x_field (int ignore ATTRIBUTE_UNUSED)
        }
 
       frag_now->tc_frag_data = 0;
-      emit_expr (&exp, 2);
+      emit_expr (&expn, 2);
     }
   else
     {
       unsigned long fmask = (size == 32) ? 0xFFFFFFFF : (1ul << size) - 1;
 
-      value = exp.X_add_number;
-      exp.X_add_number &= fmask;
-      if (value != (valueT) exp.X_add_number)
+      value = expn.X_add_number;
+      expn.X_add_number &= fmask;
+      if (value != (valueT) expn.X_add_number)
        as_warn (_("field value truncated"));
-      value = exp.X_add_number;
+      value = expn.X_add_number;
       /* Bits are stored MS first.  */
       while (size >= 16)
        {
@@ -2012,17 +2005,17 @@ tic54x_message (int type)
 static void
 tic54x_label (int ignored ATTRIBUTE_UNUSED)
 {
-  char *name = input_line_pointer;
+  char *name;
   symbolS *symbolP;
   int c;
 
   ILLEGAL_WITHIN_STRUCT ();
 
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   symbolP = colon (name);
   S_SET_STORAGE_CLASS (symbolP, C_STATLAB);
 
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
   demand_empty_rest_of_line ();
 }
 
@@ -2145,12 +2138,12 @@ tic54x_sblock (int ignore ATTRIBUTE_UNUSED)
        }
       else
        {
-         char *section_name = input_line_pointer;
+         char *section_name;
 
-         c = get_symbol_end ();
+         c = get_symbol_name (&section_name);
          name = xmalloc (strlen (section_name) + 1);
          strcpy (name, section_name);
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
        }
 
       seg = bfd_get_section_by_name (stdoutput, name);
@@ -2260,12 +2253,11 @@ tic54x_var (int ignore ATTRIBUTE_UNUSED)
          ignore_rest_of_line ();
          return;
        }
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       /* .var symbols start out with a null string.  */
       name = strcpy (xmalloc (strlen (name) + 1), name);
       hash_insert (subsym_hash[macro_level], name, empty);
-      *input_line_pointer = c;
+      c = restore_line_pointer (c);
       if (c == ',')
        {
          ++input_line_pointer;
@@ -2372,13 +2364,13 @@ tic54x_mlib (int ignore ATTRIBUTE_UNUSED)
       FILE *ftmp;
 
       /* We're not sure how big it is, but it will be smaller than "size".  */
-      bfd_bread (buf, size, mbfd);
+      size = bfd_bread (buf, size, mbfd);
 
       /* Write to a temporary file, then use s_include to include it
         a bit of a hack.  */
       ftmp = fopen (fname, "w+b");
       fwrite ((void *) buf, size, 1, ftmp);
-      if (buf[size - 1] != '\n')
+      if (size == 0 || buf[size - 1] != '\n')
        fwrite ("\n", 1, 1, ftmp);
       fclose (ftmp);
       free (buf);
@@ -2656,11 +2648,11 @@ subsym_ismember (char *sym, char *list)
 static int
 subsym_iscons (char *a, char *ignore ATTRIBUTE_UNUSED)
 {
-  expressionS exp;
+  expressionS expn;
 
-  parse_expression (a, &exp);
+  parse_expression (a, &expn);
 
-  if (exp.X_op == O_constant)
+  if (expn.X_op == O_constant)
     {
       int len = strlen (a);
 
@@ -2989,7 +2981,7 @@ static const math_proc_entry math_procs[] =
 void
 md_begin (void)
 {
-  template *tm;
+  insn_template *tm;
   symbol *sym;
   const subsym_proc_entry *subsym_proc;
   const math_proc_entry *math_proc;
@@ -3018,7 +3010,7 @@ md_begin (void)
     }
 
   op_hash = hash_new ();
-  for (tm = (template *) tic54x_optab; tm->name; tm++)
+  for (tm = (insn_template *) tic54x_optab; tm->name; tm++)
     {
       if (hash_find (op_hash, tm->name))
        continue;
@@ -3028,7 +3020,7 @@ md_begin (void)
                  tm->name, hash_err);
     }
   parop_hash = hash_new ();
-  for (tm = (template *) tic54x_paroptab; tm->name; tm++)
+  for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++)
     {
       if (hash_find (parop_hash, tm->name))
        continue;
@@ -4179,7 +4171,7 @@ optimize_insn (tic54x_insn *insn)
 static int
 tic54x_parse_insn (tic54x_insn *insn, char *line)
 {
-  insn->tm = (template *) hash_find (op_hash, insn->mnemonic);
+  insn->tm = (insn_template *) hash_find (op_hash, insn->mnemonic);
   if (!insn->tm)
     {
       as_bad (_("Unrecognized instruction \"%s\""), insn->mnemonic);
@@ -4202,8 +4194,8 @@ tic54x_parse_insn (tic54x_insn *insn, char *line)
          /* SUCCESS! now try some optimizations.  */
          if (optimize_insn (insn))
            {
-             insn->tm = (template *) hash_find (op_hash,
-                                                insn->mnemonic);
+             insn->tm = (insn_template *) hash_find (op_hash,
+                                                      insn->mnemonic);
              continue;
            }
 
@@ -4237,7 +4229,7 @@ next_line_shows_parallel (char *next_line)
 static int
 tic54x_parse_parallel_insn_firstline (tic54x_insn *insn, char *line)
 {
-  insn->tm = (template *) hash_find (parop_hash, insn->mnemonic);
+  insn->tm = (insn_template *) hash_find (parop_hash, insn->mnemonic);
   if (!insn->tm)
     {
       as_bad (_("Unrecognized parallel instruction \"%s\""),
@@ -4504,8 +4496,8 @@ subsym_substitute (char *line, int forced)
          if (forced)
            ++ptr;
 
-         name = input_line_pointer = ptr;
-         c = get_symbol_end ();
+         input_line_pointer = ptr;
+         c = get_symbol_name (&name);
          /* '?' is not normally part of a symbol, but it IS part of a local
             label.  */
          if (c == '?')
@@ -4570,10 +4562,10 @@ subsym_substitute (char *line, int forced)
              ++ptr;
              if (math_entry != NULL)
                {
-                 float arg1, arg2 = 0;
+                 float farg1, farg2 = 0;
                  volatile float fresult;
 
-                 arg1 = (float) strtod (ptr, &ptr);
+                 farg1 = (float) strtod (ptr, &ptr);
                  if (math_entry->nargs == 2)
                    {
                      if (*ptr++ != ',')
@@ -4581,9 +4573,9 @@ subsym_substitute (char *line, int forced)
                          as_bad (_("Expecting second argument"));
                          break;
                        }
-                     arg2 = (float) strtod (ptr, &ptr);
+                     farg2 = (float) strtod (ptr, &ptr);
                    }
-                 fresult = (*math_entry->proc) (arg1, arg2);
+                 fresult = (*math_entry->proc) (farg1, farg2);
                  value = xmalloc (128);
                  if (math_entry->int_return)
                    sprintf (value, "%d", (int) fresult);
@@ -4781,7 +4773,7 @@ tic54x_start_line_hook (void)
   line[endp - input_line_pointer] = 0;
 
   /* Scan ahead for parallel insns.  */
-  parallel_on_next_line_hint = next_line_shows_parallel (endp + 1);
+  parallel_on_next_line_hint = next_line_shows_parallel (endp);
 
   /* If within a macro, first process forced replacements.  */
   if (macro_level > 0)
@@ -4850,7 +4842,7 @@ md_assemble (char *line)
   int c;
 
   input_line_pointer = line;
-  c = get_symbol_end ();
+  c = get_symbol_name (&line);
 
   if (cpu == VNONE)
     cpu = V542;
@@ -5080,7 +5072,7 @@ tic54x_undefined_symbol (char *name)
 
 int
 tic54x_parse_name (char *name ATTRIBUTE_UNUSED,
-                  expressionS *exp ATTRIBUTE_UNUSED)
+                  expressionS *expn ATTRIBUTE_UNUSED)
 {
   return 0;
 }
@@ -5125,10 +5117,9 @@ tc_gen_reloc (asection *section, fixS *fixP)
 /* Handle cons expressions.  */
 
 void
-tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *exp)
+tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *expn,
+                    bfd_reloc_code_real_type r)
 {
-  bfd_reloc_code_real_type r;
-
   switch (octets)
     {
     default:
@@ -5148,7 +5139,7 @@ tic54x_cons_fix_new (fragS *frag, int where, int octets, expressionS *exp)
        r = BFD_RELOC_32;
       break;
     }
-  fix_new_exp (frag, where, octets, exp, 0, r);
+  fix_new_exp (frag, where, octets, expn, 0, r);
 }
 
 /* Attempt to simplify or even eliminate a fixup.
@@ -5366,22 +5357,21 @@ tic54x_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
    syntax puts the symbol *before* the pseudo (which is kinda like MRI syntax,
    I guess, except I've never seen a definition of MRI syntax).
 
-   C is the character that used to be at *REST, which points to the end of the
-   label.
-
    Don't allow labels to start with '.'  */
 
 int
-tic54x_start_label (int c, char *rest)
+tic54x_start_label (int nul_char, int next_char)
 {
+  char *rest;
+
   /* If within .struct/.union, no auto line labels, please.  */
   if (current_stag != NULL)
     return 0;
 
   /* Disallow labels starting with "."  */
-  if (c != ':')
+  if (next_char != ':')
     {
-      char *label = rest;
+      char *label = input_line_pointer;
 
       while (!is_end_of_line[(int) label[-1]])
        --label;
@@ -5392,22 +5382,22 @@ tic54x_start_label (int c, char *rest)
        }
     }
 
-  if (is_end_of_line[(int) c])
+  if (is_end_of_line[(int) next_char])
     return 1;
 
-  if (ISSPACE (c))
-    while (ISSPACE (c = *++rest))
-      ;
-  if (c == '.')
-    {
-      /* Don't let colon () define a label for any of these...  */
-      return (strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
-       && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
-       && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
-       && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
-       && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
-       && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4]));
-    }
+  rest = input_line_pointer;
+  if (nul_char == '"')
+    ++rest;
+  while (ISSPACE (next_char))
+    next_char = *++rest;
+  if (next_char != '.')
+    return 1;
 
-  return 1;
+  /* Don't let colon () define a label for any of these...  */
+  return ((strncasecmp (rest, ".tag", 4) != 0 || !ISSPACE (rest[4]))
+         && (strncasecmp (rest, ".struct", 7) != 0 || !ISSPACE (rest[7]))
+         && (strncasecmp (rest, ".union", 6) != 0 || !ISSPACE (rest[6]))
+         && (strncasecmp (rest, ".macro", 6) != 0 || !ISSPACE (rest[6]))
+         && (strncasecmp (rest, ".set", 4) != 0 || !ISSPACE (rest[4]))
+         && (strncasecmp (rest, ".equ", 4) != 0 || !ISSPACE (rest[4])));
 }
This page took 0.053323 seconds and 4 git commands to generate.