aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog10
-rw-r--r--gas/config/tc-alpha.c61
-rw-r--r--gas/config/tc-alpha.h2
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/alpha/alpha.exp2
-rw-r--r--gas/testsuite/gas/alpha/elf-reloc-5.d28
-rw-r--r--gas/testsuite/gas/alpha/elf-reloc-5.s31
-rw-r--r--gas/testsuite/gas/alpha/elf-reloc-6.l3
-rw-r--r--gas/testsuite/gas/alpha/elf-reloc-6.s31
9 files changed, 170 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index dbb75ebf..5d56137 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -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.
diff --git a/gas/config/tc-alpha.c b/gas/config/tc-alpha.c
index 44c651b..ae6f76b9 100644
--- a/gas/config/tc-alpha.c
+++ b/gas/config/tc-alpha.c
@@ -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:
diff --git a/gas/config/tc-alpha.h b/gas/config/tc-alpha.h
index fb428f9..5505861 100644
--- a/gas/config/tc-alpha.h
+++ b/gas/config/tc-alpha.h
@@ -39,12 +39,14 @@
#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
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 1c5d1de..df5f108 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -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
diff --git a/gas/testsuite/gas/alpha/alpha.exp b/gas/testsuite/gas/alpha/alpha.exp
index db16022..89a6334 100644
--- a/gas/testsuite/gas/alpha/alpha.exp
+++ b/gas/testsuite/gas/alpha/alpha.exp
@@ -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
index 0000000..0fd9261
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-reloc-5.d
@@ -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
index 0000000..f8934a5
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-reloc-5.s
@@ -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
index 0000000..85ee392
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-reloc-6.l
@@ -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
index 0000000..af8fb1a
--- /dev/null
+++ b/gas/testsuite/gas/alpha/elf-reloc-6.s
@@ -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
+