This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
mips16 can't add pseudo to sp directly
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 16 Mar 2002 20:52:37 -0300
- Subject: mips16 can't add pseudo to sp directly
- Organization: GCC Team, Red Hat
When the operand of an sp adjustment does not satisfy arith_operand
(for example, -100000, as in gcc.c-torture/compile/900313-1.c, we'll
have it forced into a register, and then we'll emit an instruction
that will be recognized as an sp addition but that won't be able to
satisfy its constraints.
This patch arranges for us to use a scratch register in which to
perform the addition, since the only add instruction involving sp can
only take an immediate operand. This patch was tested with the same
Red Hat-internal mips port, as well as bootstrapped on
mips-sgi-irix6.5. It was approved by Eric Christopher, so I'm
checking it in.
Index: gcc/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* config/mips/mips.md (addsi3, adddi3): Use scratch register to
add register to non-constant into sp.
Index: gcc/config/mips/mips.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/mips/mips.md,v
retrieving revision 1.118
diff -u -p -r1.118 mips.md
--- gcc/config/mips/mips.md 2002/03/16 23:44:00 1.118
+++ gcc/config/mips/mips.md 2002/03/16 23:50:41
@@ -614,6 +614,27 @@
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) == -32768)
operands[2] = force_reg (SImode, operands[2]);
+
+ /* If a large stack adjustment was forced into a register, we may be
+ asked to generate rtx such as:
+
+ (set (reg:SI sp) (plus:SI (reg:SI sp) (reg:SI pseudo)))
+
+ but no such instruction is available in mips16. Handle it by
+ using a temporary. */
+ if (TARGET_MIPS16
+ && REGNO (operands[0]) == STACK_POINTER_REGNUM
+ && ((GET_CODE (operands[1]) == REG
+ && REGNO (operands[1]) != STACK_POINTER_REGNUM)
+ || GET_CODE (operands[2]) != CONST_INT))
+ {
+ rtx tmp = gen_reg_rtx (SImode);
+
+ emit_move_insn (tmp, operands[1]);
+ emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
+ emit_move_insn (operands[0], tmp);
+ DONE;
+ }
}")
(define_insn "addsi3_internal"
@@ -776,6 +797,27 @@
&& GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) == -32768)
operands[2] = force_reg (DImode, operands[2]);
+
+ /* If a large stack adjustment was forced into a register, we may be
+ asked to generate rtx such as:
+
+ (set (reg:DI sp) (plus:DI (reg:DI sp) (reg:DI pseudo)))
+
+ but no such instruction is available in mips16. Handle it by
+ using a temporary. */
+ if (TARGET_MIPS16
+ && REGNO (operands[0]) == STACK_POINTER_REGNUM
+ && ((GET_CODE (operands[1]) == REG
+ && REGNO (operands[1]) != STACK_POINTER_REGNUM)
+ || GET_CODE (operands[2]) != CONST_INT))
+ {
+ rtx tmp = gen_reg_rtx (DImode);
+
+ emit_move_insn (tmp, operands[1]);
+ emit_insn (gen_addsi3 (tmp, tmp, operands[2]));
+ emit_move_insn (operands[0], tmp);
+ DONE;
+ }
if (TARGET_64BIT)
{
--
Alexandre Oliva Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer aoliva@{cygnus.com, redhat.com}
CS PhD student at IC-Unicamp oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist Professional serial bug killer