]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: constantsynth: Add new 2-insns synthesis method
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Sun, 15 Mar 2026 09:32:48 +0000 (18:32 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Mon, 16 Mar 2026 02:35:52 +0000 (19:35 -0700)
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

index 9998d2ece8220fb01427dba07aefcf2ff2f79c95..4a9b156e0db729cd258e12957788d40ca68d4b26 100644 (file)
@@ -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" },