From 282cb01bc29cdac825eedc4b8ad74085c2d76918 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 6 Feb 2002 02:50:09 +0000 Subject: [PATCH] crti.asm: Add changes for mips16. 2002-02-05 Eric Christopher * 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 --- gcc/config/mips/crti.asm | 8 +++--- gcc/config/mips/crtn.asm | 20 ++++++++++++++ gcc/config/mips/mips.c | 56 +++++++++++++++++++++++++++++++++------- gcc/config/mips/mips.h | 2 +- 4 files changed, 71 insertions(+), 15 deletions(-) diff --git a/gcc/config/mips/crti.asm b/gcc/config/mips/crti.asm index 6452d1e4b28..f4bef6ff92b 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 4fdd60ab16d..54f886a216f 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 8c19a992459..01e7dd30c9c 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 64ddf58e715..7a5482cc927 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. -- 2.30.2