mips.c (mips_output_move): When generating mips16 code, force loads of negative const...
authorRichard Sandiford <rsandifo@redhat.com>
Wed, 14 Jul 2004 10:02:32 +0000 (10:02 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 14 Jul 2004 10:02:32 +0000 (10:02 +0000)
* config/mips/mips.c (mips_output_move): When generating mips16 code,
force loads of negative constants to be split.
* config/mips/mips.md (*movhi_mips16, *movqi_mips16): Likewise.
Generalize SImode li/neg splitter to cope with other modes.

From-SVN: r84680

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

index e3af5983d4ecc5d70a65831e9cad19a2449698cf..ef5f5b6f2207e9c917ba74d6d92274eee0a00d89 100644 (file)
@@ -1,3 +1,10 @@
+2004-07-14  Richard Sandiford  <rsandifo@redhat.com>
+
+       * config/mips/mips.c (mips_output_move): When generating mips16 code,
+       force loads of negative constants to be split.
+       * config/mips/mips.md (*movhi_mips16, *movqi_mips16): Likewise.
+       Generalize SImode li/neg splitter to cope with other modes.
+
 2004-07-14  Paolo Bonzini  <bonzini@gnu.org>
 
        * expmed.c: Remove more references to QUEUED in the comments.
index 4e9b6b9c5ebbc9febba17b71d4d15cb5554eeeec..70c4680cf1f797ea69a72ccd122b4c611116c63e 100644 (file)
@@ -2616,7 +2616,7 @@ mips_output_move (rtx dest, rtx src)
            return "li\t%0,%1";
 
          if (INTVAL (src) < 0 && INTVAL (src) >= -0xffff)
-           return "li\t%0,%n1\n\tneg\t%0";
+           return "#";
        }
 
       if (src_code == HIGH)
index ccac110f8299010fdf222edd54bfddf55ff25863..fa096d3335754ccf2e93ef522f4468790e2a23a7 100644 (file)
@@ -4289,22 +4289,6 @@ dsrl\t%3,%3,1\n\
   operands[2] = GEN_INT (val - 0xff);
 })
 
-;; On the mips16, we can split a load of a negative constant into a
-;; load and a neg.  That's what mips_output_move will generate anyhow.
-
-(define_split
-  [(set (match_operand:SI 0 "register_operand")
-       (match_operand:SI 1 "const_int_operand"))]
-  "TARGET_MIPS16 && reload_completed && !TARGET_DEBUG_D_MODE
-   && GET_CODE (operands[0]) == REG
-   && M16_REG_P (REGNO (operands[0]))
-   && GET_CODE (operands[1]) == CONST_INT
-   && INTVAL (operands[1]) < 0
-   && INTVAL (operands[1]) > - 0x8000"
-  [(set (match_dup 0) (match_dup 1))
-   (set (match_dup 0) (neg:SI (match_dup 0)))]
-  { operands[1] = GEN_INT (- INTVAL (operands[1])); })
-
 ;; This insn handles moving CCmode values.  It's really just a
 ;; slightly simplified copy of movsi_internal2, with additional cases
 ;; to move a condition register to a general register and to move
@@ -4492,7 +4476,7 @@ dsrl\t%3,%3,1\n\
     move\t%0,%1
     move\t%0,%1
     li\t%0,%1
-    li\t%0,%n1\;neg\t%0
+    #
     lhu\t%0,%1
     sh\t%1,%0"
   [(set_attr "type"    "arith,arith,arith,arith,arith,load,store")
@@ -4599,7 +4583,7 @@ dsrl\t%3,%3,1\n\
     move\t%0,%1
     move\t%0,%1
     li\t%0,%1
-    li\t%0,%n1\;neg\t%0
+    #
     lbu\t%0,%1
     sb\t%1,%0"
   [(set_attr "type"    "arith,arith,arith,arith,arith,load,store")
@@ -4758,6 +4742,21 @@ dsrl\t%3,%3,1\n\
   DONE;
 })
 
+;; When generating mips16 code, split moves of negative constants into
+;; a positive "li" followed by a negation.
+(define_split
+  [(set (match_operand 0 "register_operand")
+       (match_operand 1 "const_int_operand"))]
+  "TARGET_MIPS16 && reload_completed && INTVAL (operands[1]) < 0"
+  [(set (match_dup 0)
+       (match_dup 2))
+   (set (match_dup 3)
+       (neg:SI (match_dup 3)))]
+{
+  operands[2] = GEN_INT (-INTVAL (operands[1]));
+  operands[3] = gen_lowpart (SImode, operands[0]);
+})
+
 ;; The HI and LO registers are not truly independent.  If we move an mthi
 ;; instruction before an mflo instruction, it will make the result of the
 ;; mflo unpredictable.  The same goes for mtlo and mfhi.