crti.asm: Add changes for mips16.
2002-02-05 Eric Christopher <echristo@redhat.com> * config/mips/crti.asm: Add changes for mips16. mips16 uses register 7 as RA instead of $31. * config/mips/crtn.asm: Ditto. * config/mips/mips.c (mips_move_2words): Add case for TARGET_MIPS16 when HOST_BITS_PER_WIDE_INT >= 64. (compute_frame_size): Fix typo. (save_restore_insns): Ditto. Make documentation about using register $7 as return register more precise. (mips_expand_epilogue): Fix comment. Add code to work around not being able to add to the stack pointer directly. * config/mips/mips.h (EH_RETURN_DATA_REGNO): Change register number to 2 for TARGET_MIPS16 as we need 6 and 7 as clobbers in the epilogue. From-SVN: r49535
This commit is contained in:
parent
8c78e3a3cd
commit
282cb01bc2
4 changed files with 71 additions and 15 deletions
|
@ -6,10 +6,10 @@
|
|||
.type _init,@function
|
||||
_init:
|
||||
#ifdef __mips64
|
||||
dsubu $sp,$sp,48
|
||||
daddu $sp,$sp,-48
|
||||
sd $31,40($sp)
|
||||
#else
|
||||
subu $sp,$sp,32
|
||||
addu $sp,$sp,-32
|
||||
sw $31,20($sp)
|
||||
#endif
|
||||
|
||||
|
@ -18,9 +18,9 @@ _init:
|
|||
.type _fini,@function
|
||||
_fini:
|
||||
#ifdef __mips64
|
||||
dsubu $sp,$sp,48
|
||||
daddu $sp,$sp,-48
|
||||
sd $31,40($sp)
|
||||
#else
|
||||
subu $sp,$sp,32
|
||||
addu $sp,$sp,-32
|
||||
sw $31,20($sp)
|
||||
#endif
|
||||
|
|
|
@ -6,17 +6,37 @@
|
|||
ld $31,40($sp)
|
||||
daddu $sp,$sp,48
|
||||
#else
|
||||
#ifndef __mips16
|
||||
lw $31,20($sp)
|
||||
addu $sp,$sp,32
|
||||
#else
|
||||
/* The mips16 uses $7 for a return address. We use that here too. */
|
||||
lw $7,20($sp)
|
||||
addu $sp,$sp,32
|
||||
|
||||
j $7
|
||||
#endif
|
||||
#endif
|
||||
#ifndef __mips16
|
||||
j $31
|
||||
#endif
|
||||
|
||||
.section .fini,"ax",@progbits
|
||||
#ifdef __mips64
|
||||
ld $31,40($sp)
|
||||
daddu $sp,$sp,48
|
||||
#else
|
||||
#ifndef __mips16
|
||||
lw $31,20($sp)
|
||||
addu $sp,$sp,32
|
||||
#else
|
||||
/* The mips16 uses $7 for a return address. We use that here too. */
|
||||
lw $7,20($sp)
|
||||
addu $sp,$sp,32
|
||||
|
||||
j $7
|
||||
#endif
|
||||
#endif
|
||||
#ifndef __mips16
|
||||
j $31
|
||||
#endif
|
||||
|
|
|
@ -2557,7 +2557,18 @@ mips_move_2words (operands, insn)
|
|||
operands[2] = GEN_INT (INTVAL (operands[1]) >> 16 >> 16);
|
||||
operands[1]
|
||||
= GEN_INT (INTVAL (operands[1]) << 16 << 16 >> 16 >> 16);
|
||||
ret = "li\t%M0,%2\n\tli\t%L0,%1";
|
||||
if (TARGET_MIPS16)
|
||||
{
|
||||
if (INTVAL (op1) >= 0 && INTVAL (op1) <= 0xffff)
|
||||
ret = "li\t%M0,%2\n\tli\t%L0,%1";
|
||||
else if (INTVAL (op1) < 0 && INTVAL (op1) >= -0xffff)
|
||||
{
|
||||
operands[2] = GEN_INT (1);
|
||||
ret = "li\t%M0,%2\n\tneg\t%M0\n\tli\t%L0,%n1\n\tneg\t%L0";
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = "li\t%M0,%2\n\tli\t%L0,%1";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6445,7 +6456,7 @@ compute_frame_size (size)
|
|||
}
|
||||
|
||||
/* This loop must iterate over the same space as its companion in
|
||||
save_restore_regs. */
|
||||
save_restore_insns. */
|
||||
for (regno = (FP_REG_LAST - fp_inc + 1);
|
||||
regno >= FP_REG_FIRST;
|
||||
regno -= fp_inc)
|
||||
|
@ -6673,7 +6684,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
|
|||
if (! store_p
|
||||
&& TARGET_ABICALLS
|
||||
&& (mips_abi == ABI_32 || mips_abi == ABI_O64))
|
||||
mask &= ~(1 << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST));
|
||||
mask &= ~(1L << (PIC_OFFSET_TABLE_REGNUM - GP_REG_FIRST));
|
||||
|
||||
if (mask == 0 && fmask == 0)
|
||||
return;
|
||||
|
@ -6767,7 +6778,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
|
|||
|
||||
/* The mips16 does not have an instruction to load
|
||||
$31, so we load $7 instead, and work things out
|
||||
in the caller. */
|
||||
in mips_expand_epilogue. */
|
||||
if (TARGET_MIPS16 && ! store_p && regno == GP_REG_FIRST + 31)
|
||||
reg_rtx = gen_rtx (REG, gpr_mode, GP_REG_FIRST + 7);
|
||||
/* The mips16 sometimes needs to save $18. */
|
||||
|
@ -7653,7 +7664,7 @@ mips_expand_epilogue ()
|
|||
{
|
||||
tsize -= current_function_outgoing_args_size;
|
||||
|
||||
/* If we have a large frame, it's easier to add to $17
|
||||
/* If we have a large frame, it's easier to add to $6
|
||||
than to $sp, since the mips16 has no instruction to
|
||||
add a register to $sp. */
|
||||
if (orig_tsize > 32767)
|
||||
|
@ -7713,12 +7724,37 @@ mips_expand_epilogue ()
|
|||
|
||||
if (tsize != 0 || current_function_calls_eh_return)
|
||||
{
|
||||
if (Pmode == DImode)
|
||||
emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
tsize_rtx));
|
||||
if (!TARGET_MIPS16)
|
||||
{
|
||||
if (Pmode == DImode)
|
||||
emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
tsize_rtx));
|
||||
else
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
tsize_rtx));
|
||||
}
|
||||
else
|
||||
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
|
||||
tsize_rtx));
|
||||
{
|
||||
/* We need to work around not being able to add a register
|
||||
to the stack pointer directly. Use register $6 as an
|
||||
intermediate step. */
|
||||
|
||||
rtx g6_rtx = gen_rtx (REG, Pmode, GP_REG_FIRST + 6);
|
||||
|
||||
if (Pmode == DImode)
|
||||
{
|
||||
emit_insn (gen_movdi (g6_rtx, stack_pointer_rtx));
|
||||
emit_insn (gen_adddi3 (g6_rtx, g6_rtx, tsize_rtx));
|
||||
emit_insn (gen_movdi (stack_pointer_rtx, g6_rtx));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_movsi (g6_rtx, stack_pointer_rtx));
|
||||
emit_insn (gen_addsi3 (g6_rtx, g6_rtx, tsize_rtx));
|
||||
emit_insn (gen_movsi (stack_pointer_rtx, g6_rtx));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1369,7 +1369,7 @@ extern int mips_abi;
|
|||
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31)
|
||||
|
||||
/* Describe how we implement __builtin_eh_return. */
|
||||
#define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
|
||||
#define EH_RETURN_DATA_REGNO(N) ((N) < (TARGET_MIPS16 ? 2 : 4) ? (N) + GP_ARG_FIRST : INVALID_REGNUM)
|
||||
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_REG_FIRST + 3)
|
||||
|
||||
/* Offsets recorded in opcodes are a multiple of this alignment factor.
|
||||
|
|
Loading…
Add table
Reference in a new issue