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:
Richard Earnshaw 2003-06-13 14:30:38 +00:00 committed by Richard Earnshaw
parent cec57f7231
commit 6ab5da8050
2 changed files with 15 additions and 39 deletions

View File

@ -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

View File

@ -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);