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
|
.type _init,@function
|
||||||
_init:
|
_init:
|
||||||
#ifdef __mips64
|
#ifdef __mips64
|
||||||
dsubu $sp,$sp,48
|
daddu $sp,$sp,-48
|
||||||
sd $31,40($sp)
|
sd $31,40($sp)
|
||||||
#else
|
#else
|
||||||
subu $sp,$sp,32
|
addu $sp,$sp,-32
|
||||||
sw $31,20($sp)
|
sw $31,20($sp)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -18,9 +18,9 @@ _init:
|
||||||
.type _fini,@function
|
.type _fini,@function
|
||||||
_fini:
|
_fini:
|
||||||
#ifdef __mips64
|
#ifdef __mips64
|
||||||
dsubu $sp,$sp,48
|
daddu $sp,$sp,-48
|
||||||
sd $31,40($sp)
|
sd $31,40($sp)
|
||||||
#else
|
#else
|
||||||
subu $sp,$sp,32
|
addu $sp,$sp,-32
|
||||||
sw $31,20($sp)
|
sw $31,20($sp)
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,17 +6,37 @@
|
||||||
ld $31,40($sp)
|
ld $31,40($sp)
|
||||||
daddu $sp,$sp,48
|
daddu $sp,$sp,48
|
||||||
#else
|
#else
|
||||||
|
#ifndef __mips16
|
||||||
lw $31,20($sp)
|
lw $31,20($sp)
|
||||||
addu $sp,$sp,32
|
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
|
||||||
|
#endif
|
||||||
|
#ifndef __mips16
|
||||||
j $31
|
j $31
|
||||||
|
#endif
|
||||||
|
|
||||||
.section .fini,"ax",@progbits
|
.section .fini,"ax",@progbits
|
||||||
#ifdef __mips64
|
#ifdef __mips64
|
||||||
ld $31,40($sp)
|
ld $31,40($sp)
|
||||||
daddu $sp,$sp,48
|
daddu $sp,$sp,48
|
||||||
#else
|
#else
|
||||||
|
#ifndef __mips16
|
||||||
lw $31,20($sp)
|
lw $31,20($sp)
|
||||||
addu $sp,$sp,32
|
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
|
||||||
|
#endif
|
||||||
|
#ifndef __mips16
|
||||||
j $31
|
j $31
|
||||||
|
#endif
|
||||||
|
|
|
@ -2557,7 +2557,18 @@ mips_move_2words (operands, insn)
|
||||||
operands[2] = GEN_INT (INTVAL (operands[1]) >> 16 >> 16);
|
operands[2] = GEN_INT (INTVAL (operands[1]) >> 16 >> 16);
|
||||||
operands[1]
|
operands[1]
|
||||||
= GEN_INT (INTVAL (operands[1]) << 16 << 16 >> 16 >> 16);
|
= 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
|
/* 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);
|
for (regno = (FP_REG_LAST - fp_inc + 1);
|
||||||
regno >= FP_REG_FIRST;
|
regno >= FP_REG_FIRST;
|
||||||
regno -= fp_inc)
|
regno -= fp_inc)
|
||||||
|
@ -6673,7 +6684,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
|
||||||
if (! store_p
|
if (! store_p
|
||||||
&& TARGET_ABICALLS
|
&& TARGET_ABICALLS
|
||||||
&& (mips_abi == ABI_32 || mips_abi == ABI_O64))
|
&& (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)
|
if (mask == 0 && fmask == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -6767,7 +6778,7 @@ save_restore_insns (store_p, large_reg, large_offset, file)
|
||||||
|
|
||||||
/* The mips16 does not have an instruction to load
|
/* The mips16 does not have an instruction to load
|
||||||
$31, so we load $7 instead, and work things out
|
$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)
|
if (TARGET_MIPS16 && ! store_p && regno == GP_REG_FIRST + 31)
|
||||||
reg_rtx = gen_rtx (REG, gpr_mode, GP_REG_FIRST + 7);
|
reg_rtx = gen_rtx (REG, gpr_mode, GP_REG_FIRST + 7);
|
||||||
/* The mips16 sometimes needs to save $18. */
|
/* The mips16 sometimes needs to save $18. */
|
||||||
|
@ -7653,7 +7664,7 @@ mips_expand_epilogue ()
|
||||||
{
|
{
|
||||||
tsize -= current_function_outgoing_args_size;
|
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
|
than to $sp, since the mips16 has no instruction to
|
||||||
add a register to $sp. */
|
add a register to $sp. */
|
||||||
if (orig_tsize > 32767)
|
if (orig_tsize > 32767)
|
||||||
|
@ -7713,12 +7724,37 @@ mips_expand_epilogue ()
|
||||||
|
|
||||||
if (tsize != 0 || current_function_calls_eh_return)
|
if (tsize != 0 || current_function_calls_eh_return)
|
||||||
{
|
{
|
||||||
if (Pmode == DImode)
|
if (!TARGET_MIPS16)
|
||||||
emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
|
{
|
||||||
tsize_rtx));
|
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
|
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)
|
#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (VOIDmode, GP_REG_FIRST + 31)
|
||||||
|
|
||||||
/* Describe how we implement __builtin_eh_return. */
|
/* 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)
|
#define EH_RETURN_STACKADJ_RTX gen_rtx_REG (Pmode, GP_REG_FIRST + 3)
|
||||||
|
|
||||||
/* Offsets recorded in opcodes are a multiple of this alignment factor.
|
/* Offsets recorded in opcodes are a multiple of this alignment factor.
|
||||||
|
|
Loading…
Add table
Reference in a new issue