]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Fix switch table and reload problems for mips16.
authorJim Wilson <wilson@cygnus.com>
Mon, 14 Jun 1999 15:47:30 +0000 (15:47 +0000)
committerJim Wilson <wilson@gcc.gnu.org>
Mon, 14 Jun 1999 15:47:30 +0000 (08:47 -0700)
* config/mips/mips.c (mips_secondary_reload_class): Check for
(PLUS (SP) (REG)) and return appropriate register class.
* config/mips/mips.md (reload_insi): Delete predicate for operand 1.
Handle (PLUS (SP) (REG)).
(tablejump): In mips16 code, use emit_insn instead of emit_jump_insn.
(tablejump_mips161, tablejump_mips162): Use emit_jump_insn instead
of emit_insn for tablejump.

From-SVN: r27519

gcc/ChangeLog
gcc/config/mips/mips.c
gcc/config/mips/mips.md

index 0c89a86f4d81ef4416c8c0f749d48a48e1c984ac..4e9ddd531a6f83d5a1d67af8020a02af6f2aeea0 100644 (file)
@@ -1,3 +1,13 @@
+Mon Jun 14 15:38:43 1999  Jim Wilson  <wilson@cygnus.com>
+
+       * config/mips/mips.c (mips_secondary_reload_class): Check for
+       (PLUS (SP) (REG)) and return appropriate register class.
+       * config/mips/mips.md (reload_insi): Delete predicate for operand 1.
+       Handle (PLUS (SP) (REG)).
+       (tablejump): In mips16 code, use emit_insn instead of emit_jump_insn.
+       (tablejump_mips161, tablejump_mips162): Use emit_jump_insn instead
+       of emit_insn for tablejump.
+       
 Mon Jun 14 17:26:40 1999  David Edelsohn  <edelsohn@gnu.org>
 
        * rs6000.c (output_prolog): RS6000_CALL_GLUE must be
index 3433052d677350a88888a877bb35a438f56d9fce..5c54dba4157a3c2df853ef7dde4ef24e516e12c7 100644 (file)
@@ -7234,6 +7234,19 @@ mips_secondary_reload_class (class, mode, x, in_p)
        }
       if (! gp_reg_p)
        {
+         /* The stack pointer isn't a valid operand to an add instruction,
+            so we need to load it into M16_REGS first.  This can happen as
+            a result of register elimination and form_sum converting
+            (plus reg (plus SP CONST)) to (plus (plus reg SP) CONST).  We
+            need an extra register if the dest is the same as the other
+            register.  In that case, we can't fix the problem by loading SP
+            into the dest first.  */
+         if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == REG
+             && GET_CODE (XEXP (x, 1)) == REG
+             && (XEXP (x, 0) == stack_pointer_rtx
+                 || XEXP (x, 1) == stack_pointer_rtx))
+           return (class == M16_REGS ? M16_NA_REGS : M16_REGS);
+
          if (class == M16_REGS || class == M16_NA_REGS)
            return NO_REGS;
          return M16_REGS;
index 4e0a5b45ec6af6e9ce8e49de77d406c62525f84e..fb739b8566974244a3030c2009780b3524443d0d 100644 (file)
@@ -5473,9 +5473,12 @@ move\\t%0,%z4\\n\\
 ;; so we use a mult.  ??? This is hideous, and we ought to figure out
 ;; something better.
 
+;; We use no predicate for operand1, because it may be a PLUS, and there
+;; is no convenient predicate for that.
+
 (define_expand "reload_insi"
   [(set (match_operand:SI 0 "register_operand" "=b")
-       (match_operand:SI 1 "register_operand" "b"))
+       (match_operand:SI 1 "" "b"))
    (clobber (match_operand:SI 2 "register_operand" "=&d"))]
   "TARGET_MIPS16"
   "
@@ -5499,6 +5502,56 @@ move\\t%0,%z4\\n\\
                                              gen_rtx (REG, SImode, 66)))));
       DONE;
     }
+
+  /* If this is a plus, then this must be an add of the stack pointer against
+     either a hard register or a pseudo.  */
+  if (TARGET_MIPS16 && GET_CODE (operands[1]) == PLUS)
+    {
+      rtx plus_op;
+
+      if (XEXP (operands[1], 0) == stack_pointer_rtx)
+       plus_op = XEXP (operands[1], 1);
+      else if (XEXP (operands[1], 1) == stack_pointer_rtx)
+       plus_op = XEXP (operands[1], 0);
+      else
+       abort ();
+
+      /* We should have a register now.  */
+      if (GET_CODE (plus_op) != REG)
+       abort ();
+
+      if (REGNO (plus_op) < FIRST_PSEUDO_REGISTER)
+       {
+         /* We have to have at least one temporary register which is not
+            overlapping plus_op.  */
+         if (! rtx_equal_p (plus_op, operands[0]))
+           {
+             emit_move_insn (operands[0], stack_pointer_rtx);
+             emit_insn (gen_addsi3 (operands[0], operands[0], plus_op));
+           }
+         else if (! rtx_equal_p (plus_op, operands[2]))
+           {
+             emit_move_insn (operands[2], stack_pointer_rtx);
+             emit_insn (gen_addsi3 (operands[0], plus_op, operands[2]));
+           }
+         else
+           abort ();
+       }
+      else
+       {
+         /* We need two registers in this case.  */
+         if (! rtx_equal_p (operands[0], operands[2]))
+           {
+             emit_move_insn (operands[0], stack_pointer_rtx);
+             emit_move_insn (operands[2], plus_op);
+             emit_insn (gen_addsi3 (operands[0], operands[0], operands[2]));
+           }
+         else
+           abort ();
+       }
+      DONE;
+    }
+
   /* FIXME: I don't know how to get a value into the HI register.  */
   emit_move_insn (operands[0], operands[1]);
   DONE;
@@ -9039,9 +9092,9 @@ move\\t%0,%z4\\n\\
          if (GET_MODE (operands[0]) != HImode)
            abort ();
          if (!(Pmode == DImode))
-           emit_jump_insn (gen_tablejump_mips161 (operands[0], operands[1]));
+           emit_insn (gen_tablejump_mips161 (operands[0], operands[1]));
          else
-           emit_jump_insn (gen_tablejump_mips162 (operands[0], operands[1]));
+           emit_insn (gen_tablejump_mips162 (operands[0], operands[1]));
          DONE;
        }
 
@@ -9110,7 +9163,7 @@ move\\t%0,%z4\\n\\
       emit_insn (gen_extendhisi2 (t1, operands[0]));
       emit_move_insn (t2, gen_rtx (LABEL_REF, SImode, operands[1]));
       emit_insn (gen_addsi3 (t3, t1, t2));
-      emit_insn (gen_tablejump_internal1 (t3, operands[1]));
+      emit_jump_insn (gen_tablejump_internal1 (t3, operands[1]));
       DONE;
     }
 }")
@@ -9132,7 +9185,7 @@ move\\t%0,%z4\\n\\
       emit_insn (gen_extendhidi2 (t1, operands[0]));
       emit_move_insn (t2, gen_rtx (LABEL_REF, DImode, operands[1]));
       emit_insn (gen_adddi3 (t3, t1, t2));
-      emit_insn (gen_tablejump_internal2 (t3, operands[1]));
+      emit_jump_insn (gen_tablejump_internal2 (t3, operands[1]));
       DONE;
     }
 }")