* config/tc-hppa.c (pa_get_number): New.
authorDave Anglin <dave.anglin@nrc.ca>
Sun, 14 Oct 2012 23:59:39 +0000 (23:59 +0000)
committerDave Anglin <dave.anglin@nrc.ca>
Sun, 14 Oct 2012 23:59:39 +0000 (23:59 +0000)
(pa_get_absolute_expression): Simplify.
(pa_ip): Use pa_get_number instead of pa_get_absolute_expression
to get SOP, SFU and COPR identifiers.

gas/ChangeLog
gas/config/tc-hppa.c

index 376869e9d6b2e63b074cb64b90313dca40efa166..c3cbe25db3b1c8b24998235994361d066d36691c 100644 (file)
@@ -1,5 +1,10 @@
 2012-10-14  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
+       * config/tc-hppa.c (pa_get_number): New.
+       (pa_get_absolute_expression): Simplify.
+       (pa_ip): Use pa_get_number instead of pa_get_absolute_expression
+       to get SOP, SFU and COPR identifiers.
+
        * config/tc-hppa.c (pa_ip): Reject double floating point stores and
        loads that reference the right half of a floating point register.
 
index 16192d8969ff4a05ba329a4de95ff6bf048cb572..6e2debe9764e50d68627b4dbf869cdb41cb191a3 100644 (file)
@@ -2552,50 +2552,54 @@ pa_get_absolute_expression (struct pa_it *insn, char **strp)
   save_in = input_line_pointer;
   input_line_pointer = *strp;
   expression (&insn->exp);
-  /* This is not perfect, but is a huge improvement over doing nothing.
+  expr_end = input_line_pointer;
+  input_line_pointer = save_in;
+  if (insn->exp.X_op != O_constant)
+    {
+      /* We have a non-match in strict mode.  */
+      if (!strict)
+       as_bad (_("Bad segment (should be absolute)."));
+      return 0;
+    }
+  return evaluate_absolute (insn);
+}
+
+/* Get an absolute number.  The input string is terminated at the
+   first whitespace character.  */
+
+static int
+pa_get_number (struct pa_it *insn, char **strp)
+{
+  char *save_in;
+  char *s, c;
+  int result;
+
+  save_in = input_line_pointer;
+  input_line_pointer = *strp;
 
-     The PA assembly syntax is ambiguous in a variety of ways.  Consider
+  /* The PA assembly syntax is ambiguous in a variety of ways.  Consider
      this string "4 %r5"  Is that the number 4 followed by the register
-     r5, or is that 4 MOD r5?
+     r5, or is that 4 MOD r5?  This situation occurs for example in the
+     coprocessor load and store instructions.  Previously, calling
+     pa_get_absolute_expression directly results in r5 being entered
+     in the symbol table.
 
-     If we get a modulo expression when looking for an absolute, we try
-     again cutting off the input string at the first whitespace character.  */
-  if (insn->exp.X_op == O_modulus)
-    {
-      char *s, c;
+     So, when looking for an absolute number, we cut off the input string
+     at the first whitespace character.  Thus, expressions should generally
+     contain no whitespace.  */
 
-      input_line_pointer = *strp;
-      s = *strp;
-      while (*s != ',' && *s != ' ' && *s != '\t')
-       s++;
+  s = *strp;
+  while (*s != ',' && *s != ' ' && *s != '\t')
+    s++;
 
-      c = *s;
-      *s = 0;
+  c = *s;
+  *s = 0;
 
-      pa_get_absolute_expression (insn, strp);
+  result = pa_get_absolute_expression (insn, strp);
 
-      input_line_pointer = save_in;
-      *s = c;
-      return evaluate_absolute (insn);
-    }
-  /* When in strict mode we have a non-match, fix up the pointers
-     and return to our caller.  */
-  if (insn->exp.X_op != O_constant && strict)
-    {
-      expr_end = input_line_pointer;
-      input_line_pointer = save_in;
-      return 0;
-    }
-  if (insn->exp.X_op != O_constant)
-    {
-      as_bad (_("Bad segment (should be absolute)."));
-      expr_end = input_line_pointer;
-      input_line_pointer = save_in;
-      return 0;
-    }
-  expr_end = input_line_pointer;
   input_line_pointer = save_in;
-  return evaluate_absolute (insn);
+  *s = c;
+  return result;
 }
 
 /* Given an argument location specification return the associated
@@ -5292,7 +5296,7 @@ pa_ip (char *str)
            case 'v':
              if (*s++ != ',')
                as_bad (_("Invalid SFU identifier"));
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5301,7 +5305,7 @@ pa_ip (char *str)
 
            /* Handle a 20 bit SOP field for spop0.  */
            case 'O':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5311,7 +5315,7 @@ pa_ip (char *str)
 
            /* Handle a 15bit SOP field for spop1.  */
            case 'o':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5320,7 +5324,7 @@ pa_ip (char *str)
 
            /* Handle a 10bit SOP field for spop3.  */
            case '0':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5330,7 +5334,7 @@ pa_ip (char *str)
 
            /* Handle a 15 bit SOP field for spop2.  */
            case '1':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5342,7 +5346,7 @@ pa_ip (char *str)
            case 'u':
              if (*s++ != ',')
                as_bad (_("Invalid COPR identifier"));
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5351,7 +5355,7 @@ pa_ip (char *str)
 
            /* Handle a 22bit SOP field for copr.  */
            case '2':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;