aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@linux-mips.org>2004-02-02 12:48:21 +0000
committerMaciej W. Rozycki <macro@linux-mips.org>2004-02-02 12:48:21 +0000
commitf6a22291f074f8dd64fca5d8f922c8bb23297012 (patch)
tree1cc2065b4de185a2eedc0219836a085aa4002540 /gas/config
parent3ad1377116556518b857286fc3a46354eff403ad (diff)
downloadgdb-f6a22291f074f8dd64fca5d8f922c8bb23297012.zip
gdb-f6a22291f074f8dd64fca5d8f922c8bb23297012.tar.gz
gdb-f6a22291f074f8dd64fca5d8f922c8bb23297012.tar.bz2
gas/
* config/tc-mips.c (add_got_offset_hilo): New function. (macro): Use load_register() and add_got_offset_hilo() to load constants instead of hardcoding code sequences throughout. gas/testsuite/ * gas/mips/div.d: Update to accomodate changes in macro expansions. gas/mips/elf-rel-got-n32.d: Likewise. gas/mips/elf-rel-got-n64.d: Likewise. gas/mips/elf-rel-xgot-n32.d: Likewise. gas/mips/elf-rel-xgot-n64.d: Likewise. gas/mips/la-svr4pic.d: Likewise. gas/mips/la-xgot.d: Likewise. gas/mips/lca-svr4pic.d: Likewise. gas/mips/lca-xgot.d: Likewise.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-mips.c71
1 files changed, 37 insertions, 34 deletions
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 42efce3..66f52b0 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -4044,8 +4044,8 @@ move_register (int dest, int source)
}
/* Emit an SVR4 PIC sequence to load address LOCAL into DEST, where
- LOCAL is the sum of a symbol and a 16-bit displacement. The two
- alternatives are:
+ LOCAL is the sum of a symbol and a 16-bit or 32-bit displacement.
+ The two alternatives are:
Global symbol Local sybmol
------------- ------------
@@ -4054,7 +4054,8 @@ move_register (int dest, int source)
addiu DEST,DEST,OFFSET addiu DEST,DEST,%lo(SYMBOL + OFFSET)
load_got_offset emits the first instruction and add_got_offset
- emits the second. */
+ emits the second for a 16-bit offset or add_got_offset_hilo emits
+ a sequence to add a 32-bit offset using a scratch register. */
static void
load_got_offset (int dest, expressionS *local)
@@ -4091,6 +4092,32 @@ add_got_offset (int dest, expressionS *local)
relax_end ();
}
+static void
+add_got_offset_hilo (int dest, expressionS *local, int tmp)
+{
+ expressionS global;
+ int hold_mips_optimize;
+
+ global.X_op = O_constant;
+ global.X_op_symbol = NULL;
+ global.X_add_symbol = NULL;
+ global.X_add_number = local->X_add_number;
+
+ relax_start (local->X_add_symbol);
+ load_register (tmp, &global, HAVE_64BIT_ADDRESSES);
+ relax_switch ();
+ /* Set mips_optimize around the lui instruction to avoid
+ inserting an unnecessary nop after the lw. */
+ hold_mips_optimize = mips_optimize;
+ mips_optimize = 2;
+ macro_build_lui (&global, tmp);
+ mips_optimize = hold_mips_optimize;
+ macro_build (local, ADDRESS_ADDI_INSN, "t,r,j", tmp, tmp, BFD_RELOC_LO16);
+ relax_end ();
+
+ macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", dest, dest, tmp);
+}
+
/*
* Build macros
* This routine implements the seemingly endless macro or synthesized
@@ -4674,14 +4701,13 @@ macro (struct mips_cl_insn *ip)
macro_build (NULL, "break", "c", 7);
}
expr1.X_add_number = -1;
- macro_build (&expr1, dbl ? "daddiu" : "addiu", "t,r,j", AT, 0,
- BFD_RELOC_LO16);
+ load_register (AT, &expr1, dbl);
expr1.X_add_number = mips_trap ? (dbl ? 12 : 8) : (dbl ? 20 : 16);
macro_build (&expr1, "bne", "s,t,p", treg, AT);
if (dbl)
{
expr1.X_add_number = 1;
- macro_build (&expr1, "daddiu", "t,r,j", AT, 0, BFD_RELOC_LO16);
+ load_register (AT, &expr1, dbl);
macro_build (NULL, "dsll32", "d,w,<", AT, AT, 31);
}
else
@@ -5069,6 +5095,7 @@ macro (struct mips_cl_insn *ip)
offset_expr.X_add_number =
((offset_expr.X_add_number + 0x8000) & 0xffff) - 0x8000;
load_got_offset (tempreg, &offset_expr);
+ offset_expr.X_add_number = expr1.X_add_number;
/* If we are going to add in a base register, and the
target register and the base register are the same,
then we are using AT as a temporary register. Since
@@ -5084,17 +5111,7 @@ macro (struct mips_cl_insn *ip)
breg = 0;
tempreg = treg;
}
-
- /* Set mips_optimize around the lui instruction to avoid
- inserting an unnecessary nop after the lw. */
- hold_mips_optimize = mips_optimize;
- mips_optimize = 2;
- macro_build_lui (&expr1, AT);
- mips_optimize = hold_mips_optimize;
-
- add_got_offset (AT, &offset_expr);
- macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
- tempreg, tempreg, AT);
+ add_got_offset_hilo (tempreg, &offset_expr, AT);
used_at = 1;
}
}
@@ -5162,9 +5179,7 @@ macro (struct mips_cl_insn *ip)
add_breg_early = 1;
}
- macro_build_lui (&expr1, AT);
- macro_build (&expr1, ADDRESS_ADDI_INSN, "t,r,j",
- AT, AT, BFD_RELOC_LO16);
+ load_register (AT, &expr1, HAVE_64BIT_ADDRESSES);
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t",
dreg, dreg, AT);
@@ -5305,15 +5320,7 @@ macro (struct mips_cl_insn *ip)
dreg = treg;
}
- /* Set mips_optimize around the lui instruction to avoid
- inserting an unnecessary nop after the lw. */
- hold_mips_optimize = mips_optimize;
- mips_optimize = 2;
- macro_build_lui (&expr1, AT);
- mips_optimize = hold_mips_optimize;
-
- macro_build (&expr1, ADDRESS_ADDI_INSN, "t,r,j",
- AT, AT, BFD_RELOC_LO16);
+ load_register (AT, &expr1, HAVE_64BIT_ADDRESSES);
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", dreg, dreg, AT);
used_at = 1;
@@ -5451,11 +5458,7 @@ macro (struct mips_cl_insn *ip)
add_breg_early = 1;
}
- /* Set mips_optimize around the lui instruction to avoid
- inserting an unnecessary nop after the lw. */
- macro_build_lui (&expr1, AT);
- macro_build (&expr1, ADDRESS_ADDI_INSN, "t,r,j",
- AT, AT, BFD_RELOC_LO16);
+ load_register (AT, &expr1, HAVE_64BIT_ADDRESSES);
macro_build (NULL, ADDRESS_ADD_INSN, "d,v,t", dreg, dreg, AT);
used_at = 1;