Assorted code cleanup and fixes for hppa. Re-enable elf32-hppa as
[deliverable/binutils-gdb.git] / gas / config / tc-hppa.c
index e72da2863e521662796fc28764318939c8211681..3876842873bf3a754960d6a1de62b4f38d1b1bb5 100644 (file)
@@ -495,6 +495,9 @@ static int pa_parse_nonneg_cmpsub_cmpltr PARAMS ((char **, int));
 static int pa_parse_neg_cmpsub_cmpltr PARAMS ((char **, int));
 static int pa_parse_neg_add_cmpltr PARAMS ((char **, int));
 static int pa_parse_nonneg_add_cmpltr PARAMS ((char **, int));
+static int pa_parse_cmpb_64_cmpltr PARAMS ((char **));
+static int pa_parse_cmpib_64_cmpltr PARAMS ((char **));
+static int pa_parse_addb_64_cmpltr PARAMS ((char **));
 static void pa_block PARAMS ((int));
 static void pa_brtab PARAMS ((int));
 static void pa_try PARAMS ((int));
@@ -525,6 +528,7 @@ static int need_pa11_opcode PARAMS ((struct pa_it *,
 static int pa_parse_number PARAMS ((char **, struct pa_11_fp_reg_struct *));
 static label_symbol_struct *pa_get_label PARAMS ((void));
 #ifdef OBJ_SOM
+static int log2 PARAMS ((int));
 static void pa_compiler PARAMS ((int));
 static void pa_align PARAMS ((int));
 static void pa_space PARAMS ((int));
@@ -565,7 +569,6 @@ static int reg_name_search PARAMS ((char *));
 static int pa_chk_field_selector PARAMS ((char **));
 static int is_same_frag PARAMS ((fragS *, fragS *));
 static void process_exit PARAMS ((void));
-static int log2 PARAMS ((int));
 static unsigned int pa_stringer_aux PARAMS ((char *));
 static fp_operand_format pa_parse_fp_cnv_format PARAMS ((char **s));
 static int pa_parse_ftest_gfx_completer PARAMS ((char **));
@@ -643,7 +646,7 @@ const pseudo_typeS md_pseudo_table[] =
   {"exit", pa_exit, 0},
   {"export", pa_export, 0},
 #ifdef OBJ_ELF
-  { "file", dwarf2_directive_file },
+  { "file", dwarf2_directive_file, 0 },
 #endif
   {"fill", pa_fill, 0},
   {"float", pa_float_cons, 'f'},
@@ -655,7 +658,7 @@ const pseudo_typeS md_pseudo_table[] =
   {"leave", pa_leave, 0},
   {"level", pa_level, 0},
 #ifdef OBJ_ELF
-  { "loc", dwarf2_directive_loc },
+  { "loc", dwarf2_directive_loc, 0 },
 #endif
   {"long", pa_cons, 4},
   {"lsym", pa_lsym, 0},
@@ -1111,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)
@@ -1254,7 +1271,7 @@ fix_new_hppa (frag, where, size, add_symbol, offset, exp, pcrel,
      enum hppa_reloc_field_selector_type_alt r_field;
      int r_format;
      long arg_reloc;
-     int* unwind_bits;
+     int* unwind_bits ATTRIBUTE_UNUSED;
 {
   fixS *new_fix;
 
@@ -1393,7 +1410,7 @@ md_begin ()
   dummy_symbol = symbol_find_or_make ("L$dummy");
   S_SET_SEGMENT (dummy_symbol, text_section);
   /* Force the symbol to be converted to a real symbol. */
-  (void) symbol_get_bfdsym (dummy_symbol); 
+  (void) symbol_get_bfdsym (dummy_symbol);
 #endif
 }
 
@@ -1683,7 +1700,7 @@ pa_ip (str)
              /* When in strict mode, we want to just reject this
                 match instead of giving an out of range error.  */
              CHECK_FIELD (num, 15, -16, strict);
-             low_sign_unext (num, 5, &num);
+             num = low_sign_unext (num, 5);
              INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
 
            /* Handle a 5 bit immediate at 31.  */
@@ -1695,7 +1712,7 @@ pa_ip (str)
              /* When in strict mode, we want to just reject this
                 match instead of giving an out of range error.  */
              CHECK_FIELD (num, 15, -16, strict)
-             low_sign_unext (num, 5, &num);
+             num = low_sign_unext (num, 5);
              INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
 
            /* Handle an unsigned 5 bit immediate at 31.  */
@@ -1741,8 +1758,8 @@ pa_ip (str)
                break;
              num = pa_parse_number (&s, 0);
              CHECK_FIELD (num, 7, 0, 1);
-             dis_assemble_3 (num, &num);
-             INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
+             opcode = re_assemble_3 (opcode, num);
+             continue;
 
            /* Handle all completers.  */
            case 'c':
@@ -1767,11 +1784,15 @@ pa_ip (str)
                          }
                        else if (strncasecmp (s, "m", 1) == 0)
                          m = 1;
-                       else if (strncasecmp (s, "s", 1) == 0)
+                       else if ((strncasecmp (s, "s ", 2) == 0)
+                                || (strncasecmp (s, "s,", 2) == 0))
                          uu = 1;
                        /* When in strict mode this is a match failure.  */
                        else if (strict)
-                         break;
+                         {
+                           s--;
+                           break;
+                         }
                        else
                          as_bad (_("Invalid Indexed Load Completer."));
                        s++;
@@ -1785,32 +1806,69 @@ pa_ip (str)
 
                /* Handle a short load/store completer.  */
                case 'm':
+               case 'q':
+               case 'J':
+               case 'e':
                  {
                    int a = 0;
                    int m = 0;
                    if (*s == ',')
                      {
+                       int found = 0;
                        s++;
                        if (strncasecmp (s, "ma", 2) == 0)
                          {
                            a = 0;
                            m = 1;
+                           found = 1;
                          }
                        else if (strncasecmp (s, "mb", 2) == 0)
                          {
                            a = 1;
                            m = 1;
+                           found = 1;
                          }
-                       /* When in strict mode this is a match failure.  */
-                       else if (strict)
-                         break;
+
+                       /* When in strict mode, pass through for cache op.  */
+                       if (!found && strict)
+                         s--;
                        else
-                         as_bad (_("Invalid Short Load/Store Completer."));
-                       s += 2;
+                         {
+                           if (!found)
+                             as_bad (_("Invalid Short Load/Store Completer."));
+                           s += 2;
+                         }
                      }
+                   /* If we did not get a ma/mb completer, then we do not
+                      consider this a positive match for 'ce'.  */
+                   else if (*args == 'e')
+                     break;
 
-                   opcode |= m << 5;
-                   INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
+                  /* 'J', 'm' and 'q' are the same, except for where they
+                      encode the before/after field.  */
+                  if (*args == 'm')
+                     {
+                       opcode |= m << 5;
+                       INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
+                     }
+                   else if (*args == 'q')
+                     {
+                       opcode |= m << 3;
+                       INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
+                     }
+                   else if (*args == 'J')
+                     {
+                       /* M bit is explicit in the major opcode.  */
+                       INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
+                     }
+                   else if (*args == 'e')
+                     {
+                       /* Gross!  Hide these values in the immediate field
+                          of the instruction, then pull them out later.  */
+                       opcode |= m << 8;
+                       opcode |= a << 9;
+                       continue;
+                     }
                  }
 
                /* Handle a stbys completer.  */
@@ -1824,13 +1882,17 @@ pa_ip (str)
                        s++;
                        if (strncasecmp (s, "m", 1) == 0)
                          m = 1;
-                       else if (strncasecmp (s, "b", 1) == 0)
+                       else if ((strncasecmp (s, "b ", 2) == 0)
+                                || (strncasecmp (s, "b,", 2) == 0))
                          a = 0;
                        else if (strncasecmp (s, "e", 1) == 0)
                          a = 1;
                        /* When in strict mode this is a match failure.  */
                        else if (strict)
-                         break;
+                         {
+                           s--;
+                           break;
+                         }
                        else
                          as_bad (_("Invalid Store Bytes Short Completer"));
                        s++;
@@ -1842,6 +1904,76 @@ pa_ip (str)
                    INSERT_FIELD_AND_CONTINUE (opcode, a, 13);
                  }
 
+               /* Handle load cache hint completer.  */
+               case 'c':
+                 cmpltr = 0;
+                 if (!strncmp(s, ",sl", 3))
+                   {
+                     s += 3;
+                     cmpltr = 2;
+                   }
+                 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);
+
+               /* Handle store cache hint completer.  */
+               case 'C':
+                 cmpltr = 0;
+                 if (!strncmp(s, ",sl", 3))
+                   {
+                     s += 3;
+                     cmpltr = 2;
+                   }
+                 else if (!strncmp(s, ",bc", 3))
+                   {
+                     s += 3;
+                     cmpltr = 1;
+                   }
+                 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);
+
+               /* Handle load and clear cache hint completer.  */
+               case 'd':
+                 cmpltr = 0;
+                 if (!strncmp(s, ",co", 3))
+                   {
+                     s += 3;
+                     cmpltr = 1;
+                   }
+                 INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);
+
+               /* Handle load ordering completer. */
+               case 'o':
+                 if (strncmp(s, ",o", 2) != 0)
+                   break;
+                 s += 2;
+                 continue;
+
+               /* Handle a branch gate completer.  */
+               case 'g':
+                 if (strncasecmp (s, ",gate", 5) != 0)
+                   break;
+                 s += 5;
+                 continue;
+
+               /* Handle a branch link and push completer.  */
+               case 'p':
+                 if (strncasecmp (s, ",l,push", 7) != 0)
+                   break;
+                 s += 7;
+                 continue;
+
+               /* Handle a branch link completer.  */
+               case 'l':
+                 if (strncasecmp (s, ",l", 2) != 0)
+                   break;
+                 s += 2;
+                 continue;
+
+               /* Handle a branch pop completer.  */
+               case 'P':
+                 if (strncasecmp (s, ",pop", 4) != 0)
+                   break;
+                 s += 4;
+                 continue;
+
                /* Handle a local processor completer.  */
                case 'L':
                  if (strncasecmp (s, ",l", 2) != 0)
@@ -1866,7 +1998,7 @@ pa_ip (str)
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 6);
 
                /* Handle MFCTL wide completer.  */
-               case 'W':       
+               case 'W':
                  if (strncasecmp (s, ",w", 2) != 0)
                    break;
                  s += 2;
@@ -1930,7 +2062,7 @@ pa_ip (str)
                      flag = 3;
                      s += 4;
                    }
-                 
+
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 10);
 
                /* Handle 64 bit carry for ADD.  */
@@ -2109,9 +2241,13 @@ pa_ip (str)
                case '*':
                  if (*s++ == ',')
                    {
-                     int permloc[4] = {13,10,8,6};
+                     int permloc[4];
                      int perm = 0;
                      int i = 0;
+                     permloc[0] = 13;
+                     permloc[1] = 10;
+                     permloc[2] = 8;
+                     permloc[3] = 6;
                      for (; i < 4; i++)
                        {
                          switch (*s++)
@@ -2248,24 +2384,27 @@ pa_ip (str)
                    cmpltr = pa_parse_nonneg_add_cmpltr (&s, 1);
                    if (cmpltr < 0)
                      {
-                       as_bad (_("Invalid Compare/Subtract Condition: %c"), *s);
+                       as_bad (_("Invalid Add and Branch Condition: %c"), *s);
                        cmpltr = 0;
                      }
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
 
-                 /* Handle negated add and branch condition.  */
-                 case 'D':
-                   abort ();
-
-                 /* Handle wide-mode non-negated add and branch condition.  */
-                 case 'w':
-                   abort ();
-
-                 /* Handle wide-mode negated add and branch condition.  */
+                 /* Handle 64 bit wide-mode add and branch condition.  */
                  case 'W':
-                   abort();
+                   cmpltr = pa_parse_addb_64_cmpltr (&s);
+                   if (cmpltr < 0)
+                     {
+                       as_bad (_("Invalid Add and Branch Condition: %c"), *s);
+                       cmpltr = 0;
+                     }
+                   else
+                     {
+                       /* Negated condition requires an opcode change. */
+                       opcode |= (cmpltr & 8) << 24;
+                     }
+                   INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
 
-                 /* Handle a negated or non-negated add and branch 
+                 /* Handle a negated or non-negated add and branch
                     condition.  */
                  case '@':
                    save_s = s;
@@ -2331,16 +2470,16 @@ pa_ip (str)
 
                        /* 64 bit conditions.  */
                        if (*args == 'S')
-                         { 
+                         {
                            if (*s == '*')
                              s++;
                            else
                              break;
-                         } 
+                         }
                        else if (*s == '*')
                          break;
                        name = s;
-                           
+
                        name = s;
                        while (*s != ',' && *s != ' ' && *s != '\t')
                          s += 1;
@@ -2419,24 +2558,7 @@ pa_ip (str)
                      }
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
 
-                 /* Handle a negated compare condition.  */
-                 case 'T':
-                   abort ();
-  
-                 /* Handle a 64 bit non-negated compare condition.  */
-                 case 'r':
-                   abort ();
-  
-                 /* Handle a 64 bit negated compare condition.  */
-                 case 'R':
-                   abort ();
-  
-                 /* Handle a 64 bit cmpib condition.  */
-                 case 'Q':
-                   abort ();
-  
-                 /* Handle a negated or non-negated compare/subtract
-                    condition.  */
+                 /* Handle a 32 bit compare and branch condition.  */
                  case 'n':
                    save_s = s;
                    cmpltr = pa_parse_nonneg_cmpsub_cmpltr (&s, 1);
@@ -2446,7 +2568,7 @@ pa_ip (str)
                        cmpltr = pa_parse_neg_cmpsub_cmpltr (&s, 1);
                        if (cmpltr < 0)
                          {
-                           as_bad (_("Invalid Compare/Subtract Condition."));
+                           as_bad (_("Invalid Compare and Branch Condition."));
                            cmpltr = 0;
                          }
                        else
@@ -2455,7 +2577,30 @@ pa_ip (str)
                            opcode |= 1 << 27;
                          }
                      }
-           
+
+                   INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
+
+                 /* Handle a 64 bit compare and branch condition.  */
+                 case 'N':
+                   cmpltr = pa_parse_cmpb_64_cmpltr (&s);
+                   if (cmpltr >= 0)
+                     {
+                       /* Negated condition requires an opcode change. */
+                       opcode |= (cmpltr & 8) << 26;
+                     }
+                   else
+                     /* Not a 64 bit cond.  Give 32 bit a chance. */
+                     break;
+
+                   INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
+
+                 /* Handle a 64 bit cmpib condition.  */
+                 case 'Q':
+                   cmpltr = pa_parse_cmpib_64_cmpltr (&s);
+                   if (cmpltr < 0)
+                     /* Not a 64 bit cond.  Give 32 bit a chance. */
+                     break;
+
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
 
                    /* Handle a logical instruction condition.  */
@@ -2478,14 +2623,14 @@ pa_ip (str)
                        else if (*s == '*')
                          break;
                        name = s;
-                           
+
                        name = s;
                        while (*s != ',' && *s != ' ' && *s != '\t')
                          s += 1;
                        c = *s;
                        *s = 0x00;
-           
-           
+
+
                        if (strcmp (name, "=") == 0)
                          cmpltr = 1;
                        else if (strcmp (name, "<") == 0)
@@ -2547,7 +2692,7 @@ pa_ip (str)
                        else if (*s == '*')
                          break;
                        name = s;
-                           
+
                        name = s;
                        while (*s != ',' && *s != ' ' && *s != '\t')
                          s += 1;
@@ -2590,7 +2735,7 @@ pa_ip (str)
                    if (*s == ',')
                      {
                        s++;
-           
+
                        /* 64 bit conditions.  */
                        if (*args == 'U')
                          {
@@ -2601,7 +2746,7 @@ pa_ip (str)
                          }
                        else if (*s == '*')
                          break;
-                           
+
                        if (strncasecmp (s, "sbz", 3) == 0)
                          {
                            cmpltr = 2;
@@ -2663,6 +2808,30 @@ pa_ip (str)
                            flag = 1;
                            s += 3;
                          }
+                       else if (strncasecmp (s, "swz", 3) == 0)
+                         {
+                           cmpltr = 1;
+                           flag = 0;
+                           s += 3;
+                         }
+                       else if (strncasecmp (s, "swc", 3) == 0)
+                         {
+                           cmpltr = 5;
+                           flag = 0;
+                           s += 3;
+                         }
+                       else if (strncasecmp (s, "nwz", 3) == 0)
+                         {
+                           cmpltr = 1;
+                           flag = 1;
+                           s += 3;
+                         }
+                       else if (strncasecmp (s, "nwc", 3) == 0)
+                         {
+                           cmpltr = 5;
+                           flag = 1;
+                           s += 3;
+                         }
                        /* ",*" is a valid condition.  */
                        else if (*args != 'U')
                          as_bad (_("Invalid Unit Instruction Condition."));
@@ -2686,43 +2855,11 @@ pa_ip (str)
              nullif = pa_parse_nullif (&s);
              INSERT_FIELD_AND_CONTINUE (opcode, nullif, 5);
 
-           /* Handle ,gate completer for new syntax branches.  */
-           case 'g':
-             if (*s == ',' && strcasecmp (s + 1, "gate") == 0)
-               s += 5;
-             else
-               break;
-             continue;
-
-           /* Handle ,l completer for new syntax branches.  */
-           case 'l':
-             if (*s == ',' && strcasecmp (s + 1, "l") == 0)
-               s += 2;
-             else
-               break;
-             continue;
-
-           /* Handle ,push completer for new syntax branches.  */
-           case 'M':
-             if (*s == ',' && strcasecmp (s + 1, "push") == 0)
-               s += 5;
-             else
-               break;
-             continue;
-
-           /* Handle ,pop completer for new syntax branches.  */
-           case 'B':
-             if (*s == ',' && strcasecmp (s + 1, "pop") == 0)
-               s += 4;
-             else
-               break;
-             continue;
-
            /* Handle ,%r2 completer for new syntax branches.  */
            case 'L':
-             if (*s == ',' && strcasecmp (s + 1, "%r2") == 0)
+             if (*s == ',' && strncasecmp (s + 1, "%r2", 3) == 0)
                s += 4;
-             else if (*s == ',' && strcasecmp (s + 1, "%rp") == 0)
+             else if (*s == ',' && strncasecmp (s + 1, "%rp", 3) == 0)
                s += 4;
              else
                break;
@@ -2747,16 +2884,16 @@ pa_ip (str)
               are 0..6 inclusive.  */
            case 'm':
              get_expression (s);
-             s = expr_end;
              if (the_insn.exp.X_op == O_constant)
                {
+                 s = expr_end;
                  num = evaluate_absolute (&the_insn);
                  CHECK_FIELD (num, 6, 0, 0);
                  num = (num + 1) ^ 1;
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 13);
                }
              else
-               as_bad (_("Invalid CBit Specification: %s"), s);
+               break;
 
            /* Handle graphics test completers for ftest */
            case '=':
@@ -2774,7 +2911,7 @@ pa_ip (str)
                {
                  num = evaluate_absolute (&the_insn);
                  CHECK_FIELD (num, 1023, -1024, 0);
-                 low_sign_unext (num, 11, &num);
+                 num = low_sign_unext (num, 11);
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
                }
              else
@@ -2789,6 +2926,125 @@ pa_ip (str)
                  continue;
                }
 
+           /* Handle a 14 bit immediate at 31.  */
+           case 'J':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 int a, m;
+
+                 /* XXX the completer stored away tibits of information
+                    for us to extract.  We need a cleaner way to do this.
+                    Now that we have lots of letters again, it would be
+                    good to rethink this.  */
+                 m = (opcode & (1 << 8)) != 0;
+                 a = (opcode & (1 << 9)) != 0;
+                 opcode &= ~ (3 << 8);
+                 num = evaluate_absolute (&the_insn);
+                 if ((a == 1 && num >= 0) || (a == 0 && num < 0))
+                   break;
+                 CHECK_FIELD (num, 8191, -8192, 0);
+                 num = low_sign_unext (num, 14);
+                 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+               }
+             else
+               {
+                 break;
+               }
+
+           /* Handle a 14 bit immediate at 31.  */
+           case 'K':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 int a, m;
+
+                 /* XXX the completer stored away tibits of information
+                    for us to extract.  We need a cleaner way to do this.
+                    Now that we have lots of letters again, it would be
+                    good to rethink this.  */
+                 m = (opcode & (1 << 8)) != 0;
+                 a = (opcode & (1 << 9)) != 0;
+                 opcode &= ~ (3 << 8);
+                 num = evaluate_absolute (&the_insn);
+                 if ((a == 1 && num < 0) || (a == 0 && num > 0))
+                   break;
+                 if (num % 4)
+                   break;
+                 CHECK_FIELD (num, 8191, -8192, 0);
+                 if (num < 0)
+                   opcode |= 1;
+                  num &= 0x1fff;
+                  num >>= 2;
+                  INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
+               }
+             else
+               {
+                 break;
+               }
+
+           /* Handle 14 bit immediated, shifted left three times.  */
+           case '#':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 num = evaluate_absolute (&the_insn);
+                 if (num & 0x7)
+                   break;
+                 CHECK_FIELD (num, 8191, -8192, 0);
+                 if (num < 0)
+                   opcode |= 1;
+                 num &= 0x1fff;
+                 num >>= 3;
+                 INSERT_FIELD_AND_CONTINUE (opcode, num, 4);
+               }
+             else
+               {
+                 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;
+               }
+             break;
+
+           /* Handle 14 bit immediate, shifted left twice.  */
+           case 'd':
+             the_insn.field_selector = pa_chk_field_selector (&s);
+             get_expression (s);
+             s = expr_end;
+             if (the_insn.exp.X_op == O_constant)
+               {
+                 num = evaluate_absolute (&the_insn);
+                 if (num & 0x3)
+                   break;
+                 CHECK_FIELD (num, 8191, -8192, 0);
+                 if (num < 0)
+                   opcode |= 1;
+                 num &= 0x1fff;
+                 num >>= 2;
+                 INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
+               }
+             else
+               {
+                 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 14 bit immediate at 31.  */
            case 'j':
@@ -2799,7 +3055,7 @@ pa_ip (str)
                {
                  num = evaluate_absolute (&the_insn);
                  CHECK_FIELD (num, 8191, -8192, 0);
-                 low_sign_unext (num, 14, &num);
+                 num = low_sign_unext (num, 14);
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
                }
              else
@@ -2823,8 +3079,8 @@ pa_ip (str)
                {
                  num = evaluate_absolute (&the_insn);
                  CHECK_FIELD (num >> 11, 1048575, -1048576, 0);
-                 dis_assemble_21 (num, &num);
-                 INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
+                 opcode = re_assemble_21 (opcode, num);
+                 continue;
                }
              else
                {
@@ -2838,6 +3094,83 @@ 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)
+               {
+                 num = evaluate_absolute (&the_insn);
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 opcode = re_assemble_16 (opcode, num, 1);
+                 continue;
+               }
+             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)
+               {
+                 num = evaluate_absolute (&the_insn);
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 CHECK_ALIGN (num, 4, 0);
+                 opcode = re_assemble_16 (opcode, num, 1);
+                 continue;
+               }
+             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)
+               {
+                 num = evaluate_absolute (&the_insn);
+                 CHECK_FIELD (num, 32767, -32768, 0);
+                 CHECK_ALIGN (num, 8, 0);
+                 opcode = re_assemble_16 (opcode, num, 1);
+                 continue;
+               }
+             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);
@@ -2846,8 +3179,6 @@ pa_ip (str)
              the_insn.pcrel = 1;
              if (!strcmp (S_GET_NAME (the_insn.exp.X_add_symbol), "L$0\001"))
                {
-                 unsigned int w1, w, result;
-
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
                    {
@@ -2855,9 +3186,9 @@ pa_ip (str)
                      break;
                    }
                  CHECK_FIELD (num, 8199, -8184, 0);
-                 sign_unext ((num - 8) >> 2, 12, &result);
-                 dis_assemble_12 (result, &w1, &w);
-                 INSERT_FIELD_AND_CONTINUE (opcode, ((w1 << 2) | w), 0);
+                 
+                 opcode = re_assemble_12 (opcode, (num - 8) >> 2);
+                 continue;
                }
              else
                {
@@ -2879,8 +3210,6 @@ pa_ip (str)
                  || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
                              "L$0\001"))
                {
-                 unsigned int w2, w1, w, result;
-
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
                    {
@@ -2892,10 +3221,8 @@ pa_ip (str)
                  if (the_insn.exp.X_add_symbol)
                    num -= 8;
 
-                 sign_unext (num >> 2, 17, &result);
-                 dis_assemble_17 (result, &w1, &w2, &w);
-                 INSERT_FIELD_AND_CONTINUE (opcode,
-                                          ((w2 << 2) | (w1 << 16) | w), 0);
+                 opcode = re_assemble_17 (opcode, num >> 2);
+                 continue;
                }
              else
                {
@@ -2916,8 +3243,6 @@ pa_ip (str)
                  || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
                              "L$0\001"))
                {
-                 unsigned int w3, w2, w1, w, result;
-
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
                    {
@@ -2929,12 +3254,7 @@ pa_ip (str)
                  if (the_insn.exp.X_add_symbol)
                    num -= 8;
 
-                 sign_unext (num >> 2, 22, &result);
-                 dis_assemble_22 (result, &w3, &w1, &w2, &w);
-                 INSERT_FIELD_AND_CONTINUE (opcode,
-                                            ((w3 << 21) | (w2 << 2)
-                                             | (w1 << 16) | w),
-                                            0);
+                 opcode = re_assemble_22 (opcode, num >> 2);
                }
              else
                {
@@ -2955,8 +3275,6 @@ pa_ip (str)
                  || !strcmp (S_GET_NAME (the_insn.exp.X_add_symbol),
                              "L$0\001"))
                {
-                 unsigned int w2, w1, w, result;
-
                  num = evaluate_absolute (&the_insn);
                  if (num % 4)
                    {
@@ -2968,10 +3286,8 @@ pa_ip (str)
                  if (the_insn.exp.X_add_symbol)
                    num -= 8;
 
-                 sign_unext (num >> 2, 17, &result);
-                 dis_assemble_17 (result, &w1, &w2, &w);
-                 INSERT_FIELD_AND_CONTINUE (opcode,
-                                          ((w2 << 2) | (w1 << 16) | w), 0);
+                 opcode = re_assemble_17 (opcode, num >> 2);
+                 continue;
                }
              else
                {
@@ -2993,6 +3309,20 @@ pa_ip (str)
              else
                break;
 
+           /* Handle '%sr0,%r31' implicit operand of be,l instruction.  */
+           case 'Y':
+             if (strncasecmp (s, "%sr0,%r31", 9) != 0)
+               break;
+             s += 9;
+             continue;
+
+           /* Handle immediate value of 0 for ordered load/store instructions.  */
+           case '@':
+             if (*s != '0')
+               break;
+             s++;
+             continue;
+
            /* Handle a 2 bit shift count at 25.  */
            case '.':
              num = pa_get_absolute_expression (&the_insn, &s);
@@ -3075,6 +3405,20 @@ pa_ip (str)
              opcode |= (num & 0x20) << 6;
              INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5);
 
+           /* Handle a 5 bit immediate at 10 with 'd' as the complement
+              of the high bit of the immediate.  */
+           case 'B':
+             num = pa_get_absolute_expression (&the_insn, &s);
+             if (strict && the_insn.exp.X_op != O_constant)
+               break;
+             s = expr_end;
+             CHECK_FIELD (num, 63, 0, strict);
+             if (num & 0x20)
+               ;
+             else
+               opcode |= (1 << 13);
+             INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 21);
+
            /* Handle a 5 bit immediate at 10.  */
            case 'Q':
              num = pa_get_absolute_expression (&the_insn, &s);
@@ -3094,7 +3438,7 @@ pa_ip (str)
              s = expr_end;
              CHECK_FIELD (num, 511, 1, strict);
              INSERT_FIELD_AND_CONTINUE (opcode, num, 3);
-  
+
            /* Handle a 13 bit immediate at 18.  */
            case 'A':
              num = pa_get_absolute_expression (&the_insn, &s);
@@ -3217,7 +3561,7 @@ pa_ip (str)
                flag = QUAD;
              opcode |= flag << 13;
              if (the_insn.fpof1 == SGL
-                 || the_insn.fpof1 == DBL 
+                 || the_insn.fpof1 == DBL
                  || the_insn.fpof1 == QUAD)
                {
                  if (the_insn.fpof2 == SGL
@@ -3236,7 +3580,7 @@ pa_ip (str)
                    abort ();
                }
              else if (the_insn.fpof1 == W
-                      || the_insn.fpof1 == DW 
+                      || the_insn.fpof1 == DW
                       || the_insn.fpof1 == QW)
                {
                  if (the_insn.fpof2 == SGL
@@ -3247,7 +3591,7 @@ pa_ip (str)
                    abort ();
                }
              else if (the_insn.fpof1 == UW
-                      || the_insn.fpof1 == UDW 
+                      || the_insn.fpof1 == UDW
                       || the_insn.fpof1 == UQW)
                {
                  if (the_insn.fpof2 == SGL
@@ -3407,7 +3751,6 @@ pa_ip (str)
                case 'C':
                  {
                    struct pa_11_fp_reg_struct result;
-                   int regnum;
 
                    /* This should be more strict.  Small steps.  */
                    if (strict && *s != '%')
@@ -3448,7 +3791,7 @@ pa_ip (str)
                case 'j':
                  {
                    struct pa_11_fp_reg_struct result;
-                 
+
                    /* This should be more strict.  Small steps.  */
                    if (strict && *s != '%')
                      break;
@@ -3471,7 +3814,7 @@ pa_ip (str)
                case 'k':
                  {
                    struct pa_11_fp_reg_struct result;
-                 
+
                    /* This should be more strict.  Small steps.  */
                    if (strict && *s != '%')
                      break;
@@ -3494,7 +3837,7 @@ pa_ip (str)
                case 'l':
                  {
                    struct pa_11_fp_reg_struct result;
-                 
+
                    /* This should be more strict.  Small steps.  */
                    if (strict && *s != '%')
                      break;
@@ -3517,7 +3860,7 @@ pa_ip (str)
                case 'm':
                  {
                    struct pa_11_fp_reg_struct result;
-                 
+
                    /* This should be more strict.  Small steps.  */
                    if (strict && *s != '%')
                      break;
@@ -3536,29 +3879,38 @@ pa_ip (str)
                    INSERT_FIELD_AND_CONTINUE (opcode, result.number_part, 11);
                  }
 
+               /* Handle L/R register halves like 'x'.  */
+               case 'E':
+               case 'e':
+                 {
+                   struct pa_11_fp_reg_struct result;
+
+                   if (strict && *s != '%')
+                     break;
+                   pa_parse_number (&s, &result);
+                   CHECK_FIELD (result.number_part, 31, 0, 0);
+                   opcode |= (result.number_part & 0x1f) << 16;
+                   if (need_pa11_opcode (&the_insn, &result))
+                     {
+                       opcode |= (result.l_r_select & 1) << 1;
+                     }
+                   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 ();
                }
              break;
 
-           /* Handle L/R register halves like 'x'.  */
-           case 'e':
-             {
-               struct pa_11_fp_reg_struct result;
-
-               /* This should be more strict.  Small steps.  */
-               if (strict && *s != '%')
-                 break;
-               pa_parse_number (&s, &result);
-               CHECK_FIELD (result.number_part, 31, 0, 0);
-               opcode |= (result.number_part & 0x1f) << 16;
-               if (need_pa11_opcode (&the_insn, &result))
-                 {
-                   opcode |= (result.l_r_select & 1) << 1;
-                 }
-               continue;
-             }
-
            default:
              abort ();
            }
@@ -3862,8 +4214,8 @@ tc_gen_reloc (section, fixp)
 
 void
 md_convert_frag (abfd, sec, fragP)
-     register bfd *abfd;
-     register asection *sec;
+     register bfd *abfd ATTRIBUTE_UNUSED;
+     register asection *sec ATTRIBUTE_UNUSED;
      register fragS *fragP;
 {
   unsigned int address;
@@ -3908,7 +4260,7 @@ md_section_align (segment, size)
 int
 md_estimate_size_before_relax (fragP, segment)
      register fragS *fragP;
-     asection *segment;
+     asection *segment ATTRIBUTE_UNUSED;
 {
   int size;
 
@@ -3928,15 +4280,15 @@ size_t md_longopts_size = sizeof(md_longopts);
 
 int
 md_parse_option (c, arg)
-     int c;
-     char *arg;
+     int c ATTRIBUTE_UNUSED;
+     char *arg ATTRIBUTE_UNUSED;
 {
   return 0;
 }
 
 void
 md_show_usage (stream)
-     FILE *stream;
+     FILE *stream ATTRIBUTE_UNUSED;
 {
 }
 \f
@@ -3944,7 +4296,7 @@ md_show_usage (stream)
 
 symbolS *
 md_undefined_symbol (name)
-     char *name;
+     char *name ATTRIBUTE_UNUSED;
 {
   return 0;
 }
@@ -3958,8 +4310,8 @@ md_apply_fix (fixP, valp)
 {
   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   struct hppa_fix_struct *hppa_fixP;
-  long new_val, result = 0;
-  unsigned int w1, w2, w, resulti;
+  offsetT new_val;
+  unsigned int insn, val;
 
   hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
   /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
@@ -3988,7 +4340,7 @@ md_apply_fix (fixP, valp)
   if (hppa_fixP)
     {
       unsigned long buf_wd = bfd_get_32 (stdoutput, buf);
-      unsigned char fmt = bfd_hppa_insn2fmt (buf_wd);
+      int fmt = bfd_hppa_insn2fmt (buf_wd);
 
       /* If there is a symbol associated with this fixup, then it's something
         which will need a SOM relocation (except for some PC-relative relocs).
@@ -4039,109 +4391,93 @@ md_apply_fix (fixP, valp)
              
        new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
 #undef arg_reloc_stub_needed
-       
+
+      insn = bfd_get_32 (stdoutput, buf);
       switch (fmt)
        {
+       case 10:
+         CHECK_FIELD (new_val, 8191, -8192, 0);
+         val = new_val;
+
+         insn = (insn & ~ 0x3ff1) | (((val & 0x1ff8) << 1)
+                                     | ((val & 0x2000) >> 13));
+         break;
+       case -11:
+         CHECK_FIELD (new_val, 8191, -8192, 0);
+         val = new_val;
+
+         insn = (insn & ~ 0x3ff9) | (((val & 0x1ffc) << 1)
+                                     | ((val & 0x2000) >> 13));
+         break;
        /* Handle all opcodes with the 'j' operand type.  */
        case 14:
          CHECK_FIELD (new_val, 8191, -8192, 0);
+         val = new_val;
 
-         /* Mask off 14 bits to be changed.  */
-         bfd_put_32 (stdoutput,
-                     bfd_get_32 (stdoutput, buf) & 0xffffc000,
-                     buf);
-         low_sign_unext (new_val, 14, &resulti);
-         result = resulti;
+         insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
          break;
 
        /* Handle all opcodes with the 'k' operand type.  */
        case 21:
-         CHECK_FIELD (new_val, 2097152, 0, 0);
-
-         /* Mask off 21 bits to be changed.  */
-         bfd_put_32 (stdoutput,
-                     bfd_get_32 (stdoutput, buf) & 0xffe00000,
-                     buf);
-         dis_assemble_21 (new_val, &resulti);
-         result = resulti;
+         CHECK_FIELD (new_val, 1048576, -1048576, 0);
+         val = new_val;
+
+         insn = re_assemble_21 (insn, val);
          break;
 
        /* Handle all the opcodes with the 'i' operand type.  */
        case 11:
          CHECK_FIELD (new_val, 1023, -1023, 0);
+         val = new_val;
 
-         /* Mask off 11 bits to be changed.  */
-         bfd_put_32 (stdoutput,
-                     bfd_get_32 (stdoutput, buf) & 0xffff800,
-                     buf);
-         low_sign_unext (new_val, 11, &resulti);
-         result = resulti;
+         insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
          break;
 
        /* Handle all the opcodes with the 'w' operand type.  */
        case 12:
          CHECK_FIELD (new_val, 8199, -8184, 0);
+         val = new_val;
 
-         /* Mask off 11 bits to be changed.  */
-         sign_unext ((new_val - 8) >> 2, 12, &resulti);
-         bfd_put_32 (stdoutput,
-                     bfd_get_32 (stdoutput, buf) & 0xffffe002,
-                     buf);
-
-         dis_assemble_12 (resulti, &w1, &w);
-         result = ((w1 << 2) | w);
+         insn = re_assemble_12 (insn, (val - 8) >> 2);
          break;
 
        /* Handle some of the opcodes with the 'W' operand type.  */
        case 17:
          {
-           int distance = *valp;
-
-           CHECK_FIELD (new_val, 262143, -262144, 0);
+           offsetT distance = *valp;
 
            /* If this is an absolute branch (ie no link) with an out of
               range target, then we want to complain.  */
            if (fixP->fx_r_type == R_HPPA_PCREL_CALL
-               && (distance > 262143 || distance < -262144)
-               && (bfd_get_32 (stdoutput, buf) & 0xffe00000) == 0xe8000000)
+               && (insn & 0xffe00000) == 0xe8000000)
              CHECK_FIELD (distance, 262143, -262144, 0);
 
-           /* Mask off 17 bits to be changed.  */
-           bfd_put_32 (stdoutput,
-                       bfd_get_32 (stdoutput, buf) & 0xffe0e002,
-                       buf);
-           sign_unext ((new_val - 8) >> 2, 17, &resulti);
-           dis_assemble_17 (resulti, &w1, &w2, &w);
-           result = ((w2 << 2) | (w1 << 16) | w);
+           CHECK_FIELD (new_val, 262143, -262144, 0);
+           val = new_val;
+
+           insn = re_assemble_17 (insn, (val - 8) >> 2);
            break;
          }
 
        case 22:
          {
-           int distance = *valp, w3;
-
-           CHECK_FIELD (new_val, 8388607, -8388608, 0);
+           offsetT distance = *valp;
 
            /* If this is an absolute branch (ie no link) with an out of
               range target, then we want to complain.  */
            if (fixP->fx_r_type == R_HPPA_PCREL_CALL
-               && (distance > 8388607 || distance < -8388608)
-               && (bfd_get_32 (stdoutput, buf) & 0xffe00000) == 0xe8000000)
+               && (insn & 0xffe00000) == 0xe8000000)
              CHECK_FIELD (distance, 8388607, -8388608, 0);
 
-           /* Mask off 22 bits to be changed.  */
-           bfd_put_32 (stdoutput,
-                       bfd_get_32 (stdoutput, buf) & 0xfc00e002,
-                       buf);
-           sign_unext ((new_val - 8) >> 2, 22, &resulti);
-           dis_assemble_22 (resulti, &w3, &w1, &w2, &w);
-           result = ((w3 << 21) | (w2 << 2) | (w1 << 16) | w);
+           CHECK_FIELD (new_val, 8388607, -8388608, 0);
+           val = new_val;
+
+           insn = re_assemble_22 (insn, (val - 8) >> 2);
            break;
          }
 
        case 32:
-         result = 0;
-         bfd_put_32 (stdoutput, new_val, buf);
+         insn = new_val;
          break;
 
        default:
@@ -4150,7 +4486,7 @@ md_apply_fix (fixP, valp)
        }
 
       /* Insert the relocation.  */
-      bfd_put_32 (stdoutput, bfd_get_32 (stdoutput, buf) | result, buf);
+      bfd_put_32 (stdoutput, insn, buf);
       return 1;
     }
   else
@@ -4799,70 +5135,14 @@ static int
 evaluate_absolute (insn)
      struct pa_it *insn;
 {
-  int value;
+  offsetT value;
   expressionS exp;
   int field_selector = insn->field_selector;
 
   exp = insn->exp;
   value = exp.X_add_number;
 
-  switch (field_selector)
-    {
-    /* No change.  */
-    case e_fsel:
-      break;
-
-    /* If bit 21 is on then add 0x800 and arithmetic shift right 11 bits.  */
-    case e_lssel:
-      if (value & 0x00000400)
-       value += 0x800;
-      value = (value & 0xfffff800) >> 11;
-      break;
-
-    /* Sign extend from bit 21.  */
-    case e_rssel:
-      if (value & 0x00000400)
-       value |= 0xfffff800;
-      else
-       value &= 0x7ff;
-      break;
-
-    /* Arithmetic shift right 11 bits.  */
-    case e_lsel:
-      value = (value & 0xfffff800) >> 11;
-      break;
-
-    /* Set bits 0-20 to zero.  */
-    case e_rsel:
-      value = value & 0x7ff;
-      break;
-
-    /* Add 0x800 and arithmetic shift right 11 bits.  */
-    case e_ldsel:
-      value += 0x800;
-      value = (value & 0xfffff800) >> 11;
-      break;
-
-    /* Set bitgs 0-21 to one.  */
-    case e_rdsel:
-      value |= 0xfffff800;
-      break;
-
-#define RSEL_ROUND(c)  (((c) + 0x1000) & ~0x1fff)
-    case e_rrsel:
-      value = (RSEL_ROUND (value) & 0x7ff) + (value - RSEL_ROUND (value));
-      break;
-
-    case e_lrsel:
-      value = (RSEL_ROUND (value) >> 11) & 0x1fffff;
-      break;
-#undef RSEL_ROUND
-
-    default:
-      BAD_CASE (field_selector);
-      break;
-    }
-  return value;
+  return hppa_field_adjust (0, value, field_selector);
 }
 
 /* Given an argument location specification return the associated
@@ -5106,6 +5386,167 @@ pa_parse_neg_cmpsub_cmpltr (s, isbranch)
 }
 
 
+/* Parse a 64 bit compare and branch completer returning the number (for
+   encoding in instrutions) of the given completer.
+
+   Nonnegated comparisons are returned as 0-7, negated comparisons are
+   returned as 8-15.  */
+
+static int
+pa_parse_cmpb_64_cmpltr (s)
+     char **s;
+{
+  int cmpltr;
+  char *name = *s + 1;
+  char c;
+
+  cmpltr = -1;
+  if (**s == ',')
+    {
+      *s += 1;
+      while (**s != ',' && **s != ' ' && **s != '\t')
+       *s += 1;
+      c = **s;
+      **s = 0x00;
+
+      if (strcmp (name, "*") == 0)
+       {
+         cmpltr = 0;
+       }
+      else if (strcmp (name, "*=") == 0)
+       {
+         cmpltr = 1;
+       }
+      else if (strcmp (name, "*<") == 0)
+       {
+         cmpltr = 2;
+       }
+      else if (strcmp (name, "*<=") == 0)
+       {
+         cmpltr = 3;
+       }
+      else if (strcmp (name, "*<<") == 0)
+       {
+         cmpltr = 4;
+       }
+      else if (strcmp (name, "*<<=") == 0)
+       {
+         cmpltr = 5;
+       }
+      else if (strcasecmp (name, "*sv") == 0)
+       {
+         cmpltr = 6;
+       }
+      else if (strcasecmp (name, "*od") == 0)
+       {
+         cmpltr = 7;
+       }
+      else if (strcasecmp (name, "*tr") == 0)
+       {
+         cmpltr = 8;
+       }
+      else if (strcmp (name, "*<>") == 0)
+       {
+         cmpltr = 9;
+       }
+      else if (strcmp (name, "*>=") == 0)
+       {
+         cmpltr = 10;
+       }
+      else if (strcmp (name, "*>") == 0)
+       {
+         cmpltr = 11;
+       }
+      else if (strcmp (name, "*>>=") == 0)
+       {
+         cmpltr = 12;
+       }
+      else if (strcmp (name, "*>>") == 0)
+       {
+         cmpltr = 13;
+       }
+      else if (strcasecmp (name, "*nsv") == 0)
+       {
+         cmpltr = 14;
+       }
+      else if (strcasecmp (name, "*ev") == 0)
+       {
+         cmpltr = 15;
+       }
+      else
+       {
+         cmpltr = -1;
+       }
+      **s = c;
+    }
+
+
+  return cmpltr;
+}
+
+/* Parse a 64 bit compare immediate and branch completer returning the number
+   (for encoding in instrutions) of the given completer.  */
+
+static int
+pa_parse_cmpib_64_cmpltr (s)
+     char **s;
+{
+  int cmpltr;
+  char *name = *s + 1;
+  char c;
+
+  cmpltr = -1;
+  if (**s == ',')
+    {
+      *s += 1;
+      while (**s != ',' && **s != ' ' && **s != '\t')
+       *s += 1;
+      c = **s;
+      **s = 0x00;
+
+      if (strcmp (name, "*<<") == 0)
+       {
+         cmpltr = 0;
+       }
+      else if (strcmp (name, "*=") == 0)
+       {
+         cmpltr = 1;
+       }
+      else if (strcmp (name, "*<") == 0)
+       {
+         cmpltr = 2;
+       }
+      else if (strcmp (name, "*<=") == 0)
+       {
+         cmpltr = 3;
+       }
+      else if (strcmp (name, "*>>=") == 0)
+       {
+         cmpltr = 4;
+       }
+      else if (strcmp (name, "*<>") == 0)
+       {
+         cmpltr = 5;
+       }
+      else if (strcasecmp (name, "*>=") == 0)
+       {
+         cmpltr = 6;
+       }
+      else if (strcasecmp (name, "*>") == 0)
+       {
+         cmpltr = 7;
+       }
+      else
+       {
+         cmpltr = -1;
+       }
+      **s = c;
+    }
+
+
+  return cmpltr;
+}
+
 /* Parse a non-negated addition completer returning the number
    (for encoding in instrutions) of the given completer.
 
@@ -5256,6 +5697,108 @@ pa_parse_neg_add_cmpltr (s, isbranch)
   return cmpltr;
 }
 
+/* Parse a 64 bit wide mode add and branch completer returning the number (for
+   encoding in instrutions) of the given completer.  */
+
+static int
+pa_parse_addb_64_cmpltr (s)
+     char **s;
+{
+  int cmpltr;
+  char *name = *s + 1;
+  char c;
+  char *save_s = *s;
+  int nullify = 0;
+
+  cmpltr = 0;
+  if (**s == ',')
+    {
+      *s += 1;
+      while (**s != ',' && **s != ' ' && **s != '\t')
+       *s += 1;
+      c = **s;
+      **s = 0x00;
+      if (strcmp (name, "=") == 0)
+       {
+         cmpltr = 1;
+       }
+      else if (strcmp (name, "<") == 0)
+       {
+         cmpltr = 2;
+       }
+      else if (strcmp (name, "<=") == 0)
+       {
+         cmpltr = 3;
+       }
+      else if (strcasecmp (name, "nuv") == 0)
+       {
+         cmpltr = 4;
+       }
+      else if (strcasecmp (name, "*=") == 0)
+       {
+         cmpltr = 5;
+       }
+      else if (strcasecmp (name, "*<") == 0)
+       {
+         cmpltr = 6;
+       }
+      else if (strcasecmp (name, "*<=") == 0)
+       {
+         cmpltr = 7;
+       }
+      else if (strcmp (name, "tr") == 0)
+       {
+         cmpltr = 8;
+       }
+      else if (strcmp (name, "<>") == 0)
+       {
+         cmpltr = 9;
+       }
+      else if (strcmp (name, ">=") == 0)
+       {
+         cmpltr = 10;
+       }
+      else if (strcmp (name, ">") == 0)
+       {
+         cmpltr = 11;
+       }
+      else if (strcasecmp (name, "uv") == 0)
+       {
+         cmpltr = 12;
+       }
+      else if (strcasecmp (name, "*<>") == 0)
+       {
+         cmpltr = 13;
+       }
+      else if (strcasecmp (name, "*>=") == 0)
+       {
+         cmpltr = 14;
+       }
+      else if (strcasecmp (name, "*>") == 0)
+       {
+         cmpltr = 15;
+       }
+      /* If we have something like addb,n then there is no condition
+         completer.  */
+      else if (strcasecmp (name, "n") == 0)
+       {
+         cmpltr = 0;
+         nullify = 1;
+       }
+      else
+       {
+         cmpltr = -1;
+       }
+      **s = c;
+    }
+
+  /* Reset pointers if this was really a ,n for a branch instruction.  */
+  if (nullify)
+    *s = save_s;
+
+  return cmpltr;
+}
+
 #ifdef OBJ_SOM
 /* Handle an alignment directive.  Special so that we can update the
    alignment of the subspace if necessary.  */
@@ -5279,7 +5822,7 @@ pa_align (bytes)
 
 static void
 pa_block (z)
-     int z;
+     int z ATTRIBUTE_UNUSED;
 {
   char *p;
   long int temp_fill;
@@ -5317,7 +5860,7 @@ pa_block (z)
 
 static void
 pa_brtab (begin)
-     int begin;
+     int begin ATTRIBUTE_UNUSED;
 {
 
 #ifdef OBJ_SOM
@@ -5338,7 +5881,7 @@ pa_brtab (begin)
 
 static void
 pa_try (begin)
-     int begin;
+     int begin ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   expressionS exp;
@@ -5365,7 +5908,7 @@ pa_try (begin)
 
 static void
 pa_call (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -5456,9 +5999,9 @@ pa_build_unwind_subspace (call_info)
 {
   char *unwind;
   asection *seg, *save_seg;
-  asymbol *sym;
-  subsegT subseg, save_subseg;
-  int i, reloc;
+  subsegT save_subseg;
+  unsigned int i;
+  int reloc;
   char c, *p;
 
   if (now_seg != text_section)
@@ -5468,22 +6011,22 @@ pa_build_unwind_subspace (call_info)
     reloc = R_PARISC_DIR32;
   else
     reloc = R_PARISC_SEGREL32;
-    
+
+  save_seg = now_seg;
+  save_subseg = now_subseg;
   /* Get into the right seg/subseg.  This may involve creating
      the seg the first time through.  Make sure to have the
      old seg/subseg so that we can reset things when we are done.  */
   seg = bfd_get_section_by_name (stdoutput, UNWIND_SECTION_NAME);
   if (seg == ASEC_NULL)
     {
-      seg = bfd_make_section_old_way (stdoutput, UNWIND_SECTION_NAME);
+      seg = subseg_new (UNWIND_SECTION_NAME, 0);
       bfd_set_section_flags (stdoutput, seg,
                             SEC_READONLY | SEC_HAS_CONTENTS
                             | SEC_LOAD | SEC_RELOC | SEC_ALLOC | SEC_DATA);
       bfd_set_section_alignment (stdoutput, seg, 2);
     }
 
-  save_seg = now_seg;
-  save_subseg = now_subseg;
   subseg_set (seg, 0);
 
 
@@ -5535,7 +6078,7 @@ pa_build_unwind_subspace (call_info)
 
 static void
 pa_callinfo (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *name, c, *p;
   int temp;
@@ -5678,7 +6221,7 @@ pa_callinfo (unused)
 
 static void
 pa_code (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   current_space = is_defined_space ("$TEXT$");
@@ -5711,7 +6254,7 @@ pa_code (unused)
 
 static void
 pa_comm (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   unsigned int size;
   symbolS *symbol;
@@ -5743,7 +6286,7 @@ pa_comm (unused)
 
 static void
 pa_end (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   demand_empty_rest_of_line ();
 }
@@ -5751,7 +6294,7 @@ pa_end (unused)
 /* Process a .ENTER pseudo-op.  This is not supported.  */
 static void
 pa_enter (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -5766,7 +6309,7 @@ pa_enter (unused)
    procesure.  */
 static void
 pa_entry (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -5873,7 +6416,7 @@ process_exit ()
 
 static void
 pa_exit (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -5906,7 +6449,7 @@ pa_exit (unused)
 
 static void
 pa_export (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *name, c, *p;
   symbolS *symbol;
@@ -5947,7 +6490,9 @@ pa_type_args (symbolP, is_export)
   char *name, c, *p;
   unsigned int temp, arg_reloc;
   pa_symbol_type type = SYMBOL_TYPE_UNKNOWN;
+#ifdef OBJ_SOM
   obj_symbol_type *symbol = (obj_symbol_type *) symbol_get_bfdsym (symbolP);
+#endif
 
   if (strncasecmp (input_line_pointer, "absolute", 8) == 0)
 
@@ -6093,7 +6638,7 @@ pa_type_args (symbolP, is_export)
 
 static void
 pa_import (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *name, c, *p;
   symbolS *symbol;
@@ -6145,7 +6690,7 @@ pa_import (unused)
 
 static void
 pa_label (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *name, c, *p;
 
@@ -6175,7 +6720,7 @@ pa_label (unused)
 
 static void
 pa_leave (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -6190,7 +6735,7 @@ pa_leave (unused)
 
 static void
 pa_level (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *level;
 
@@ -6231,7 +6776,7 @@ pa_level (unused)
 
 static void
 pa_origin (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -6247,7 +6792,7 @@ pa_origin (unused)
 
 static void
 pa_param (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *name, c, *p;
   symbolS *symbol;
@@ -6282,7 +6827,7 @@ pa_param (unused)
 
 static void
 pa_proc (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   struct call_info *call_info;
 
@@ -6352,7 +6897,7 @@ pa_proc (unused)
 
 static void
 pa_procend (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 
 #ifdef OBJ_SOM
@@ -6419,6 +6964,8 @@ pa_procend (unused)
   pa_undefine_label ();
 }
 
+
+#ifdef OBJ_SOM
 /* If VALUE is an exact power of two between zero and 2^31, then
    return log2 (VALUE).  Else return -1.  */
 
@@ -6437,8 +6984,6 @@ log2 (value)
     return shift;
 }
 
-
-#ifdef OBJ_SOM
 /* Check to make sure we have a valid space and subspace.  */
 
 static void
@@ -6578,7 +7123,7 @@ pa_parse_space_stmt (space_name, create_flag)
 
 static void
 pa_space (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *name, c, *space_name, *save_s;
   int temp;
@@ -6697,7 +7242,7 @@ pa_space (unused)
 
 static void
 pa_spnum (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   char *name;
   char c;
@@ -7537,7 +8082,7 @@ pa_stringer (append_zero)
 
 static void
 pa_version (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   obj_version (0);
   pa_undefine_label ();
@@ -7549,7 +8094,7 @@ pa_version (unused)
 
 static void
 pa_compiler (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   obj_som_compiler (0);
   pa_undefine_label ();
@@ -7561,7 +8106,7 @@ pa_compiler (unused)
 
 static void
 pa_copyright (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
   obj_copyright (0);
   pa_undefine_label ();
@@ -7582,7 +8127,7 @@ pa_cons (nbytes)
 
 static void
 pa_data (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   current_space = is_defined_space ("$PRIVATE$");
@@ -7607,7 +8152,7 @@ pa_float_cons (float_type)
 
 static void
 pa_fill (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -7637,7 +8182,7 @@ pa_lcomm (needs_align)
 
 static void
 pa_lsym (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   /* We must have a valid space and subspace.  */
@@ -7652,7 +8197,7 @@ pa_lsym (unused)
    label when finished.  */
 static void
 pa_text (unused)
-     int unused;
+     int unused ATTRIBUTE_UNUSED;
 {
 #ifdef OBJ_SOM
   current_space = is_defined_space ("$TEXT$");
@@ -7683,7 +8228,7 @@ pa_text (unused)
    selectors).
 
    Reject reductions involving symbols with external scope; such
-   reductions make life a living hell for object file editors. 
+   reductions make life a living hell for object file editors.
 
    FIXME.  Also reject R_HPPA relocations which are 32bits wide in
    the code space.  The SOM BFD backend doesn't know how to pull the
@@ -7703,7 +8248,7 @@ hppa_fix_adjustable (fixp)
     return 0;
 
   /* Reject reductions of symbols in sym1-sym2 expressions when
-     the fixup will occur in a CODE subspace. 
+     the fixup will occur in a CODE subspace.
 
      XXX FIXME: Long term we probably want to reject all of these;
      for example reducing in the debug section would lose if we ever
@@ -7881,7 +8426,7 @@ elf_hppa_final_processing ()
 #endif
 
 #ifdef OBJ_ELF
-pa_end_of_source ()
+void pa_end_of_source ()
 {
   if (debug_type == DEBUG_DWARF2)
     dwarf2_finish ();
This page took 0.086161 seconds and 4 git commands to generate.