aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>2023-05-26 00:07:49 +0900
committerMax Filippov <jcmvbkbc@gmail.com>2023-05-26 03:22:54 -0700
commit9b867c8281ee313cf6ec737d8f4a9ba7ef78408e (patch)
tree17456ea8026f625e264fc33dbd0e3cc3f8651956 /gcc
parentbf78e24a90d4d064b0372a03c0327b6f90475949 (diff)
downloadgcc-9b867c8281ee313cf6ec737d8f4a9ba7ef78408e.zip
gcc-9b867c8281ee313cf6ec737d8f4a9ba7ef78408e.tar.gz
gcc-9b867c8281ee313cf6ec737d8f4a9ba7ef78408e.tar.bz2
xtensa: Add 'subtraction from constant' insn pattern
This patch makes try to eliminate using temporary pseudo for '(minus:SI (const_int) (reg:SI))' if the addition of negative constant value can be emitted in a single machine instruction. /* example */ int test0(int x) { return 1 - x; } int test1(int x) { return 100 - x; } int test2(int x) { return 25600 - x; } ;; before test0: movi.n a9, 1 sub a2, a9, a2 ret.n test1: movi a9, 0x64 sub a2, a9, a2 ret.n test2: movi.n a9, 0x19 slli a9, a9, 10 sub a2, a9, a2 ret.n ;; after test0: addi.n a2, a2, -1 neg a2, a2 ret.n test1: addi a2, a2, -100 neg a2, a2 ret.n test2: addmi a2, a2, -0x6400 neg a2, a2 ret.n gcc/ChangeLog: * config/xtensa/xtensa-protos.h (xtensa_m1_or_1_thru_15): New prototype. * config/xtensa/xtensa.cc (xtensa_m1_or_1_thru_15): New function. * config/xtensa/constraints.md (O): Change to use the above function. * config/xtensa/xtensa.md (*subsi3_from_const): New insn_and_split pattern.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/xtensa/constraints.md2
-rw-r--r--gcc/config/xtensa/xtensa-protos.h1
-rw-r--r--gcc/config/xtensa/xtensa.cc7
-rw-r--r--gcc/config/xtensa/xtensa.md24
4 files changed, 33 insertions, 1 deletions
diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md
index 53e4d0d..5cade1d 100644
--- a/gcc/config/xtensa/constraints.md
+++ b/gcc/config/xtensa/constraints.md
@@ -108,7 +108,7 @@
(define_constraint "O"
"An integer constant that can be used in ADDI.N instructions."
(and (match_code "const_int")
- (match_test "ival == -1 || IN_RANGE (ival, 1, 15)")))
+ (match_test "xtensa_m1_or_1_thru_15 (ival)")))
(define_constraint "P"
"An integer constant that can be used as a mask value in an EXTUI
diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
index 64cbf27..ec715b4 100644
--- a/gcc/config/xtensa/xtensa-protos.h
+++ b/gcc/config/xtensa/xtensa-protos.h
@@ -27,6 +27,7 @@ extern bool xtensa_simm8x256 (HOST_WIDE_INT);
extern bool xtensa_simm12b (HOST_WIDE_INT);
extern bool xtensa_b4const_or_zero (HOST_WIDE_INT);
extern bool xtensa_b4constu (HOST_WIDE_INT);
+extern bool xtensa_m1_or_1_thru_15 (HOST_WIDE_INT);
extern bool xtensa_mask_immediate (HOST_WIDE_INT);
extern bool xtensa_mem_offset (unsigned, machine_mode);
diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc
index e3af78c..46ab9f3 100644
--- a/gcc/config/xtensa/xtensa.cc
+++ b/gcc/config/xtensa/xtensa.cc
@@ -472,6 +472,13 @@ xtensa_b4constu (HOST_WIDE_INT v)
bool
+xtensa_m1_or_1_thru_15 (HOST_WIDE_INT v)
+{
+ return v == -1 || IN_RANGE (v, 1, 15);
+}
+
+
+bool
xtensa_mask_immediate (HOST_WIDE_INT v)
{
return IN_RANGE (exact_log2 (v + 1), 1, 16);
diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
index 1125812..113b313 100644
--- a/gcc/config/xtensa/xtensa.md
+++ b/gcc/config/xtensa/xtensa.md
@@ -216,6 +216,30 @@
(set_attr "mode" "SI")
(set_attr "length" "3")])
+(define_insn_and_split "*subsi3_from_const"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (minus:SI (match_operand:SI 1 "const_int_operand" "i")
+ (match_operand:SI 2 "register_operand" "r")))]
+ "xtensa_simm8 (-INTVAL (operands[1]))
+ || xtensa_simm8x256 (-INTVAL (operands[1]))"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (plus:SI (match_dup 2)
+ (match_dup 1)))
+ (set (match_dup 0)
+ (neg:SI (match_dup 0)))]
+{
+ operands[1] = GEN_INT (-INTVAL (operands[1]));
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")
+ (set (attr "length")
+ (if_then_else (match_test "TARGET_DENSITY
+ && xtensa_m1_or_1_thru_15 (-INTVAL (operands[1]))")
+ (const_int 5)
+ (const_int 6)))])
+
(define_insn "subsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(minus:SF (match_operand:SF 1 "register_operand" "f")