sparc.c (arith_4096_operand, [...]): New predicates.
authorJakub Jelinek <jj@sunsite.ms.mff.cuni.cz>
Tue, 25 Aug 1998 06:56:57 +0000 (08:56 +0200)
committerDavid S. Miller <davem@gcc.gnu.org>
Tue, 25 Aug 1998 06:56:57 +0000 (23:56 -0700)
* config/sparc/sparc.c (arith_4096_operand, arith_add_operand,
arith_double_4096_operand, arith_double_add_operand): New
predicates.
* config/sparc/sparc.h (PREDICATE_CODES): Add them, declare them.
* config/sparc/sparc.md (adddi3, addsi3, subdi3, subsi3): Use
them to transform add/sub 4096 into add/sub -4096.

From-SVN: r21961

gcc/ChangeLog
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.h
gcc/config/sparc/sparc.md

index 98e2b5311077edbf6168c442141b847a8f5b545b..d1e50cfc34a8471ac94af8f103d893a28a038d3a 100644 (file)
@@ -1,3 +1,12 @@
+Tue Aug 25 05:48:18 1998  Jakub Jelinek  <jj@sunsite.ms.mff.cuni.cz>
+
+       * config/sparc/sparc.c (arith_4096_operand, arith_add_operand,
+       arith_double_4096_operand, arith_double_add_operand): New
+       predicates.
+       * config/sparc/sparc.h (PREDICATE_CODES): Add them, declare them.
+       * config/sparc/sparc.md (adddi3, addsi3, subdi3, subsi3): Use
+       them to transform add/sub 4096 into add/sub -4096.
+
 Mon Aug 24 23:31:03 1998  David S. Miller  <davem@pierdol.cobaltmicro.com>
 
        * loop.c (scan_loop): Allocate some slop to handle pseudos
index 1726c61a7bf254b3122007ede14a36b38727cfd5..1ac5d2fa6aae441b4096fea98bdf883409d5f28f 100644 (file)
@@ -780,6 +780,30 @@ arith_operand (op, mode)
   return SPARC_SIMM13_P (val);
 }
 
+/* Return true if OP is a constant 4096  */
+
+int
+arith_4096_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  int val;
+  if (GET_CODE (op) != CONST_INT)
+    return 0;
+  val = INTVAL (op) & 0xffffffff;
+  return val == 4096;
+}
+
+/* Return true if OP is suitable as second operand for add/sub */
+
+int
+arith_add_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  return arith_operand (op, mode) || arith_4096_operand (op, mode);
+}
+
 /* Return true if OP is a CONST_INT or a CONST_DOUBLE which can fit in the
    immediate field of OR and XOR instructions.  Used for 64-bit
    constant formation patterns.  */
@@ -879,6 +903,30 @@ arith_double_operand (op, mode)
                      && (CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
 }
 
+/* Return true if OP is a constant 4096 for DImode on ARCH64 */
+
+int
+arith_double_4096_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  return (TARGET_ARCH64 &&
+         ((GET_CODE (op) == CONST_INT && INTVAL (op) == 4096) ||
+          (GET_CODE (op) == CONST_DOUBLE &&
+           CONST_DOUBLE_LOW (op) == 4096 &&
+           CONST_DOUBLE_HIGH (op) == 0)));
+}
+
+/* Return true if OP is suitable as second operand for add/sub in DImode */
+
+int
+arith_double_add_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  return arith_double_operand (op, mode) || arith_double_4096_operand (op, mode);
+}
+
 /* Return true if OP is a register, or is a CONST_INT or CONST_DOUBLE that
    can fit in an 11 bit immediate field.  This is an acceptable DImode
    operand for the movcc instructions.  */
index 78882dbe6e31556aa58c3c1f13c70b762afaa800..af0dba84d1e20f1554adb0a3322ced479ed92863 100644 (file)
@@ -3214,9 +3214,11 @@ do {                                                                     \
 {"cc_arithop", {AND, IOR, XOR}},                                                   \
 {"cc_arithopn", {AND, IOR}},                                                       \
 {"arith_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}},                       \
+{"arith_add_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}},                   \
 {"arith11_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}},                     \
 {"arith10_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT}},                     \
 {"arith_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}},   \
+{"arith_double_add_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}},\
 {"arith11_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
 {"arith10_double_operand", {SUBREG, REG, CONSTANT_P_RTX, CONST_INT, CONST_DOUBLE}}, \
 {"small_int", {CONST_INT, CONSTANT_P_RTX}},                                        \
@@ -3262,7 +3264,11 @@ extern int arith10_operand ();
 extern int arith11_double_operand ();
 extern int arith11_operand ();
 extern int arith_double_operand ();
+extern int arith_double_4096_operand ();
+extern int arith_double_add_operand ();
 extern int arith_operand ();
+extern int arith_4096_operand ();
+extern int arith_add_operand ();
 extern int call_operand_address ();
 extern int input_operand ();
 extern int zero_operand ();
index 003e39eb92a11724e9004c35a0c74daf0f32ad3b..47cdea6b5eec20117e99a76c24acfdd656a1b653 100644 (file)
 (define_expand "adddi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (plus:DI (match_operand:DI 1 "arith_double_operand" "%r")
-                (match_operand:DI 2 "arith_double_operand" "rHI")))]
+                (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
   ""
   "
 {
                                   gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
       DONE;
     }
+  if (arith_double_4096_operand(operands[2], DImode))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+                             gen_rtx_MINUS (DImode, operands[1],
+                                            GEN_INT(-4096))));
+      DONE;
+    }
 }")
 
 (define_insn "adddi3_insn_sp32"
   [(set_attr "type" "binary")
    (set_attr "length" "1")])
 
-(define_insn "addsi3"
+(define_expand "addsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,d")
+       (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
+                (match_operand:SI 2 "arith_add_operand" "rI,d")))]
+  ""
+  "
+{
+  if (arith_4096_operand(operands[2], DImode))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+                             gen_rtx_MINUS (SImode, operands[1],
+                                            GEN_INT(-4096))));
+      DONE;
+    }
+}")
+
+(define_insn "*addsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,d")
        (plus:SI (match_operand:SI 1 "arith_operand" "%r,d")
                 (match_operand:SI 2 "arith_operand" "rI,d")))]
 (define_expand "subdi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
        (minus:DI (match_operand:DI 1 "register_operand" "r")
-                 (match_operand:DI 2 "arith_double_operand" "rHI")))]
+                 (match_operand:DI 2 "arith_double_add_operand" "rHI")))]
   ""
   "
 {
                                   gen_rtx_REG (CCmode, SPARC_ICC_REG)))));
       DONE;
     }
+  if (arith_double_4096_operand(operands[2], DImode))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+                             gen_rtx_PLUS (DImode, operands[1],
+                                           GEN_INT(-4096))));
+      DONE;
+    }
 }")
 
 (define_insn "*subdi3_sp32"
   [(set_attr "type" "binary")
    (set_attr "length" "1")])
 
-(define_insn "subsi3"
+(define_expand "subsi3"
+  [(set (match_operand:SI 0 "register_operand" "=r,d")
+       (minus:SI (match_operand:SI 1 "register_operand" "r,d")
+                 (match_operand:SI 2 "arith_add_operand" "rI,d")))]
+  ""
+  "
+{
+  if (arith_4096_operand(operands[2], DImode))
+    {
+      emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+                             gen_rtx_PLUS (SImode, operands[1],
+                                           GEN_INT(-4096))));
+      DONE;
+    }
+}")
+
+(define_insn "*subsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,d")
        (minus:SI (match_operand:SI 1 "register_operand" "r,d")
                  (match_operand:SI 2 "arith_operand" "rI,d")))]