Commit 282cb01b by Eric Christopher

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
parent 8c78e3a3
...@@ -6,10 +6,10 @@ ...@@ -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: ...@@ -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 @@ ...@@ -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,6 +2557,17 @@ mips_move_2words (operands, insn) ...@@ -2557,6 +2557,17 @@ 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);
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"; ret = "li\t%M0,%2\n\tli\t%L0,%1";
} }
} }
...@@ -6445,7 +6456,7 @@ compute_frame_size (size) ...@@ -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) ...@@ -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) ...@@ -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 () ...@@ -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,6 +7724,8 @@ mips_expand_epilogue () ...@@ -7713,6 +7724,8 @@ mips_expand_epilogue ()
if (tsize != 0 || current_function_calls_eh_return) if (tsize != 0 || current_function_calls_eh_return)
{ {
if (!TARGET_MIPS16)
{
if (Pmode == DImode) if (Pmode == DImode)
emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx, emit_insn (gen_adddi3 (stack_pointer_rtx, stack_pointer_rtx,
tsize_rtx)); tsize_rtx));
...@@ -7720,6 +7733,29 @@ mips_expand_epilogue () ...@@ -7720,6 +7733,29 @@ mips_expand_epilogue ()
emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
tsize_rtx)); tsize_rtx));
} }
else
{
/* 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));
}
}
}
} }
/* The mips16 loads the return address into $7, not $31. */ /* The mips16 loads the return address into $7, not $31. */
......
...@@ -1369,7 +1369,7 @@ extern int mips_abi; ...@@ -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.
......
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