2000-12-03 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / gas / config / tc-hppa.c
index f74f6b852b9525ad1a5c148b7d500ab2f0d30720..2f889b284d5cdbb04b494c03499d777fe3ddf4ee 100644 (file)
@@ -19,7 +19,6 @@
    Software Foundation, 59 Temple Place - Suite 330, Boston, MA
    02111-1307, USA.  */
 
-
 /* HP PA-RISC support was contributed by the Center for Software Science
    at the University of Utah.  */
 
@@ -43,7 +42,6 @@ error only one of OBJ_ELF and OBJ_SOM can be defined
    then we want to use the assembler support for compact line numbers.  */
 #ifdef OBJ_ELF
 #include "dwarf2dbg.h"
-struct dwarf2_line_info debug_line;
 
 /* A "convient" place to put object file dependencies which do
    not need to be seen outside of tc-hppa.c.  */
@@ -232,7 +230,6 @@ struct pa_it
 
 /* PA-89 floating point registers are arranged like this:
 
-
    +--------------+--------------+
    |   0 or 16L   |  16 or 16R   |
    +--------------+--------------+
@@ -696,7 +693,7 @@ const pseudo_typeS md_pseudo_table[] =
    first line of the input file.  This is because the compiler outputs
    #NO_APP at the beginning of its output.
 
-   Also note that C style comments will always work. */
+   Also note that C style comments will always work.  */
 const char line_comment_chars[] = "#";
 
 /* This array holds the chars that always start a comment.  If the
@@ -787,7 +784,7 @@ static int print_errors = 1;
    Almost every control register has a synonym; they are not listed
    here for brevity.
 
-   The table is sorted. Suitable for searching by a binary search. */
+   The table is sorted. Suitable for searching by a binary search.  */
 
 static const struct pd_reg pre_defined_registers[] =
 {
@@ -1260,7 +1257,6 @@ pa_undefine_label ()
     }
 }
 
-
 /* An HPPA-specific version of fix_new.  This is required because the HPPA
    code needs to keep track of some extra stuff.  Each call to fix_new_hppa
    results in the creation of an instance of an hppa_fix_struct.  An
@@ -1424,7 +1420,7 @@ md_begin ()
 #ifdef OBJ_SOM
   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. */
+  /* Force the symbol to be converted to a real symbol.  */
   (void) symbol_get_bfdsym (dummy_symbol);
 #endif
 }
@@ -1484,7 +1480,7 @@ md_assemble (str)
   /* Get somewhere to put the assembled instrution.  */
   to = frag_more (4);
 
-  /* Output the opcode. */
+  /* Output the opcode.  */
   md_number_to_chars (to, the_insn.opcode, 4);
 
   /* If necessary output more stuff.  */
@@ -1495,20 +1491,7 @@ md_assemble (str)
                  the_insn.format, the_insn.arg_reloc, NULL);
 
 #ifdef OBJ_ELF
-  if (debug_type == DEBUG_DWARF2)
-    {
-      bfd_vma addr;
-
-      /* First update the notion of the current source line.  */
-      dwarf2_where (&debug_line);
-
-      /* We want the offset of the start of this instruction within the
-        the current frag.  */
-      addr = frag_now->fr_address + frag_now_fix () - 4;
-
-      /* And record the information.  */
-      dwarf2_gen_line_info (addr, &debug_line);
-    }
+  dwarf2_emit_insn (4);
 #endif
 }
 
@@ -1948,7 +1931,7 @@ pa_ip (str)
                    }
                  INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 10);
 
-               /* Handle load ordering completer. */
+               /* Handle load ordering completer.  */
                case 'o':
                  if (strncmp(s, ",o", 2) != 0)
                    break;
@@ -2408,7 +2391,7 @@ pa_ip (str)
                      }
                    else
                      {
-                       /* Negated condition requires an opcode change. */
+                       /* Negated condition requires an opcode change.  */
                        opcode |= (cmpltr & 8) << 24;
                      }
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
@@ -2429,7 +2412,7 @@ pa_ip (str)
                          }
                        else
                          {
-                           /* Negated condition requires an opcode change. */
+                           /* Negated condition requires an opcode change.  */
                            opcode |= 1 << 27;
                          }
                      }
@@ -2582,7 +2565,7 @@ pa_ip (str)
                          }
                        else
                          {
-                           /* Negated condition requires an opcode change. */
+                           /* Negated condition requires an opcode change.  */
                            opcode |= 1 << 27;
                          }
                      }
@@ -2594,11 +2577,11 @@ pa_ip (str)
                    cmpltr = pa_parse_cmpb_64_cmpltr (&s);
                    if (cmpltr >= 0)
                      {
-                       /* Negated condition requires an opcode change. */
+                       /* Negated condition requires an opcode change.  */
                        opcode |= (cmpltr & 8) << 26;
                      }
                    else
-                     /* Not a 64 bit cond.  Give 32 bit a chance. */
+                     /* Not a 64 bit cond.  Give 32 bit a chance.  */
                      break;
 
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr & 7, 13);
@@ -2607,7 +2590,7 @@ pa_ip (str)
                  case 'Q':
                    cmpltr = pa_parse_cmpib_64_cmpltr (&s);
                    if (cmpltr < 0)
-                     /* Not a 64 bit cond.  Give 32 bit a chance. */
+                     /* Not a 64 bit cond.  Give 32 bit a chance.  */
                      break;
 
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
@@ -3192,7 +3175,7 @@ pa_ip (str)
                      break;
                    }
                  CHECK_FIELD (num, 8199, -8184, 0);
-                 
+
                  opcode |= re_assemble_12 ((num - 8) >> 2);
                  continue;
                }
@@ -4014,7 +3997,10 @@ tc_gen_reloc (section, fixp)
                               symbol_get_bfdsym (fixp->fx_addsy));
 
   if (codes == NULL)
-    abort ();
+    {
+      as_bad (_("Cannot handle fixup at %s:%d"), fixp->fx_file, fixp->fx_line);
+      abort ();
+    }
 
   for (n_relocs = 0; codes[n_relocs]; n_relocs++)
     ;
@@ -4226,7 +4212,7 @@ md_convert_frag (abfd, sec, fragP)
     }
 }
 
-/* Round up a section size to the appropriate boundary. */
+/* Round up a section size to the appropriate boundary.  */
 
 valueT
 md_section_align (segment, size)
@@ -4275,7 +4261,7 @@ struct option md_longopts[] = {
 #endif
   {NULL, no_argument, NULL, 0}
 };
-size_t md_longopts_size = sizeof(md_longopts);
+size_t md_longopts_size = sizeof (md_longopts);
 
 int
 md_parse_option (c, arg)
@@ -4326,8 +4312,10 @@ md_undefined_symbol (name)
 }
 
 #if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
+#define nonzero_dibits(x) \
+  ((x) | (((x) & 0x55555555) << 1) | (((x) & 0xAAAAAAAA) >> 1))
 #define arg_reloc_stub_needed(CALLER, CALLEE) \
-  ((CALLEE) && (CALLER) && ((CALLEE) != (CALLER)))
+  (((CALLER) ^ (CALLEE)) & nonzero_dibits (CALLER) & nonzero_dibits (CALLEE))
 #else
 #define arg_reloc_stub_needed(CALLER, CALLEE) 0
 #endif
@@ -4339,12 +4327,11 @@ md_apply_fix (fixP, valp)
      fixS *fixP;
      valueT *valp;
 {
-  char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
+  unsigned char *buf;
   struct hppa_fix_struct *hppa_fixP;
   offsetT new_val;
-  int insn, val;
+  int insn, val, fmt;
 
-  hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
   /* SOM uses R_HPPA_ENTRY and R_HPPA_EXIT relocations which can
      never be "applied" (they are just markers).  Likewise for
      R_HPPA_BEGIN_BRTAB and R_HPPA_END_BRTAB.  */
@@ -4371,177 +4358,185 @@ md_apply_fix (fixP, valp)
     return 1;
 #endif
 
-  insn = bfd_get_32 (stdoutput, (unsigned char *) buf);
   /* There should have been an HPPA specific fixup associated
      with the GAS fixup.  */
-  if (hppa_fixP)
+  hppa_fixP = (struct hppa_fix_struct *) fixP->tc_fix_data;
+  if (hppa_fixP == NULL)
     {
-      int fmt = bfd_hppa_insn2fmt (stdoutput, insn);
-
-      /* 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).
-        In such cases we should treat the "val" or "addend" as zero since it
-        will be added in as needed from fx_offset in tc_gen_reloc.  */
-      if ((fixP->fx_addsy != NULL
-          || fixP->fx_r_type == (int) R_HPPA_NONE)
+      printf (_("no hppa_fixup entry for fixup type 0x%x at %s:%d"),
+             fixP->fx_r_type, fixP->fx_file, fixP->fx_line);
+      return 0;
+    }
+
+  buf = fixP->fx_frag->fr_literal + fixP->fx_where;
+  insn = bfd_get_32 (stdoutput, buf);
+  fmt = bfd_hppa_insn2fmt (stdoutput, insn);
+
+  /* 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).
+     In such cases we should treat the "val" or "addend" as zero since it
+     will be added in as needed from fx_offset in tc_gen_reloc.  */
+  if ((fixP->fx_addsy != NULL
+       || fixP->fx_r_type == (int) R_HPPA_NONE)
 #ifdef OBJ_SOM
-         && fmt != 32
+      && fmt != 32
 #endif
-         )
-       new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
+      )
+    new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
 #ifdef OBJ_SOM
-      /* These field selectors imply that we do not want an addend.  */
-      else if (hppa_fixP->fx_r_field == e_psel
-              || hppa_fixP->fx_r_field == e_rpsel
-              || hppa_fixP->fx_r_field == e_lpsel
-              || hppa_fixP->fx_r_field == e_tsel
-              || hppa_fixP->fx_r_field == e_rtsel
-              || hppa_fixP->fx_r_field == e_ltsel)
-       new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
-      /* This is truely disgusting.  The machine independent code blindly
-        adds in the value of the symbol being relocated against.  Damn!  */
-      else if (fmt == 32
-              && fixP->fx_addsy != NULL
-              && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr)
-       new_val = hppa_field_adjust (*valp - S_GET_VALUE (fixP->fx_addsy),
-                                    0, hppa_fixP->fx_r_field);
+  /* These field selectors imply that we do not want an addend.  */
+  else if (hppa_fixP->fx_r_field == e_psel
+          || hppa_fixP->fx_r_field == e_rpsel
+          || hppa_fixP->fx_r_field == e_lpsel
+          || hppa_fixP->fx_r_field == e_tsel
+          || hppa_fixP->fx_r_field == e_rtsel
+          || hppa_fixP->fx_r_field == e_ltsel)
+    new_val = ((fmt == 12 || fmt == 17 || fmt == 22) ? 8 : 0);
+  /* This is truly disgusting.  The machine independent code blindly
+     adds in the value of the symbol being relocated against.  Damn!  */
+  else if (fmt == 32
+          && fixP->fx_addsy != NULL
+          && S_GET_SEGMENT (fixP->fx_addsy) != bfd_com_section_ptr)
+    new_val = hppa_field_adjust (*valp - S_GET_VALUE (fixP->fx_addsy),
+                                0, hppa_fixP->fx_r_field);
 #endif
-      else
-       new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
-
-      /* Handle pc-relative exceptions from above.  */
-      if ((fmt == 12 || fmt == 17 || fmt == 22)
-         && fixP->fx_addsy
-         && fixP->fx_pcrel
-         && !arg_reloc_stub_needed (symbol_arg_reloc_info (fixP->fx_addsy),
-                                    hppa_fixP->fx_arg_reloc)
-         && ((*valp + 8192) < 16384
-             || (fmt == 17 && (*valp + 262144) < 524288)
-             || (fmt == 22 && (*valp + 8388608) < 16777216))
-         && 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);
-       }
-
-      switch (fmt)
-       {
-       case 10:
-         CHECK_FIELD (new_val, 8191, -8192, 0);
-         val = new_val;
+  else
+    new_val = hppa_field_adjust (*valp, 0, hppa_fixP->fx_r_field);
+
+  /* Handle pc-relative exceptions from above.  */
+  if ((fmt == 12 || fmt == 17 || fmt == 22)
+      && fixP->fx_addsy
+      && fixP->fx_pcrel
+      && !arg_reloc_stub_needed (symbol_arg_reloc_info (fixP->fx_addsy),
+                                hppa_fixP->fx_arg_reloc)
+#ifdef OBJ_ELF
+      && (*valp - 8 + 8192 < 16384
+         || (fmt == 17 && *valp - 8 + 262144 < 524288)
+         || (fmt == 22 && *valp - 8 + 8388608 < 16777216))
+#endif
+#ifdef OBJ_SOM
+      && (*valp - 8 + 262144 < 524288
+         || (fmt == 22 && *valp - 8 + 8388608 < 16777216))
+#endif
+      && !S_IS_EXTERNAL (fixP->fx_addsy)
+      && !S_IS_WEAK (fixP->fx_addsy)
+      && 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);
+    }
 
-         insn = (insn & ~ 0x3ff1) | (((val & 0x1ff8) << 1)
-                                     | ((val & 0x2000) >> 13));
-         break;
-       case -11:
-         CHECK_FIELD (new_val, 8191, -8192, 0);
-         val = new_val;
+  switch (fmt)
+    {
+    case 10:
+      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;
+      insn = (insn & ~ 0x3ff1) | (((val & 0x1ff8) << 1)
+                                 | ((val & 0x2000) >> 13));
+      break;
+    case -11:
+      CHECK_FIELD (new_val, 8191, -8192, 0);
+      val = new_val;
 
-         insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
-         break;
+      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;
 
-       /* Handle all opcodes with the 'k' operand type.  */
-       case 21:
-         CHECK_FIELD (new_val, 1048575, -1048576, 0);
-         val = new_val;
+      insn = ((insn & ~ 0x3fff) | low_sign_unext (val, 14));
+      break;
 
-         insn = (insn & ~ 0x1fffff) | re_assemble_21 (val);
-         break;
+      /* Handle all opcodes with the 'k' operand type.  */
+    case 21:
+      CHECK_FIELD (new_val, 1048575, -1048576, 0);
+      val = new_val;
 
-       /* Handle all the opcodes with the 'i' operand type.  */
-       case 11:
-         CHECK_FIELD (new_val, 1023, -1023, 0);
-         val = new_val;
+      insn = (insn & ~ 0x1fffff) | re_assemble_21 (val);
+      break;
 
-         insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
-         break;
+      /* Handle all the opcodes with the 'i' operand type.  */
+    case 11:
+      CHECK_FIELD (new_val, 1023, -1023, 0);
+      val = new_val;
 
-       /* Handle all the opcodes with the 'w' operand type.  */
-       case 12:
-         CHECK_FIELD (new_val, 8199, -8184, 0);
-         val = new_val;
+      insn = (insn & ~ 0x7ff) | low_sign_unext (val, 11);
+      break;
 
-         insn = (insn & ~ 0x1ffd) | re_assemble_12 ((val - 8) >> 2);
-         break;
+      /* Handle all the opcodes with the 'w' operand type.  */
+    case 12:
+      CHECK_FIELD (new_val - 8, 8191, -8192, 0);
+      val = new_val - 8;
 
-       /* Handle some of the opcodes with the 'W' operand type.  */
-       case 17:
-         {
-           offsetT distance = *valp;
+      insn = (insn & ~ 0x1ffd) | re_assemble_12 (val >> 2);
+      break;
 
-           /* 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 == (int) R_HPPA_PCREL_CALL
-               && (insn & 0xffe00000) == 0xe8000000)
-             CHECK_FIELD (distance, 262143, -262144, 0);
+      /* Handle some of the opcodes with the 'W' operand type.  */
+    case 17:
+      {
+       offsetT distance = *valp;
 
-           CHECK_FIELD (new_val, 262143, -262144, 0);
-           val = new_val;
+       /* 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 == (int) R_HPPA_PCREL_CALL
+           && (insn & 0xffe00000) == 0xe8000000)
+         CHECK_FIELD (distance - 8, 262143, -262144, 0);
 
-           insn = (insn & ~ 0x1f1ffd) | re_assemble_17 ((val - 8) >> 2);
-           break;
-         }
+       CHECK_FIELD (new_val - 8, 262143, -262144, 0);
+       val = new_val - 8;
 
-       case 22:
-         {
-           offsetT distance = *valp;
+       insn = (insn & ~ 0x1f1ffd) | re_assemble_17 (val >> 2);
+       break;
+      }
 
-           /* 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 == (int) R_HPPA_PCREL_CALL
-               && (insn & 0xffe00000) == 0xe8000000)
-             CHECK_FIELD (distance, 8388607, -8388608, 0);
+    case 22:
+      {
+       offsetT distance = *valp;
 
-           CHECK_FIELD (new_val, 8388607, -8388608, 0);
-           val = new_val;
+       /* 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 == (int) R_HPPA_PCREL_CALL
+           && (insn & 0xffe00000) == 0xe8000000)
+         CHECK_FIELD (distance - 8, 8388607, -8388608, 0);
 
-           insn = (insn & ~ 0x3ff1ffd) | re_assemble_22 ((val - 8) >> 2);
-           break;
-         }
+       CHECK_FIELD (new_val - 8, 8388607, -8388608, 0);
+       val = new_val - 8;
 
-       case -10:
-         val = new_val;
-         insn = (insn & ~ 0xfff1) | re_assemble_16 (val & -8);
-         break;
+       insn = (insn & ~ 0x3ff1ffd) | re_assemble_22 (val >> 2);
+       break;
+      }
 
-       case -16:
-         val = new_val;
-         insn = (insn & ~ 0xfff9) | re_assemble_16 (val & -4);
-         break;
+    case -10:
+      val = new_val;
+      insn = (insn & ~ 0xfff1) | re_assemble_16 (val & -8);
+      break;
 
-       case 16:
-         val = new_val;
-         insn = (insn & ~ 0xffff) | re_assemble_16 (val);
-         break;
+    case -16:
+      val = new_val;
+      insn = (insn & ~ 0xfff9) | re_assemble_16 (val & -4);
+      break;
 
-       case 32:
-         insn = new_val;
-         break;
+    case 16:
+      val = new_val;
+      insn = (insn & ~ 0xffff) | re_assemble_16 (val);
+      break;
 
-       default:
-         as_bad (_("Unknown relocation encountered in md_apply_fix."));
-         return 0;
-       }
+    case 32:
+      insn = new_val;
+      break;
 
-      /* Insert the relocation.  */
-      bfd_put_32 (stdoutput, insn, (unsigned char *) buf);
-      return 1;
-    }
-  else
-    {
-      printf (_("no hppa_fixup entry for this fixup (fixP = 0x%x, type = 0x%x)\n"),
-             (unsigned int) fixP, fixP->fx_r_type);
+    default:
+      as_bad (_("Unknown relocation encountered in md_apply_fix."));
       return 0;
     }
+
+  /* Insert the relocation.  */
+  bfd_put_32 (stdoutput, insn, buf);
+  return 1;
 }
 
 /* Exactly what point is a PC-relative offset relative TO?
@@ -4659,7 +4654,7 @@ pa_parse_number (s, is_float)
       c = *p;
       /* Tege hack: Special case for general registers as the general
          code makes a binary search with case translation, and is VERY
-         slow. */
+         slow.  */
       if (c == 'r')
        {
          p++;
@@ -4769,7 +4764,7 @@ pa_parse_number (s, is_float)
   return 0;
 }
 
-#define REG_NAME_CNT   (sizeof(pre_defined_registers) / sizeof(struct pd_reg))
+#define REG_NAME_CNT   (sizeof (pre_defined_registers) / sizeof (struct pd_reg))
 
 /* Given NAME, find the register number associated with that name, return
    the integer value associated with the given name or -1 on failure.  */
@@ -4800,7 +4795,6 @@ reg_name_search (name)
   return -1;
 }
 
-
 /* Return nonzero if the given INSN and L/R information will require
    a new PA-1.1 opcode.  */
 
@@ -5104,7 +5098,7 @@ get_expression (str)
   return 0;
 }
 
-/* Mark (via expr_end) the end of an absolute expression.  FIXME. */
+/* Mark (via expr_end) the end of an absolute expression.  FIXME.  */
 static int
 pa_get_absolute_expression (insn, strp)
      struct pa_it *insn;
@@ -5286,7 +5280,6 @@ pa_parse_nonneg_cmpsub_cmpltr (s, isbranch)
       c = **s;
       **s = 0x00;
 
-
       if (strcmp (name, "=") == 0)
        {
          cmpltr = 1;
@@ -5333,7 +5326,6 @@ pa_parse_nonneg_cmpsub_cmpltr (s, isbranch)
   if (nullify)
     *s = save_s;
 
-
   return cmpltr;
 }
 
@@ -5364,7 +5356,6 @@ pa_parse_neg_cmpsub_cmpltr (s, isbranch)
       c = **s;
       **s = 0x00;
 
-
       if (strcasecmp (name, "tr") == 0)
        {
          cmpltr = 0;
@@ -5415,11 +5406,9 @@ pa_parse_neg_cmpsub_cmpltr (s, isbranch)
   if (nullify)
     *s = save_s;
 
-
   return cmpltr;
 }
 
-
 /* Parse a 64 bit compare and branch completer returning the number (for
    encoding in instrutions) of the given completer.
 
@@ -5514,7 +5503,6 @@ pa_parse_cmpb_64_cmpltr (s)
       **s = c;
     }
 
-
   return cmpltr;
 }
 
@@ -5577,7 +5565,6 @@ pa_parse_cmpib_64_cmpltr (s)
       **s = c;
     }
 
-
   return cmpltr;
 }
 
@@ -5838,6 +5825,7 @@ pa_parse_addb_64_cmpltr (s)
    alignment of the subspace if necessary.  */
 static void
 pa_align (bytes)
+     int bytes;
 {
   /* We must have a valid space and subspace.  */
   pa_check_current_space_and_subspace ();
@@ -6063,7 +6051,6 @@ pa_build_unwind_subspace (call_info)
 
   subseg_set (seg, 0);
 
-
   /* Get some space to hold relocation information for the unwind
      descriptor.  */
   p = frag_more (4);
@@ -6091,7 +6078,7 @@ pa_build_unwind_subspace (call_info)
                (expressionS *) NULL, 0, reloc,
                e_fsel, 32, 0, NULL);
 
-  /* Dump it. */
+  /* Dump it.  */
   unwind = (char *) &call_info->ci_unwind;
   for (i = 8; i < sizeof (struct unwind_table); i++)
     {
@@ -6561,7 +6548,7 @@ pa_export (unused)
   else
     {
       /* OK.  Set the external bits and process argument relocations.
-         For the HP, weak and global are not mutually exclusive. 
+         For the HP, weak and global are not mutually exclusive.
          S_SET_EXTERNAL will not set BSF_GLOBAL if WEAK is set.
          Call S_SET_EXTERNAL to get the other processing.  Manually
          set BSF_GLOBAL when we get back.  */
@@ -7069,7 +7056,6 @@ 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.  */
@@ -7598,7 +7584,6 @@ pa_subspace (create_new)
   SUBSPACE_DEFINED (current_subspace) = 1;
 }
 
-
 /* Create default space and subspace dictionaries.  */
 
 static void
@@ -7641,7 +7626,6 @@ pa_spaces_begin ()
       /* Create the new section.  */
       segment = subseg_new (name, subsegment);
 
-
       /* For SOM we want to replace the standard .text, .data, and .bss
          sections with our own.   We also want to set BFD flags for
         all the built-in subspaces.  */
@@ -7664,7 +7648,6 @@ pa_spaces_begin ()
                                               | SEC_RELOC
                                               | SEC_HAS_CONTENTS));
 
-
        }
       else if (!strcmp (pa_def_subspaces[i].name, "$BSS$"))
        {
@@ -7726,8 +7709,6 @@ pa_spaces_begin ()
     }
 }
 
-
-
 /* Create a new space NAME, with the appropriate flags as defined
    by the given parameters.  */
 
@@ -8330,6 +8311,10 @@ hppa_fix_adjustable (fixp)
     return 0;
 #endif
 
+  if (fixp->fx_addsy && (S_IS_EXTERNAL (fixp->fx_addsy)
+                        || S_IS_WEAK (fixp->fx_addsy)))
+    return 0;
+
   /* Reject reductions of symbols in sym1-sym2 expressions when
      the fixup will occur in a CODE subspace.
 
@@ -8390,19 +8375,15 @@ hppa_fix_adjustable (fixp)
       || hppa_fix->fx_r_field == e_lpsel)
     return 0;
 
-  if (fixp->fx_addsy && (S_IS_EXTERNAL (fixp->fx_addsy)
-                        || S_IS_WEAK (fixp->fx_addsy)))
-    return 0;
-
   /* Reject absolute calls (jumps).  */
   if (hppa_fix->fx_r_type == R_HPPA_ABS_CALL)
     return 0;
 
   /* Reject reductions of function symbols.  */
-  if (fixp->fx_addsy == 0 || ! S_IS_FUNCTION (fixp->fx_addsy))
-    return 1;
+  if (fixp->fx_addsy != 0 && S_IS_FUNCTION (fixp->fx_addsy))
+    return 0;
 
-  return 0;
+  return 1;
 }
 
 /* Return nonzero if the fixup in FIXP will require a relocation,
@@ -8414,7 +8395,6 @@ hppa_force_relocation (fixp)
      struct fix *fixp;
 {
   struct hppa_fix_struct *hppa_fixp;
-  int distance;
 
   hppa_fixp = (struct hppa_fix_struct *) fixp->tc_fix_data;
 #ifdef OBJ_SOM
@@ -8434,20 +8414,36 @@ hppa_force_relocation (fixp)
     return 1;
 #endif
 
+  assert (fixp->fx_addsy != NULL);
+
+  /* Ensure we emit a relocation for global symbols so that dynamic
+     linking works.  */
+  if (S_IS_EXTERNAL (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy))
+    return 1;
+
   /* It is necessary to force PC-relative calls/jumps to have a relocation
      entry if they're going to need either a argument relocation or long
-     call stub.  FIXME.  Can't we need the same for absolute calls?  */
-  if (fixp->fx_pcrel && fixp->fx_addsy
-      && (arg_reloc_stub_needed (symbol_arg_reloc_info (fixp->fx_addsy),
-                                hppa_fixp->fx_arg_reloc)))
+     call stub.  */
+  if (fixp->fx_pcrel
+      && arg_reloc_stub_needed (symbol_arg_reloc_info (fixp->fx_addsy),
+                               hppa_fixp->fx_arg_reloc))
     return 1;
 
-  distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy)
-             - md_pcrel_from (fixp));
-  /* Now check and see if we're going to need a long-branch stub.  */
-  if (fixp->fx_r_type == (int) R_HPPA_PCREL_CALL
-      && (distance > 262143 || distance < -262144))
-    return 1;
+  /* Now check to see if we're going to need a long-branch stub.  */
+  if (fixp->fx_r_type == (int) R_HPPA_PCREL_CALL)
+    {
+      valueT distance;
+
+      distance = (fixp->fx_offset + S_GET_VALUE (fixp->fx_addsy)
+                 - md_pcrel_from (fixp) - 8);
+      if (distance + 8388608 >= 16777216
+         || (hppa_fixp->fx_r_format == 17 && distance + 262144 >= 524288)
+#ifdef OBJ_ELF
+         || (hppa_fixp->fx_r_format == 12 && distance + 8192 >= 16384)
+#endif
+         )
+       return 1;
+    }
 
   if (fixp->fx_r_type == (int) R_HPPA_ABS_CALL)
     return 1;
@@ -8543,13 +8539,6 @@ elf_hppa_final_processing ()
     }
 }
 
-void
-pa_end_of_source ()
-{
-  if (debug_type == DEBUG_DWARF2)
-    dwarf2_finish ();
-}
-
 static void
 pa_vtable_entry (ignore)
      int ignore ATTRIBUTE_UNUSED;
This page took 0.034818 seconds and 4 git commands to generate.