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.
---
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 9998d2ece82..4a9b156e0db 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" },
--
2.39.5