* config/tc-hppa.c (md_apply_fix): Handle new PA2.0 formats.
authorJeff Law <law@redhat.com>
Fri, 21 Apr 2000 20:34:00 +0000 (20:34 +0000)
committerJeff Law <law@redhat.com>
Fri, 21 Apr 2000 20:34:00 +0000 (20:34 +0000)
        * config/tc-hppa.c (CHECK_ALIGN): New macro.
        Added handling of new operand types l,y,&,fe,fE,fx.

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

index ca922ec3473d9614c260c3f1f287b8a72a2d3ae4..bbea9c3b31af2d12d3b97b4893ea53a128cfe4c5 100644 (file)
@@ -1,3 +1,11 @@
+Fri Apr 21 14:29:43 2000  Jeffrey A Law  (law@cygnus.com)
+                         Jason Eckhardt  <jle@cygnus.com>
+
+        * config/tc-hppa.c (md_apply_fix): Handle new PA2.0 formats.
+
+       * config/tc-hppa.c (CHECK_ALIGN): New macro.
+       Added handling of new operand types l,y,&,fe,fE,fx.
+
 Fri Apr 21 13:20:53 2000  Richard Henderson  <rth@cygnus.com>
                          David Mosberger  <davidm@hpl.hp.com>
                          Timothy Wall <twall@cygnus.com>
@@ -386,6 +394,8 @@ Sat Mar 11 00:01:39 2000  Hans-Peter Nilsson  <hp@axis.se>
        * doc/Makefile.in: Regenerate.
        * doc/c-m32r.texi (M32R-Opts): Document new command line switch.
 
+
+
 2000-03-02  Michael Meissner  <meissner@redhat.com>
 
        * config/tc-d30v.c (check_range): Remove code that incorrectly
index 7e95a4ad6d0a0462f7ab6a59cc5e94328c916dda..1dc5af4744909cfa308fd70f8e0bc7c2fccf2da5 100644 (file)
@@ -1114,6 +1114,20 @@ static struct default_space_dict pa_def_spaces[] =
       } \
   }
 
+/* Simple alignment checking for FIELD againt ALIGN (a power of two).
+   IGNORE is used to suppress the error message.  */
+
+#define CHECK_ALIGN(FIELD, ALIGN, IGNORE) \
+  { \
+    if ((FIELD) & ((ALIGN) - 1)) \
+      { \
+       if (! IGNORE) \
+          as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \
+                 (int) (FIELD));\
+        break; \
+      } \
+  }
+
 #define is_DP_relative(exp)                    \
   ((exp).X_op == O_subtract                    \
    && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0)
@@ -3080,6 +3094,86 @@ pa_ip (str)
                  continue;
                }
 
+           /* Handle a 16 bit immediate at 31 (PA 2.0 wide mode only).  */
+           case 'l':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 unsigned int result;
+                 num = evaluate_absolute (&the_insn);
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 dis_assemble_16 (num, &result, 1);
+                 INSERT_FIELD_AND_CONTINUE (opcode, result, 0);
+               }
+             else
+               {
+                 /* ??? Is this valid for wide mode?  */
+                 if (is_DP_relative (the_insn.exp))
+                   the_insn.reloc = R_HPPA_GOTOFF;
+                 else if (is_PC_relative (the_insn.exp))
+                   the_insn.reloc = R_HPPA_PCREL_CALL;
+                 else
+                   the_insn.reloc = R_HPPA;
+                 the_insn.format = 14;
+                 continue;
+               }
+
+           /* Handle a word-aligned 16-bit imm. at 31 (PA2.0 wide).  */
+           case 'y':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 unsigned int result;
+                 num = evaluate_absolute (&the_insn);
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 CHECK_ALIGN (num, 4, 0);
+                 dis_assemble_16 (num, &result, 1);
+                 INSERT_FIELD_AND_CONTINUE (opcode, result, 0);
+               }
+             else
+               {
+                 /* ??? Is this valid for wide mode?  */
+                 if (is_DP_relative (the_insn.exp))
+                   the_insn.reloc = R_HPPA_GOTOFF;
+                 else if (is_PC_relative (the_insn.exp))
+                   the_insn.reloc = R_HPPA_PCREL_CALL;
+                 else
+                   the_insn.reloc = R_HPPA;
+                 the_insn.format = 14;
+                 continue;
+               }
+
+           /* Handle a dword-aligned 16-bit imm. at 31 (PA2.0 wide).  */
+           case '&':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 unsigned int result;
+                 num = evaluate_absolute (&the_insn);
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 CHECK_ALIGN (num, 8, 0);
+                 dis_assemble_16 (num, &result, 1);
+                 INSERT_FIELD_AND_CONTINUE (opcode, result, 0);
+               }
+             else
+               {
+                 /* ??? Is this valid for wide mode?  */
+                 if (is_DP_relative (the_insn.exp))
+                   the_insn.reloc = R_HPPA_GOTOFF;
+                 else if (is_PC_relative (the_insn.exp))
+                   the_insn.reloc = R_HPPA_PCREL_CALL;
+                 else
+                   the_insn.reloc = R_HPPA;
+                 the_insn.format = 14;
+                 continue;
+               }
+
            /* Handle a 12 bit branch displacement.  */
            case 'w':
              the_insn.field_selector = pa_chk_field_selector (&s);
@@ -3806,6 +3900,7 @@ pa_ip (str)
                  }
 
                /* Handle L/R register halves like 'x'.  */
+               case 'E':
                case 'e':
                  {
                    struct pa_11_fp_reg_struct result;
@@ -3821,6 +3916,16 @@ pa_ip (str)
                      }
                    continue;
                  }
+
+               /* Float target register (PA 2.0 wide).  */
+               case 'x':
+                 /* This should be more strict.  Small steps.  */
+                 if (strict && *s != '%')
+                   break;
+                 num = pa_parse_number (&s, 0);
+                 CHECK_FIELD (num, 31, 0, 0);
+                 INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
+
                default:
                  abort ();
                }
@@ -4303,12 +4408,30 @@ md_apply_fix (fixP, valp)
          && S_GET_SEGMENT (fixP->fx_addsy) == hppa_fixP->segment
          && !(fixP->fx_subsy
               && S_GET_SEGMENT (fixP->fx_subsy) != hppa_fixP->segment))
-
+             
        new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
 #undef arg_reloc_stub_needed
-
+       
       switch (fmt)
        {
+       case 10:
+         CHECK_FIELD (new_val, 8191, -8192, 0);
+
+         /* Mask off 11 bits to be changed.  */
+         bfd_put_32 (stdoutput,
+                     bfd_get_32 (stdoutput, buf) & 0xffffc00e,
+                     buf);
+         result = ((new_val & 0x1fff) >> 2) | ((new_val & 0x2000) >> 13);
+         break;
+       case -11:
+         CHECK_FIELD (new_val, 8191, -8192, 0);
+
+         /* Mask off 14 bits to be changed.  */
+         bfd_put_32 (stdoutput,
+                     bfd_get_32 (stdoutput, buf) & 0xffffc006,
+                     buf);
+         result = ((new_val & 0x1fff) >> 1) | ((new_val & 0x2000) >> 15);
+         break;
        /* Handle all opcodes with the 'j' operand type.  */
        case 14:
          CHECK_FIELD (new_val, 8191, -8192, 0);