aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Christopher <echristo@gcc.gnu.org>2002-02-06 02:50:09 +0000
committerEric Christopher <echristo@gcc.gnu.org>2002-02-06 02:50:09 +0000
commit282cb01bc29cdac825eedc4b8ad74085c2d76918 (patch)
tree9337895f122027be87b47a40122704463955bf79
parent8c78e3a3cdfb624d8f2d232a2d03ee78c6e633eb (diff)
downloadgcc-282cb01bc29cdac825eedc4b8ad74085c2d76918.zip
gcc-282cb01bc29cdac825eedc4b8ad74085c2d76918.tar.gz
gcc-282cb01bc29cdac825eedc4b8ad74085c2d76918.tar.bz2
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
-rw-r--r--gcc/config/mips/crti.asm8
-rw-r--r--gcc/config/mips/crtn.asm20
-rw-r--r--gcc/config/mips/mips.c56
-rw-r--r--gcc/config/mips/mips.h2
4 files changed, 71 insertions, 15 deletions
diff --git a/gcc/config/mips/crti.asm b/gcc/config/mips/crti.asm
index 6452d1e..f4bef6f 100644
--- a/gcc/config/mips/crti.asm
+++ b/gcc/config/mips/crti.asm
@@ -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
diff --git a/gcc/config/mips/crtn.asm b/gcc/config/mips/crtn.asm
index 4fdd60a..54f886a 100644
--- a/gcc/config/mips/crtn.asm
+++ b/gcc/config/mips/crtn.asm
@@ -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
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 8c19a99..01e7dd3 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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));
+ }
+ }
+
}
}
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 64ddf58..7a5482c 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -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.