This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mips16 can't add pseudo to sp directly


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]