arm.c (output_call_mem): If the address references the link-register use an instruction sequence that...
* arm.c (output_call_mem): If the address references the link-register use an instruction sequence that avoids early-clobbering IP. (eliminate_lr2ip): Delete. From-SVN: r67899
This commit is contained in:
parent
cec57f7231
commit
6ab5da8050
@ -1,3 +1,9 @@
|
||||
2003-06-13 Richard Earnshaw <rearnsha@arm.com>
|
||||
|
||||
* arm.c (output_call_mem): If the address references the link-register
|
||||
use an instruction sequence that avoids early-clobbering IP.
|
||||
(eliminate_lr2ip): Delete.
|
||||
|
||||
2003-06-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu>
|
||||
|
||||
* c-format.c (format_types_orig): Disallow '*' width/precision in
|
||||
|
@ -73,7 +73,6 @@ static int arm_legitimate_index_p (enum machine_mode, rtx, int);
|
||||
static int thumb_base_register_rtx_p (rtx, enum machine_mode, int);
|
||||
inline static int thumb_index_register_rtx_p (rtx, int);
|
||||
static int const_ok_for_op (HOST_WIDE_INT, enum rtx_code);
|
||||
static int eliminate_lr2ip (rtx *);
|
||||
static rtx emit_multi_reg_push (int);
|
||||
static rtx emit_sfm (int, int);
|
||||
#ifndef AOF_ASSEMBLER
|
||||
@ -6965,54 +6964,25 @@ output_call (rtx *operands)
|
||||
return "";
|
||||
}
|
||||
|
||||
static int
|
||||
eliminate_lr2ip (rtx *x)
|
||||
{
|
||||
int something_changed = 0;
|
||||
rtx x0 = * x;
|
||||
int code = GET_CODE (x0);
|
||||
int i, j;
|
||||
const char * fmt;
|
||||
|
||||
switch (code)
|
||||
{
|
||||
case REG:
|
||||
if (REGNO (x0) == LR_REGNUM)
|
||||
{
|
||||
*x = gen_rtx_REG (SImode, IP_REGNUM);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
default:
|
||||
/* Scan through the sub-elements and change any references there. */
|
||||
fmt = GET_RTX_FORMAT (code);
|
||||
|
||||
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
|
||||
if (fmt[i] == 'e')
|
||||
something_changed |= eliminate_lr2ip (&XEXP (x0, i));
|
||||
else if (fmt[i] == 'E')
|
||||
for (j = 0; j < XVECLEN (x0, i); j++)
|
||||
something_changed |= eliminate_lr2ip (&XVECEXP (x0, i, j));
|
||||
|
||||
return something_changed;
|
||||
}
|
||||
}
|
||||
|
||||
/* Output a 'call' insn that is a reference in memory. */
|
||||
const char *
|
||||
output_call_mem (rtx *operands)
|
||||
{
|
||||
operands[0] = copy_rtx (operands[0]); /* Be ultra careful. */
|
||||
/* Handle calls using lr by using ip (which may be clobbered in subr anyway). */
|
||||
if (eliminate_lr2ip (&operands[0]))
|
||||
output_asm_insn ("mov%?\t%|ip, %|lr", operands);
|
||||
|
||||
if (TARGET_INTERWORK)
|
||||
{
|
||||
output_asm_insn ("ldr%?\t%|ip, %0", operands);
|
||||
output_asm_insn ("mov%?\t%|lr, %|pc", operands);
|
||||
output_asm_insn ("bx%?\t%|ip", operands);
|
||||
}
|
||||
else if (regno_use_in (LR_REGNUM, operands[0]))
|
||||
{
|
||||
/* LR is used in the memory address. We load the address in the
|
||||
first instruction. It's safe to use IP as the target of the
|
||||
load since the call will kill it anyway. */
|
||||
output_asm_insn ("ldr%?\t%|ip, %0", operands);
|
||||
output_asm_insn ("mov%?\t%|lr, %|pc", operands);
|
||||
output_asm_insn ("mov%?\t%|pc, %|ip", operands);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_asm_insn ("mov%?\t%|lr, %|pc", operands);
|
||||
|
Loading…
Reference in New Issue
Block a user