https://gcc.gnu.org/g:089e4fb29ffa2520c487db3724cb1beb0df0ce6b
commit r16-8105-g089e4fb29ffa2520c487db3724cb1beb0df0ce6b Author: Takayuki 'January June' Suwa <[email protected]> Date: Sun Mar 15 18:32:48 2026 +0900 xtensa: constantsynth: Add new 2-insns synthesis method This patch adds a new 2-instructions constant synthesis method: - A positive integer value that, despite left-shifting the leading 0 bits, becomes a negative number that still fits into a signed 12-bit => "MOVI(.N) Ax, simm12" + "SRLI Ax, Ax, 1...10" /* example */ int test(void) { return 0x1FFFFF55; /* 0b00011111111111111111111101010101 */ } ;; before (-O1 -mextra-l32r-costs=1) .literal_position .literal .LC0, 536870741 test: entry sp, 32 l32r a2, .LC0 retw.n ;; after (-O1 -mextra-l32r-costs=1) test: entry sp, 32 movi a2, -0x558 srli a2, a2, 3 retw.n gcc/ChangeLog: * config/xtensa/xtensa.cc (constantsynth_method_lshr_mi12b): New. (constantsynth_methods): Add constantsynth_method_lshr_mi12b. Diff: --- gcc/config/xtensa/xtensa.cc | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc index 9998d2ece822..4a9b156e0db7 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -5777,6 +5777,31 @@ constantsynth_method_lshr_m1 (rtx dest, HOST_WIDE_INT v) return end_sequence (); } +/* A method that generates two machine instructions to logically right- + shift a negative signed 12-bit value a certain number of bits to + synthesize a positive number with a bit sequence of 1s on the MSB + side (eg., 0x1FFFFF55). */ + +static rtx_insn * +constantsynth_method_lshr_mi12b (rtx dest, HOST_WIDE_INT v) +{ + int i; + HOST_WIDE_INT v0; + + /* HOST_WIDE_INT should be always 64 bits (see gcc/hwint.h), while + asserts just in case. */ + gcc_assert (HOST_BITS_PER_WIDE_INT == 64); + + if (! IN_RANGE (i = clz_hwi (v) - 32, 1, 10) + || ! IN_RANGE (v0 = (int32_t)(v << i), -2048, -2)) + return NULL; + + start_sequence (); + emit_insn (gen_rtx_SET (dest, GEN_INT (v0))); + emit_insn (gen_lshrsi3 (dest, dest, GEN_INT (i))); + return end_sequence (); +} + /* Split the specified value between -34816 and 34559 into the two immediates for the MOVI and ADDMI instruction. */ @@ -5951,6 +5976,7 @@ struct constantsynth_method_info static const struct constantsynth_method_info constantsynth_methods[] = { { constantsynth_method_lshr_m1, "lshr_m1" }, + { constantsynth_method_lshr_mi12b, "lshr_mi12b" }, { constantsynth_method_16bits, "16bits" }, { constantsynth_method_32bits, "32bits" }, { constantsynth_method_square, "square" },
