re PR target/11535 (__builtin_return_address may not work on ia64)
PR target/11535 * config/ia64/ia64.c (ia64_initial_elimination_offset): Remove RETURN_ADDRESS_POINTER_REGNUM. (ia64_expand_prologue): Don't frob it. (ia64_output_function_epilogue): Likewise. (ia64_return_addr_rtx): New. (ia64_split_return_addr_rtx): New. * config/ia64/ia64-protos.h: Update. * config/ia64/ia64.h (FIRST_PSEUDO_REGISTER): Decrement. (RETURN_ADDRESS_POINTER_REGNUM): Remove. (GENERAL_REGNO_P): Don't check it. (AR_*_REGNUM): Renumber. (FIXED_REGISTERS): Remove RETURN_ADDRESS_POINTER_REGNUM. (CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS): Likewise. (REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Likewise. (ELIMINABLE_REGS, REGISTER_NAMES): Likewise. (RETURN_ADDR_RTX): Use ia64_return_addr_rtx. * config/ia64/ia64.md (UNSPEC_RET_ADDR): New. (movdi_ret_addr): New. From-SVN: r70263
This commit is contained in:
parent
5dddb92059
commit
af1e551876
|
@ -1,3 +1,25 @@
|
||||||
|
2003-08-08 Richard Henderson <rth@redhat.com>
|
||||||
|
|
||||||
|
PR target/11535
|
||||||
|
* config/ia64/ia64.c (ia64_initial_elimination_offset): Remove
|
||||||
|
RETURN_ADDRESS_POINTER_REGNUM.
|
||||||
|
(ia64_expand_prologue): Don't frob it.
|
||||||
|
(ia64_output_function_epilogue): Likewise.
|
||||||
|
(ia64_return_addr_rtx): New.
|
||||||
|
(ia64_split_return_addr_rtx): New.
|
||||||
|
* config/ia64/ia64-protos.h: Update.
|
||||||
|
* config/ia64/ia64.h (FIRST_PSEUDO_REGISTER): Decrement.
|
||||||
|
(RETURN_ADDRESS_POINTER_REGNUM): Remove.
|
||||||
|
(GENERAL_REGNO_P): Don't check it.
|
||||||
|
(AR_*_REGNUM): Renumber.
|
||||||
|
(FIXED_REGISTERS): Remove RETURN_ADDRESS_POINTER_REGNUM.
|
||||||
|
(CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS): Likewise.
|
||||||
|
(REG_ALLOC_ORDER, REG_CLASS_CONTENTS): Likewise.
|
||||||
|
(ELIMINABLE_REGS, REGISTER_NAMES): Likewise.
|
||||||
|
(RETURN_ADDR_RTX): Use ia64_return_addr_rtx.
|
||||||
|
* config/ia64/ia64.md (UNSPEC_RET_ADDR): New.
|
||||||
|
(movdi_ret_addr): New.
|
||||||
|
|
||||||
2003-08-08 Geoffrey Keating <geoffk@apple.com>
|
2003-08-08 Geoffrey Keating <geoffk@apple.com>
|
||||||
|
|
||||||
* config.gcc (powerpc-*-darwin*): Don't build a soft-float multilib.
|
* config.gcc (powerpc-*-darwin*): Don't build a soft-float multilib.
|
||||||
|
|
|
@ -139,6 +139,9 @@ extern void ia64_init_builtins PARAMS((void));
|
||||||
extern void ia64_override_options PARAMS((void));
|
extern void ia64_override_options PARAMS((void));
|
||||||
extern int ia64_dbx_register_number PARAMS((int));
|
extern int ia64_dbx_register_number PARAMS((int));
|
||||||
|
|
||||||
|
extern rtx ia64_return_addr_rtx PARAMS ((HOST_WIDE_INT, rtx));
|
||||||
|
extern void ia64_split_return_addr_rtx PARAMS ((rtx));
|
||||||
|
|
||||||
#ifdef SDATA_SECTION_ASM_OP
|
#ifdef SDATA_SECTION_ASM_OP
|
||||||
extern void sdata_section PARAMS ((void));
|
extern void sdata_section PARAMS ((void));
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -2197,10 +2197,6 @@ ia64_initial_elimination_offset (from, to)
|
||||||
abort ();
|
abort ();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RETURN_ADDRESS_POINTER_REGNUM:
|
|
||||||
offset = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
@ -2551,17 +2547,6 @@ ia64_expand_prologue ()
|
||||||
reg_names[current_frame_info.reg_fp] = tmp;
|
reg_names[current_frame_info.reg_fp] = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fix up the return address placeholder. */
|
|
||||||
/* ??? We can fail if __builtin_return_address is used, and we didn't
|
|
||||||
allocate a register in which to save b0. I can't think of a way to
|
|
||||||
eliminate RETURN_ADDRESS_POINTER_REGNUM to a local register and
|
|
||||||
then be sure that I got the right one. Further, reload doesn't seem
|
|
||||||
to care if an eliminable register isn't used, and "eliminates" it
|
|
||||||
anyway. */
|
|
||||||
if (regs_ever_live[RETURN_ADDRESS_POINTER_REGNUM]
|
|
||||||
&& current_frame_info.reg_save_b0 != 0)
|
|
||||||
XINT (return_address_pointer_rtx, 0) = current_frame_info.reg_save_b0;
|
|
||||||
|
|
||||||
/* We don't need an alloc instruction if we've used no outputs or locals. */
|
/* We don't need an alloc instruction if we've used no outputs or locals. */
|
||||||
if (current_frame_info.n_local_regs == 0
|
if (current_frame_info.n_local_regs == 0
|
||||||
&& current_frame_info.n_output_regs == 0
|
&& current_frame_info.n_output_regs == 0
|
||||||
|
@ -3118,6 +3103,72 @@ ia64_direct_return ()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the magic cookie that we use to hold the return address
|
||||||
|
during early compilation. */
|
||||||
|
|
||||||
|
rtx
|
||||||
|
ia64_return_addr_rtx (count, frame)
|
||||||
|
HOST_WIDE_INT count;
|
||||||
|
rtx frame ATTRIBUTE_UNUSED;
|
||||||
|
{
|
||||||
|
if (count != 0)
|
||||||
|
return NULL;
|
||||||
|
return gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx), UNSPEC_RET_ADDR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Split this value after reload, now that we know where the return
|
||||||
|
address is saved. */
|
||||||
|
|
||||||
|
void
|
||||||
|
ia64_split_return_addr_rtx (dest)
|
||||||
|
rtx dest;
|
||||||
|
{
|
||||||
|
rtx src;
|
||||||
|
|
||||||
|
if (TEST_HARD_REG_BIT (current_frame_info.mask, BR_REG (0)))
|
||||||
|
{
|
||||||
|
if (current_frame_info.reg_save_b0 != 0)
|
||||||
|
src = gen_rtx_REG (DImode, current_frame_info.reg_save_b0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HOST_WIDE_INT off;
|
||||||
|
unsigned int regno;
|
||||||
|
|
||||||
|
/* Compute offset from CFA for BR0. */
|
||||||
|
/* ??? Must be kept in sync with ia64_expand_prologue. */
|
||||||
|
off = (current_frame_info.spill_cfa_off
|
||||||
|
+ current_frame_info.spill_size);
|
||||||
|
for (regno = GR_REG (1); regno <= GR_REG (31); ++regno)
|
||||||
|
if (TEST_HARD_REG_BIT (current_frame_info.mask, regno))
|
||||||
|
off -= 8;
|
||||||
|
|
||||||
|
/* Convert CFA offset to a register based offset. */
|
||||||
|
if (frame_pointer_needed)
|
||||||
|
src = hard_frame_pointer_rtx;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
src = stack_pointer_rtx;
|
||||||
|
off += current_frame_info.total_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load address into scratch register. */
|
||||||
|
if (CONST_OK_FOR_I (off))
|
||||||
|
emit_insn (gen_adddi3 (dest, src, GEN_INT (off)));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit_move_insn (dest, GEN_INT (off));
|
||||||
|
emit_insn (gen_adddi3 (dest, src, dest));
|
||||||
|
}
|
||||||
|
|
||||||
|
src = gen_rtx_MEM (Pmode, dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
src = gen_rtx_REG (DImode, BR_REG (0));
|
||||||
|
|
||||||
|
emit_move_insn (dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
ia64_hard_regno_rename_ok (from, to)
|
ia64_hard_regno_rename_ok (from, to)
|
||||||
int from;
|
int from;
|
||||||
|
@ -3267,9 +3318,6 @@ ia64_output_function_epilogue (file, size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Reset from the function's potential modifications. */
|
|
||||||
XINT (return_address_pointer_rtx, 0) = RETURN_ADDRESS_POINTER_REGNUM;
|
|
||||||
|
|
||||||
if (current_frame_info.reg_fp)
|
if (current_frame_info.reg_fp)
|
||||||
{
|
{
|
||||||
const char *tmp = reg_names[HARD_FRAME_POINTER_REGNUM];
|
const char *tmp = reg_names[HARD_FRAME_POINTER_REGNUM];
|
||||||
|
|
|
@ -455,7 +455,7 @@ while (0)
|
||||||
64 predicate registers, 8 branch registers, one frame pointer,
|
64 predicate registers, 8 branch registers, one frame pointer,
|
||||||
and several "application" registers. */
|
and several "application" registers. */
|
||||||
|
|
||||||
#define FIRST_PSEUDO_REGISTER 335
|
#define FIRST_PSEUDO_REGISTER 334
|
||||||
|
|
||||||
/* Ranges for the various kinds of registers. */
|
/* Ranges for the various kinds of registers. */
|
||||||
#define ADDL_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 3)
|
#define ADDL_REGNO_P(REGNO) ((unsigned HOST_WIDE_INT) (REGNO) <= 3)
|
||||||
|
@ -464,9 +464,7 @@ while (0)
|
||||||
#define PR_REGNO_P(REGNO) ((REGNO) >= 256 && (REGNO) <= 319)
|
#define PR_REGNO_P(REGNO) ((REGNO) >= 256 && (REGNO) <= 319)
|
||||||
#define BR_REGNO_P(REGNO) ((REGNO) >= 320 && (REGNO) <= 327)
|
#define BR_REGNO_P(REGNO) ((REGNO) >= 320 && (REGNO) <= 327)
|
||||||
#define GENERAL_REGNO_P(REGNO) \
|
#define GENERAL_REGNO_P(REGNO) \
|
||||||
(GR_REGNO_P (REGNO) \
|
(GR_REGNO_P (REGNO) || (REGNO) == FRAME_POINTER_REGNUM)
|
||||||
|| (REGNO) == FRAME_POINTER_REGNUM \
|
|
||||||
|| (REGNO) == RETURN_ADDRESS_POINTER_REGNUM)
|
|
||||||
|
|
||||||
#define GR_REG(REGNO) ((REGNO) + 0)
|
#define GR_REG(REGNO) ((REGNO) + 0)
|
||||||
#define FR_REG(REGNO) ((REGNO) + 128)
|
#define FR_REG(REGNO) ((REGNO) + 128)
|
||||||
|
@ -476,11 +474,11 @@ while (0)
|
||||||
#define IN_REG(REGNO) ((REGNO) + 112)
|
#define IN_REG(REGNO) ((REGNO) + 112)
|
||||||
#define LOC_REG(REGNO) ((REGNO) + 32)
|
#define LOC_REG(REGNO) ((REGNO) + 32)
|
||||||
|
|
||||||
#define AR_CCV_REGNUM 330
|
#define AR_CCV_REGNUM 329
|
||||||
#define AR_UNAT_REGNUM 331
|
#define AR_UNAT_REGNUM 330
|
||||||
#define AR_PFS_REGNUM 332
|
#define AR_PFS_REGNUM 331
|
||||||
#define AR_LC_REGNUM 333
|
#define AR_LC_REGNUM 332
|
||||||
#define AR_EC_REGNUM 334
|
#define AR_EC_REGNUM 333
|
||||||
|
|
||||||
#define IN_REGNO_P(REGNO) ((REGNO) >= IN_REG (0) && (REGNO) <= IN_REG (7))
|
#define IN_REGNO_P(REGNO) ((REGNO) >= IN_REG (0) && (REGNO) <= IN_REG (7))
|
||||||
#define LOC_REGNO_P(REGNO) ((REGNO) >= LOC_REG (0) && (REGNO) <= LOC_REG (79))
|
#define LOC_REGNO_P(REGNO) ((REGNO) >= LOC_REG (0) && (REGNO) <= LOC_REG (79))
|
||||||
|
@ -543,8 +541,8 @@ while (0)
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||||
/* Branch registers. */ \
|
/* Branch registers. */ \
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, \
|
0, 0, 0, 0, 0, 0, 0, 0, \
|
||||||
/*FP RA CCV UNAT PFS LC EC */ \
|
/*FP CCV UNAT PFS LC EC */ \
|
||||||
1, 1, 1, 1, 1, 0, 1 \
|
1, 1, 1, 1, 0, 1 \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered
|
/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered
|
||||||
|
@ -578,8 +576,8 @@ while (0)
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||||
/* Branch registers. */ \
|
/* Branch registers. */ \
|
||||||
1, 0, 0, 0, 0, 0, 1, 1, \
|
1, 0, 0, 0, 0, 0, 1, 1, \
|
||||||
/*FP RA CCV UNAT PFS LC EC */ \
|
/*FP CCV UNAT PFS LC EC */ \
|
||||||
1, 1, 1, 1, 1, 0, 1 \
|
1, 1, 1, 1, 0, 1 \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
|
/* Like `CALL_USED_REGISTERS' but used to overcome a historical
|
||||||
|
@ -616,8 +614,8 @@ while (0)
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
|
||||||
/* Branch registers. */ \
|
/* Branch registers. */ \
|
||||||
1, 0, 0, 0, 0, 0, 1, 1, \
|
1, 0, 0, 0, 0, 0, 1, 1, \
|
||||||
/*FP RA CCV UNAT PFS LC EC */ \
|
/*FP CCV UNAT PFS LC EC */ \
|
||||||
0, 0, 1, 0, 1, 0, 0 \
|
0, 1, 0, 1, 0, 0 \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -763,7 +761,7 @@ while (0)
|
||||||
/* Special branch registers. */ \
|
/* Special branch registers. */ \
|
||||||
R_BR (0), \
|
R_BR (0), \
|
||||||
/* Other fixed registers. */ \
|
/* Other fixed registers. */ \
|
||||||
FRAME_POINTER_REGNUM, RETURN_ADDRESS_POINTER_REGNUM, \
|
FRAME_POINTER_REGNUM, \
|
||||||
AR_CCV_REGNUM, AR_UNAT_REGNUM, AR_PFS_REGNUM, AR_LC_REGNUM, \
|
AR_CCV_REGNUM, AR_UNAT_REGNUM, AR_PFS_REGNUM, AR_LC_REGNUM, \
|
||||||
AR_EC_REGNUM \
|
AR_EC_REGNUM \
|
||||||
}
|
}
|
||||||
|
@ -892,11 +890,11 @@ enum reg_class
|
||||||
/* AR_M_REGS. */ \
|
/* AR_M_REGS. */ \
|
||||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0x00000000, 0x00000000, 0x0C00 }, \
|
0x00000000, 0x00000000, 0x0600 }, \
|
||||||
/* AR_I_REGS. */ \
|
/* AR_I_REGS. */ \
|
||||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0x00000000, 0x00000000, 0x7000 }, \
|
0x00000000, 0x00000000, 0x3800 }, \
|
||||||
/* ADDL_REGS. */ \
|
/* ADDL_REGS. */ \
|
||||||
{ 0x0000000F, 0x00000000, 0x00000000, 0x00000000, \
|
{ 0x0000000F, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
|
@ -904,7 +902,7 @@ enum reg_class
|
||||||
/* GR_REGS. */ \
|
/* GR_REGS. */ \
|
||||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0x00000000, 0x00000000, 0x0300 }, \
|
0x00000000, 0x00000000, 0x0100 }, \
|
||||||
/* FR_REGS. */ \
|
/* FR_REGS. */ \
|
||||||
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
||||||
|
@ -912,15 +910,15 @@ enum reg_class
|
||||||
/* GR_AND_BR_REGS. */ \
|
/* GR_AND_BR_REGS. */ \
|
||||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
||||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
0x00000000, 0x00000000, 0x00000000, 0x00000000, \
|
||||||
0x00000000, 0x00000000, 0x03FF }, \
|
0x00000000, 0x00000000, 0x01FF }, \
|
||||||
/* GR_AND_FR_REGS. */ \
|
/* GR_AND_FR_REGS. */ \
|
||||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
||||||
0x00000000, 0x00000000, 0x0300 }, \
|
0x00000000, 0x00000000, 0x0100 }, \
|
||||||
/* ALL_REGS. */ \
|
/* ALL_REGS. */ \
|
||||||
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, \
|
||||||
0xFFFFFFFF, 0xFFFFFFFF, 0x7FFF }, \
|
0xFFFFFFFF, 0xFFFFFFFF, 0x3FFF }, \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A C expression whose value is a register class containing hard register
|
/* A C expression whose value is a register class containing hard register
|
||||||
|
@ -1142,7 +1140,7 @@ enum reg_class
|
||||||
DYNAMIC_CHAIN_ADDRESS and SETUP_FRAME_ADDRESS (for the reg stack flush). */
|
DYNAMIC_CHAIN_ADDRESS and SETUP_FRAME_ADDRESS (for the reg stack flush). */
|
||||||
|
|
||||||
#define RETURN_ADDR_RTX(COUNT, FRAME) \
|
#define RETURN_ADDR_RTX(COUNT, FRAME) \
|
||||||
((COUNT) == 0 ? return_address_pointer_rtx : const0_rtx)
|
ia64_return_addr_rtx (COUNT, FRAME)
|
||||||
|
|
||||||
/* A C expression whose value is RTL representing the location of the incoming
|
/* A C expression whose value is RTL representing the location of the incoming
|
||||||
return address at the beginning of any function, before the prologue. This
|
return address at the beginning of any function, before the prologue. This
|
||||||
|
@ -1203,13 +1201,6 @@ enum reg_class
|
||||||
REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = 64; \
|
REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = 64; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/* The register number for the return address register. For IA-64, this
|
|
||||||
is not actually a pointer as the name suggests, but that's a name that
|
|
||||||
gen_rtx_REG already takes care to keep unique. We modify
|
|
||||||
return_address_pointer_rtx in ia64_expand_prologue to reference the
|
|
||||||
final output regnum. */
|
|
||||||
#define RETURN_ADDRESS_POINTER_REGNUM 329
|
|
||||||
|
|
||||||
/* Register numbers used for passing a function's static chain pointer. */
|
/* Register numbers used for passing a function's static chain pointer. */
|
||||||
/* ??? The ABI sez the static chain should be passed as a normal parameter. */
|
/* ??? The ABI sez the static chain should be passed as a normal parameter. */
|
||||||
#define STATIC_CHAIN_REGNUM 15
|
#define STATIC_CHAIN_REGNUM 15
|
||||||
|
@ -1233,7 +1224,6 @@ enum reg_class
|
||||||
{ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
{ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
||||||
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
{FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
|
||||||
{FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
{FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}, \
|
||||||
{RETURN_ADDRESS_POINTER_REGNUM, BR_REG (0)}, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A C expression that returns nonzero if the compiler is allowed to try to
|
/* A C expression that returns nonzero if the compiler is allowed to try to
|
||||||
|
@ -1879,8 +1869,8 @@ do { \
|
||||||
"p60", "p61", "p62", "p63", \
|
"p60", "p61", "p62", "p63", \
|
||||||
/* Branch registers. */ \
|
/* Branch registers. */ \
|
||||||
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
|
"b0", "b1", "b2", "b3", "b4", "b5", "b6", "b7", \
|
||||||
/* Frame pointer. Return address. */ \
|
/* Frame pointer. Application registers. */ \
|
||||||
"sfp", "retaddr", "ar.ccv", "ar.unat", "ar.pfs", "ar.lc", "ar.ec", \
|
"sfp", "ar.ccv", "ar.unat", "ar.pfs", "ar.lc", "ar.ec", \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If defined, a C initializer for an array of structures containing a name and
|
/* If defined, a C initializer for an array of structures containing a name and
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
(UNSPEC_BUNDLE_SELECTOR 23)
|
(UNSPEC_BUNDLE_SELECTOR 23)
|
||||||
(UNSPEC_ADDP4 24)
|
(UNSPEC_ADDP4 24)
|
||||||
(UNSPEC_PROLOGUE_USE 25)
|
(UNSPEC_PROLOGUE_USE 25)
|
||||||
|
(UNSPEC_RET_ADDR 26)
|
||||||
])
|
])
|
||||||
|
|
||||||
(define_constants
|
(define_constants
|
||||||
|
@ -410,6 +411,25 @@
|
||||||
operands[3] = pic_offset_table_rtx;
|
operands[3] = pic_offset_table_rtx;
|
||||||
})
|
})
|
||||||
|
|
||||||
|
;; This is used as a placeholder for the return address during early
|
||||||
|
;; compilation. We won't know where we've placed this until during
|
||||||
|
;; reload, at which point it can wind up in b0, a general register,
|
||||||
|
;; or memory. The only safe destination under these conditions is a
|
||||||
|
;; general register.
|
||||||
|
|
||||||
|
(define_insn_and_split "*movdi_ret_addr"
|
||||||
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
|
(unspec:DI [(const_int 0)] UNSPEC_RET_ADDR))]
|
||||||
|
""
|
||||||
|
"#"
|
||||||
|
"reload_completed"
|
||||||
|
[(const_int 0)]
|
||||||
|
{
|
||||||
|
ia64_split_return_addr_rtx (operands[0]);
|
||||||
|
DONE;
|
||||||
|
}
|
||||||
|
[(set_attr "itanium_class" "ialu")])
|
||||||
|
|
||||||
(define_insn "*load_symptr_high"
|
(define_insn "*load_symptr_high"
|
||||||
[(set (match_operand:DI 0 "register_operand" "=r")
|
[(set (match_operand:DI 0 "register_operand" "=r")
|
||||||
(plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
|
(plus:DI (high:DI (match_operand 1 "got_symbolic_operand" "s"))
|
||||||
|
|
Loading…
Reference in New Issue