From: Takayuki 'January June' Suwa Date: Thu, 25 May 2023 15:07:49 +0000 (+0900) Subject: xtensa: Add 'subtraction from constant' insn pattern X-Git-Tag: basepoints/gcc-15~8844 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9b867c8281ee313cf6ec737d8f4a9ba7ef78408e;p=thirdparty%2Fgcc.git 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. --- diff --git a/gcc/config/xtensa/constraints.md b/gcc/config/xtensa/constraints.md index 53e4d0d8dd1a..5cade1db8ff1 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 64cbf27c2485..ec715b44e4d9 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 e3af78cd2284..46ab9f36b56f 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -471,6 +471,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) { diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index 112581251651..113b313026ef 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")