* config/tc-mips.c (append_insn): Use fix_new rather than fix_new_exp

to build the second and third fixups for a composite relocation.
	(macro_read_relocs): New function.
	(macro_build): Use it.
	(s_cpsetup): Pass all three composite relocation codes to macro_build.
	Simplify fragging code accordingly.
	(s_gpdword): Use fix_new rather than fix_new_exp for the second part
	of the composite relocation.  Set fx_tcbit in both fixups.
This commit is contained in:
Richard Sandiford
2004-10-07 22:29:19 +00:00
parent 1c877e87e3
commit 6e1304d817
8 changed files with 89 additions and 31 deletions

View File

@ -1,3 +1,14 @@
2004-10-07 Richard Sandiford <rsandifo@redhat.com>
* config/tc-mips.c (append_insn): Use fix_new rather than fix_new_exp
to build the second and third fixups for a composite relocation.
(macro_read_relocs): New function.
(macro_build): Use it.
(s_cpsetup): Pass all three composite relocation codes to macro_build.
Simplify fragging code accordingly.
(s_gpdword): Use fix_new rather than fix_new_exp for the second part
of the composite relocation. Set fx_tcbit in both fixups.
2004-10-07 Richard Sandiford <rsandifo@redhat.com> 2004-10-07 Richard Sandiford <rsandifo@redhat.com>
* config/tc-mips.c (append_insn): Set fx_tcbit for composite relocs. * config/tc-mips.c (append_insn): Set fx_tcbit for composite relocs.

View File

@ -2224,13 +2224,9 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
for (i = 1; i < 3; i++) for (i = 1; i < 3; i++)
if (reloc_type[i] != BFD_RELOC_UNUSED) if (reloc_type[i] != BFD_RELOC_UNUSED)
{ {
address_expr->X_op = O_absent; fixp[i] = fix_new (frag_now, fixp[0]->fx_where,
address_expr->X_add_symbol = 0; fixp[0]->fx_size, NULL, 0,
address_expr->X_add_number = 0; FALSE, reloc_type[i]);
fixp[i] = fix_new_exp (frag_now, fixp[0]->fx_where,
fixp[0]->fx_size, address_expr,
FALSE, reloc_type[i]);
/* Use fx_tcbit to mark compound relocs. */ /* Use fx_tcbit to mark compound relocs. */
fixp[0]->fx_tcbit = 1; fixp[0]->fx_tcbit = 1;
@ -2975,6 +2971,24 @@ macro_end (void)
} }
} }
/* Read a macro's relocation codes from *ARGS and store them in *R.
The first argument in *ARGS will be either the code for a single
relocation or -1 followed by the three codes that make up a
composite relocation. */
static void
macro_read_relocs (va_list *args, bfd_reloc_code_real_type *r)
{
int i, next;
next = va_arg (*args, int);
if (next >= 0)
r[0] = (bfd_reloc_code_real_type) next;
else
for (i = 0; i < 3; i++)
r[i] = (bfd_reloc_code_real_type) va_arg (*args, int);
}
/* Build an instruction created by a macro expansion. This is passed /* Build an instruction created by a macro expansion. This is passed
a pointer to the count of instructions created so far, an a pointer to the count of instructions created so far, an
expression, the name of the instruction to build, an operand format expression, the name of the instruction to build, an operand format
@ -3138,7 +3152,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
case 'i': case 'i':
case 'j': case 'j':
case 'o': case 'o':
*r = (bfd_reloc_code_real_type) va_arg (args, int); macro_read_relocs (&args, r);
assert (*r == BFD_RELOC_GPREL16 assert (*r == BFD_RELOC_GPREL16
|| *r == BFD_RELOC_MIPS_LITERAL || *r == BFD_RELOC_MIPS_LITERAL
|| *r == BFD_RELOC_MIPS_HIGHER || *r == BFD_RELOC_MIPS_HIGHER
@ -3154,7 +3168,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
continue; continue;
case 'u': case 'u':
*r = (bfd_reloc_code_real_type) va_arg (args, int); macro_read_relocs (&args, r);
assert (ep != NULL assert (ep != NULL
&& (ep->X_op == O_constant && (ep->X_op == O_constant
|| (ep->X_op == O_symbol || (ep->X_op == O_symbol
@ -11837,7 +11851,6 @@ s_cpsetup (int ignore ATTRIBUTE_UNUSED)
expressionS ex_off; expressionS ex_off;
expressionS ex_sym; expressionS ex_sym;
int reg1; int reg1;
char *f;
/* If we are not generating SVR4 PIC code, .cpsetup is ignored. /* If we are not generating SVR4 PIC code, .cpsetup is ignored.
We also need NewABI support. */ We also need NewABI support. */
@ -11893,23 +11906,12 @@ s_cpsetup (int ignore ATTRIBUTE_UNUSED)
macro_build (NULL, "daddu", "d,v,t", mips_cpreturn_register, macro_build (NULL, "daddu", "d,v,t", mips_cpreturn_register,
mips_gp_register, 0); mips_gp_register, 0);
/* Ensure there's room for the next two instructions, so that `f' macro_build (&ex_sym, "lui", "t,u", mips_gp_register,
doesn't end up with an address in the wrong frag. */ -1, BFD_RELOC_GPREL16, BFD_RELOC_MIPS_SUB, BFD_RELOC_HI16_S);
frag_grow (8);
f = frag_more (0);
macro_build (&ex_sym, "lui", "t,u", mips_gp_register, BFD_RELOC_GPREL16);
fix_new (frag_now, f - frag_now->fr_literal,
8, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
fix_new (frag_now, f - frag_now->fr_literal,
4, NULL, 0, 0, BFD_RELOC_HI16_S);
f = frag_more (0);
macro_build (&ex_sym, "addiu", "t,r,j", mips_gp_register, macro_build (&ex_sym, "addiu", "t,r,j", mips_gp_register,
mips_gp_register, BFD_RELOC_GPREL16); mips_gp_register, -1, BFD_RELOC_GPREL16,
fix_new (frag_now, f - frag_now->fr_literal, BFD_RELOC_MIPS_SUB, BFD_RELOC_LO16);
8, NULL, 0, 0, BFD_RELOC_MIPS_SUB);
fix_new (frag_now, f - frag_now->fr_literal,
4, NULL, 0, 0, BFD_RELOC_LO16);
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", mips_gp_register, macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", mips_gp_register,
mips_gp_register, reg1); mips_gp_register, reg1);
@ -12093,14 +12095,11 @@ s_gpdword (int ignore ATTRIBUTE_UNUSED)
p = frag_more (8); p = frag_more (8);
md_number_to_chars (p, 0, 8); md_number_to_chars (p, 0, 8);
fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE, fix_new_exp (frag_now, p - frag_now->fr_literal, 4, &ex, FALSE,
BFD_RELOC_GPREL32); BFD_RELOC_GPREL32)->fx_tcbit = 1;
/* GPREL32 composed with 64 gives a 64-bit GP offset. */ /* GPREL32 composed with 64 gives a 64-bit GP offset. */
ex.X_op = O_absent; fix_new (frag_now, p - frag_now->fr_literal, 8, NULL, 0,
ex.X_add_symbol = 0; FALSE, BFD_RELOC_64)->fx_tcbit = 1;
ex.X_add_number = 0;
fix_new_exp (frag_now, p - frag_now->fr_literal, 8, &ex, FALSE,
BFD_RELOC_64);
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
} }

View File

@ -1,3 +1,8 @@
2004-10-07 Richard Sandiford <rsandifo@redhat.com>
* gas/mips/elf-rel{23,24}.[sd]: New tests.
* gas/mips/mips.exp: New test.
2004-10-07 Richard Sandiford <rsandifo@redhat.com> 2004-10-07 Richard Sandiford <rsandifo@redhat.com>
* gas/mips/elf-rel22.[sd]: New test. * gas/mips/elf-rel22.[sd]: New test.

View File

@ -0,0 +1,19 @@
#as: -march=mips3 -mabi=64
#objdump: -dr -Mgpr-names=numeric
#name: MIPS ELF reloc 23
.*: * file format elf64-tradbigmips
Disassembly of section \.text:
0+00 <.*>:
.*: 0380282d move \$5,\$28
.*: 3c1c0000 lui \$28,0x0
.*: R_MIPS_GPREL16 foo
.*: R_MIPS_SUB \*ABS\*
.*: R_MIPS_HI16 \*ABS\*
.*: 279c0000 addiu \$28,\$28,0
.*: R_MIPS_GPREL16 foo
.*: R_MIPS_SUB \*ABS\*
.*: R_MIPS_LO16 \*ABS\*
.*: 0384e02d daddu \$28,\$28,\$4

View File

@ -0,0 +1,6 @@
.abicalls
.globl foo
.ent foo
foo:
.cpsetup $4,$5,foo
.end foo

View File

@ -0,0 +1,12 @@
#as: -march=mips3 -mabi=64
#readelf: --relocs
#name: MIPS ELF reloc 24
Relocation section '\.rela\.text' .*:
.*
.* R_MIPS_GPREL32 * 0+00 foo \+ 0
* Type2: R_MIPS_64 *
* Type3: R_MIPS_NONE *
.* R_MIPS_GPREL32 * 0+00 \.text \+ 10
* Type2: R_MIPS_64 *
* Type3: R_MIPS_NONE *

View File

@ -0,0 +1,4 @@
.abicalls
.gpdword foo
.gpdword bar
bar:

View File

@ -665,6 +665,8 @@ if { [istarget mips*-*-*] } then {
if $has_newabi { if $has_newabi {
run_dump_test "elf-rel21" run_dump_test "elf-rel21"
run_dump_test "elf-rel22" run_dump_test "elf-rel22"
run_dump_test "elf-rel23"
run_dump_test "elf-rel24"
} }
if { !$no_mips16 } { if { !$no_mips16 } {