Jakub Jelinek <jj@ultra.linux.cz>
authorRichard Henderson <rth@redhat.com>
Fri, 16 Jul 1999 21:30:35 +0000 (21:30 +0000)
committerRichard Henderson <rth@redhat.com>
Fri, 16 Jul 1999 21:30:35 +0000 (21:30 +0000)
        * config/tc-sparc.c (sparc_ip): Allow OLO10 relocations
        on -64 and not pic.
        (output_insn): Put OLO10's secondary addend into tc_fix_data.
        (md_apply_fix3): Handle BFD_RELOC_SPARC_OLO10.
        (tc_gen_reloc): Return two relocs for OLO10, LO10 and SPARC13.
        * config/tc-sparc.h (RELOC_EXPANSION_POSSIBLE,
        MAX_RELOC_EXPANSION): Define.
        (TC_FIX_TYPE, TC_INIT_FIX_DATA, TC_FIX_DATA_PRINT): Likewise.

gas/ChangeLog
gas/config/tc-sparc.c
gas/config/tc-sparc.h

index 54af92643d3529b1be582b74b1c37dfefa033e72..c977b52df1e55997b0ff8c26a9cdaafa0413e6e5 100644 (file)
@@ -1,3 +1,14 @@
+1999-07-16  Jakub Jelinek  <jj@ultra.linux.cz>
+
+       * config/tc-sparc.c (sparc_ip): Allow OLO10 relocations
+       on -64 and not pic.
+       (output_insn): Put OLO10's secondary addend into tc_fix_data.
+       (md_apply_fix3): Handle BFD_RELOC_SPARC_OLO10.
+       (tc_gen_reloc): Return two relocs for OLO10, LO10 and SPARC13.
+       * config/tc-sparc.h (RELOC_EXPANSION_POSSIBLE,
+       MAX_RELOC_EXPANSION): Define.
+       (TC_FIX_TYPE, TC_INIT_FIX_DATA, TC_FIX_DATA_PRINT): Likewise.
+
 1999-07-16  Alan Modra  <alan@spri.levels.unisa.edu.au>
 
        * config/tc-i386.c (intel_float_operand): Add prototype, make static.
index fe8c8909a40e413bfad2e37b48384b0cec94fa1e..1bced2942f6538b8a0d3f34eb5e590d0be6dfea1 100644 (file)
@@ -2226,7 +2226,7 @@ sparc_ip (str, pinsn)
                      }
                    else
                      {
-                       if (1 || old_reloc != BFD_RELOC_SPARC13
+                       if (old_reloc != BFD_RELOC_SPARC13
                            || the_insn.reloc != BFD_RELOC_LO10
                            || sparc_arch_size != 64
                            || sparc_pic_code)
@@ -2645,6 +2645,8 @@ output_insn (insn, the_insn)
         the insn size is 4 and fixup_segment will signal an overflow for
         large 8 byte quantities.  */
       fixP->fx_no_overflow = 1;
+      if (the_insn->reloc == BFD_RELOC_SPARC_OLO10)
+       fixP->tc_fix_data = the_insn->exp2.X_add_number;
     }
 
   last_insn = insn;
@@ -2979,6 +2981,11 @@ md_apply_fix3 (fixP, value, segment)
            }
          break;
 
+       case BFD_RELOC_SPARC_OLO10:
+         val &= 0x3ff;
+         val += fixP->tc_fix_data;
+         /* intentional fallthrough */
+
        case BFD_RELOC_SPARC13:
          if (! in_signed_range (val, 0x1fff))
            as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -3048,15 +3055,17 @@ md_apply_fix3 (fixP, value, segment)
 
 /* Translate internal representation of relocation info to BFD target
    format.  */
-arelent *
+arelent **
 tc_gen_reloc (section, fixp)
      asection *section;
      fixS *fixp;
 {
+  static arelent *relocs[3];
   arelent *reloc;
   bfd_reloc_code_real_type code;
 
-  reloc = (arelent *) xmalloc (sizeof (arelent));
+  relocs[0] = reloc = (arelent *) xmalloc (sizeof (arelent));
+  relocs[1] = NULL;
 
   reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
@@ -3093,6 +3102,7 @@ tc_gen_reloc (section, fixp)
     case BFD_RELOC_SPARC_HIX22:
     case BFD_RELOC_SPARC_LOX10:
     case BFD_RELOC_SPARC_REV32:
+    case BFD_RELOC_SPARC_OLO10:
     case BFD_RELOC_VTABLE_ENTRY:
     case BFD_RELOC_VTABLE_INHERIT:
       code = fixp->fx_r_type;
@@ -3146,13 +3156,18 @@ tc_gen_reloc (section, fixp)
     }
 #endif /* defined (OBJ_ELF) || defined (OBJ_AOUT) */
 
-  reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
+  if (code == BFD_RELOC_SPARC_OLO10)
+    reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_LO10);
+  else
+    reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
   if (reloc->howto == 0)
     {
       as_bad_where (fixp->fx_file, fixp->fx_line,
                    _("internal error: can't export reloc type %d (`%s')"),
                    fixp->fx_r_type, bfd_get_reloc_code_name (code));
-      return 0;
+      xfree (reloc);
+      relocs[0] = NULL;
+      return relocs;
     }
 
   /* @@ Why fx_addnumber sometimes and fx_offset other times?  */
@@ -3187,7 +3202,21 @@ tc_gen_reloc (section, fixp)
     reloc->addend = fixp->fx_offset;
 #endif
 
-  return reloc;
+  /* We expand R_SPARC_OLO10 to R_SPARC_LO10 and R_SPARC_13
+     on the same location.  */
+  if (code == BFD_RELOC_SPARC_OLO10)
+    {
+      relocs[1] = reloc = (arelent *) xmalloc (sizeof (arelent));
+      relocs[2] = NULL;
+
+      reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+      *reloc->sym_ptr_ptr = symbol_get_bfdsym (section_symbol (absolute_section));
+      reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
+      reloc->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_SPARC13);
+      reloc->addend = fixp->tc_fix_data;
+    }
+
+  return relocs;
 }
 \f
 /* We have no need to default values of symbols. */
index 2f9525fd6fcef5bf7c92f68555e6cf13c312b20b..40ab02c8bd9fa8a9af64ab8b4911e8d9222e67c0 100644 (file)
@@ -35,6 +35,9 @@ struct frag;
 extern const char *sparc_target_format PARAMS ((void));
 #define TARGET_FORMAT sparc_target_format ()
 
+#define RELOC_EXPANSION_POSSIBLE
+#define MAX_RELOC_EXPANSION 2
+
 #if 0
 #ifdef TE_SPARCAOUT
 /* Bi-endian support may eventually be unconditional, but until things are
@@ -160,4 +163,21 @@ extern void sparc_md_end PARAMS ((void));
 extern void cons_fix_new_sparc
   PARAMS ((struct frag *, int, unsigned int, struct expressionS *));
 
+#define TC_FIX_TYPE    valueT
+
+#define TC_INIT_FIX_DATA(X)                    \
+  do                                           \
+     {                                         \
+       (X)->tc_fix_data = 0;                   \
+     }                                         \
+  while(0)
+
+#define TC_FIX_DATA_PRINT(FILE, FIXP)                                  \
+  do                                                                   \
+    {                                                                  \
+      fprintf((FILE), "addend2=%ld\n",                                 \
+             (unsigned long) (FIXP)->tc_fix_data);                     \
+    }                                                                  \
+  while(0)
+
 /* end of tc-sparc.h */