Commit 6ab5da80 by Richard Earnshaw Committed by Richard Earnshaw

arm.c (output_call_mem): If the address references the link-register use an…

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
parent cec57f72
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment