aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1995-12-09 15:11:50 -0800
committerJim Wilson <wilson@gcc.gnu.org>1995-12-09 15:11:50 -0800
commitcaca3c8a0325fb2b5fc674777ad658bc5058b6c0 (patch)
tree63fdc5001622d681be5da5baf9ed0536ee473aa5 /gcc
parent06ada9d1c1b11112e676aff4c41a683c67028fbc (diff)
downloadgcc-caca3c8a0325fb2b5fc674777ad658bc5058b6c0.zip
gcc-caca3c8a0325fb2b5fc674777ad658bc5058b6c0.tar.gz
gcc-caca3c8a0325fb2b5fc674777ad658bc5058b6c0.tar.bz2
(subsi3): Rename to subsi3_internal.
(subsi3): Rename to subsi3_internal. Add new define_expand to handle subtracting a register from a constant. From-SVN: r10693
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/sh/sh.md22
1 files changed, 21 insertions, 1 deletions
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 3b767fb..898b508 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -321,13 +321,33 @@
"clrt\;subc %R2,%R0\;subc %S2,%S0"
[(set_attr "length" "6")])
-(define_insn "subsi3"
+(define_insn "*subsi3_internal"
[(set (match_operand:SI 0 "arith_reg_operand" "=r")
(minus:SI (match_operand:SI 1 "arith_reg_operand" "0")
(match_operand:SI 2 "arith_reg_operand" "r")))]
""
"sub %2,%0"
[(set_attr "type" "arith")])
+
+;; Convert `constant - reg' to `neg rX; add rX, #const' since this
+;; will sometimes save one instruction. Otherwise we might get
+;; `mov #const, rY; sub rY,rX; mov rX, rY' if the source and dest regs
+;; are the same.
+
+(define_expand "subsi3"
+ [(set (match_operand:SI 0 "arith_reg_operand" "")
+ (minus:SI (match_operand:SI 1 "arith_operand" "")
+ (match_operand:SI 2 "arith_reg_operand" "")))]
+ ""
+ "
+{
+ if (GET_CODE (operands[1]) == CONST_INT)
+ {
+ emit_insn (gen_negsi2 (operands[0], operands[2]));
+ emit_insn (gen_addsi3 (operands[0], operands[0], operands[1]));
+ DONE;
+ }
+}")
;; -------------------------------------------------------------------------
;; Division instructions