* config/tc-alpha.c (O_samegp): New.
authorRichard Henderson <rth@redhat.com>
Sat, 9 Feb 2002 22:55:06 +0000 (22:55 +0000)
committerRichard Henderson <rth@redhat.com>
Sat, 9 Feb 2002 22:55:06 +0000 (22:55 +0000)
        (USER_RELOC_P): Include it.
        (alpha_reloc_op_tag, debug_exp, find_macro_match): Add it.
        (md_apply_fix3): Handle BFD_RELOC_ALPHA_BRSGP.
        (alpha_force_relocation, alpha_fix_adjustable): Likewise.
        (alpha_validate_fix): New.
        * config/tc-alpha.h (TC_VALIDATE_FIX): New.

        * gas/alpha/elf-reloc-5.s, gas/alpha/elf-reloc-5.d: New.
        * gas/alpha/elf-reloc-6.s, gas/alpha/elf-reloc-6.l: New.
        * gas/alpha/alpha.exp: Run them.

gas/ChangeLog
gas/config/tc-alpha.c
gas/config/tc-alpha.h
gas/testsuite/ChangeLog
gas/testsuite/gas/alpha/alpha.exp
gas/testsuite/gas/alpha/elf-reloc-5.d [new file with mode: 0644]
gas/testsuite/gas/alpha/elf-reloc-5.s [new file with mode: 0644]
gas/testsuite/gas/alpha/elf-reloc-6.l [new file with mode: 0644]
gas/testsuite/gas/alpha/elf-reloc-6.s [new file with mode: 0644]

index dbb75eb..5d56137 100644 (file)
@@ -1,3 +1,13 @@
+2002-02-09  Richard Henderson  <rth@redhat.com>
+
+       * config/tc-alpha.c (O_samegp): New.
+       (USER_RELOC_P): Include it.
+       (alpha_reloc_op_tag, debug_exp, find_macro_match): Add it.
+       (md_apply_fix3): Handle BFD_RELOC_ALPHA_BRSGP.
+       (alpha_force_relocation, alpha_fix_adjustable): Likewise.
+       (alpha_validate_fix): New.
+       * config/tc-alpha.h (TC_VALIDATE_FIX): New.
+
 2002-02-09  Hans-Peter Nilsson  <hp@axis.com>
 
        * doc/c-cris.texi: New.
index 44c651b..ae6f76b 100644 (file)
@@ -117,6 +117,7 @@ struct alpha_macro {
 #define O_gprelhigh    O_md9   /* !gprelhigh relocation */
 #define O_gprellow     O_md10  /* !gprellow relocation */
 #define O_gprel                O_md11  /* !gprel relocation */
+#define O_samegp       O_md12  /* !samegp relocation */
 
 #define DUMMY_RELOC_LITUSE_ADDR                (BFD_RELOC_UNUSED + 1)
 #define DUMMY_RELOC_LITUSE_BASE                (BFD_RELOC_UNUSED + 2)
@@ -128,7 +129,7 @@ struct alpha_macro {
 #define LITUSE_BYTOFF  2
 #define LITUSE_JSR     3
 
-#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_gprel)
+#define USER_RELOC_P(R) ((R) >= O_literal && (R) <= O_samegp)
 
 /* Macros for extracting the type and number of encoded register tokens */
 
@@ -498,7 +499,8 @@ static const struct alpha_reloc_op_tag {
   DEF(gpdisp, BFD_RELOC_ALPHA_GPDISP, 1, 1),
   DEF(gprelhigh, BFD_RELOC_ALPHA_GPREL_HI16, 0, 0),
   DEF(gprellow, BFD_RELOC_ALPHA_GPREL_LO16, 0, 0),
-  DEF(gprel, BFD_RELOC_GPREL16, 0, 0)
+  DEF(gprel, BFD_RELOC_GPREL16, 0, 0),
+  DEF(samegp, BFD_RELOC_ALPHA_BRSGP, 0, 0)
 };
 
 #undef DEF
@@ -1219,6 +1221,11 @@ md_apply_fix3 (fixP, valP, seg)
        }
       return;
 
+#ifdef OBJ_ELF
+    case BFD_RELOC_ALPHA_BRSGP:
+      return;
+#endif
+
 #ifdef OBJ_ECOFF
     case BFD_RELOC_ALPHA_LITERAL:
       md_number_to_chars (fixpos, value, 2);
@@ -1364,6 +1371,49 @@ alpha_define_label (sym)
   alpha_insn_label = sym;
 }
 
+/* If we have a BRSGP reloc to a local symbol, adjust it to BRADDR and
+   let it get resolved at assembly time.  */
+
+void
+alpha_validate_fix (f)
+     fixS *f;
+{
+#ifdef OBJ_ELF
+  int offset = 0;
+  const char *name;
+
+  if (f->fx_r_type != BFD_RELOC_ALPHA_BRSGP)
+    return;
+
+  if (! S_IS_DEFINED (f->fx_addsy))
+    return;
+
+  switch (S_GET_OTHER (f->fx_addsy) & STO_ALPHA_STD_GPLOAD)
+    {
+    case STO_ALPHA_NOPV:
+      break;
+    case STO_ALPHA_STD_GPLOAD:
+      offset = 8;
+      break;
+    default:
+      if (S_IS_LOCAL (f->fx_addsy))
+       name = "<local>";
+      else
+       name = S_GET_NAME (f->fx_addsy);
+      as_bad_where (f->fx_file, f->fx_line,
+                   _("!samegp reloc against symbol without .prologue: %s"),
+                   name);
+      break;
+    }
+
+  if (! (S_IS_EXTERN (f->fx_addsy) || S_IS_WEAK (f->fx_addsy)))
+    {
+      f->fx_r_type = BFD_RELOC_23_PCREL_S2;
+      f->fx_offset += offset;
+    }
+#endif
+}
+
 /* Return true if we must always emit a reloc for a type and false if
    there is some hope of resolving it at assembly time.  */
 
@@ -1388,6 +1438,7 @@ alpha_force_relocation (f)
     case BFD_RELOC_ALPHA_GPREL_LO16:
     case BFD_RELOC_ALPHA_LINKAGE:
     case BFD_RELOC_ALPHA_CODEADDR:
+    case BFD_RELOC_ALPHA_BRSGP:
     case BFD_RELOC_VTABLE_INHERIT:
     case BFD_RELOC_VTABLE_ENTRY:
       return 1;
@@ -1422,6 +1473,7 @@ alpha_fix_adjustable (f)
     case BFD_RELOC_ALPHA_GPDISP_HI16:
     case BFD_RELOC_ALPHA_GPDISP_LO16:
     case BFD_RELOC_ALPHA_GPDISP:
+    case BFD_RELOC_ALPHA_BRSGP:
       return 0;
 
     case BFD_RELOC_ALPHA_LITERAL:
@@ -1763,6 +1815,7 @@ debug_exp (tok, ntok)
        case O_pregister:               name = "O_pregister";           break;
        case O_cpregister:              name = "O_cpregister";          break;
        case O_literal:                 name = "O_literal";             break;
+       case O_lituse_addr:             name = "O_lituse_addr";         break;
        case O_lituse_base:             name = "O_lituse_base";         break;
        case O_lituse_bytoff:           name = "O_lituse_bytoff";       break;
        case O_lituse_jsr:              name = "O_lituse_jsr";          break;
@@ -1770,8 +1823,7 @@ debug_exp (tok, ntok)
        case O_gprelhigh:               name = "O_gprelhigh";           break;
        case O_gprellow:                name = "O_gprellow";            break;
        case O_gprel:                   name = "O_gprel";               break;
-       case O_md11:                    name = "O_md11";                break;
-       case O_md12:                    name = "O_md12";                break;
+       case O_samegp:                  name = "O_samegp";              break;
        case O_md13:                    name = "O_md13";                break;
        case O_md14:                    name = "O_md14";                break;
        case O_md15:                    name = "O_md15";                break;
@@ -2166,6 +2218,7 @@ find_macro_match (first_macro, tok, pntok)
                case O_gprelhigh:
                case O_gprellow:
                case O_gprel:
+               case O_samegp:
                  goto match_failed;
 
                default:
index fb428f9..5505861 100644 (file)
 #define NEED_LITERAL_POOL
 #define REPEAT_CONS_EXPRESSIONS
 
+extern void alpha_validate_fix PARAMS ((struct fix *));
 extern int alpha_force_relocation PARAMS ((struct fix *));
 extern int alpha_fix_adjustable PARAMS ((struct fix *));
 
 extern unsigned long alpha_gprmask, alpha_fprmask;
 extern valueT alpha_gp_value;
 
+#define TC_VALIDATE_FIX(FIXP,SEGTYPE,SKIP) alpha_validate_fix (FIXP)
 #define TC_FORCE_RELOCATION(FIXP)      alpha_force_relocation (FIXP)
 #define tc_fix_adjustable(FIXP)                alpha_fix_adjustable (FIXP)
 #define RELOC_REQUIRES_SYMBOL
index 1c5d1de..df5f108 100644 (file)
@@ -1,3 +1,9 @@
+2002-02-09  Richard Henderson  <rth@redhat.com>
+
+       * gas/alpha/elf-reloc-5.s, gas/alpha/elf-reloc-5.d: New.
+       * gas/alpha/elf-reloc-6.s, gas/alpha/elf-reloc-6.l: New.
+       * gas/alpha/alpha.exp: Run them.
+
 2002-02-08  Chris Demetriou  <cgd@broadcom.com>
 
        * gas/mips/mips.exp: Document (but do not XFAIL) currently-failing
index db16022..89a6334 100644 (file)
@@ -27,6 +27,8 @@ if { [istarget alpha*-*-*] } then {
        run_list_test "elf-reloc-2" ""
        run_list_test "elf-reloc-3" ""
        run_dump_test "elf-reloc-4"
+       run_dump_test "elf-reloc-5"
+       run_list_test "elf-reloc-6" ""
     }
 
     run_dump_test "fp"
diff --git a/gas/testsuite/gas/alpha/elf-reloc-5.d b/gas/testsuite/gas/alpha/elf-reloc-5.d
new file mode 100644 (file)
index 0000000..0fd9261
--- /dev/null
@@ -0,0 +1,28 @@
+#objdump: -dr
+#name: alpha elf-reloc-5
+
+.*:     file format elf64-alpha
+
+Disassembly of section \.text:
+
+0*0000000 <_start>:
+   0:  05 00 e0 c3     br      18 <nopv>
+   4:  04 00 e0 c3     br      18 <nopv>
+   8:  04 00 e0 c3     br      1c <stdgp>
+   c:  05 00 e0 c3     br      24 <stdgp\+0x8>
+  10:  00 00 e0 c3     br      14 <_start\+0x14>
+                       10: BRSGP       undef
+  14:  00 00 e0 c3     br      18 <nopv>
+                       14: BRSGP       extern
+
+0*0000018 <nopv>:
+  18:  1f 04 ff 47     nop     
+
+0*000001c <stdgp>:
+  1c:  00 00 bb 27     ldah    gp,0\(t12\)
+                       1c: GPDISP      \.text\+0x4
+  20:  00 00 bd 23     lda     gp,0\(gp\)
+  24:  1f 04 ff 47     nop     
+
+0*0000028 <extern>:
+  28:  1f 04 ff 47     nop     
diff --git a/gas/testsuite/gas/alpha/elf-reloc-5.s b/gas/testsuite/gas/alpha/elf-reloc-5.s
new file mode 100644 (file)
index 0000000..f8934a5
--- /dev/null
@@ -0,0 +1,31 @@
+       .text
+       .align 2
+_start:
+       br $31, nopv
+       br $31, nopv    !samegp
+       br $31, stdgp
+       br $31, stdgp   !samegp
+
+       br $31, undef   !samegp
+       br $31, extern  !samegp
+
+.ent nopv
+nopv:
+       .prologue 0
+       nop
+.end nopv
+
+.ent stdgp
+stdgp:
+       ldgp $29,0($27)
+       .prologue 1
+       nop
+.end stdgp
+
+.globl extern
+.ent extern
+extern:
+       .prologue 0
+       nop
+.end extern
+
diff --git a/gas/testsuite/gas/alpha/elf-reloc-6.l b/gas/testsuite/gas/alpha/elf-reloc-6.l
new file mode 100644 (file)
index 0000000..85ee392
--- /dev/null
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:8: Error: !samegp reloc against symbol without \.prologue: nopro
+.*:10: Error: !samegp reloc against symbol without \.prologue: <local>
diff --git a/gas/testsuite/gas/alpha/elf-reloc-6.s b/gas/testsuite/gas/alpha/elf-reloc-6.s
new file mode 100644 (file)
index 0000000..af8fb1a
--- /dev/null
@@ -0,0 +1,31 @@
+       br $31, undef
+       br $31, undef   !samegp
+       br $31, nopv
+       br $31, nopv    !samegp
+       br $31, stdgp
+       br $31, stdgp   !samegp
+       br $31, nopro
+       br $31, nopro   !samegp
+       br $31, 1f
+       br $31, 1f      !samegp
+
+1:     nop
+
+.ent nopv
+nopv:
+       .prologue 0
+       nop
+.end nopv
+
+.ent stdgp
+stdgp:
+       ldgp $29,0($27)
+       .prologue 1
+       nop
+.end stdgp
+
+.ent nopro
+nopro:
+       nop
+.end nopro
+