]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
xtensa: Make use of DEPBITS instruction
authorTakayuki 'January June' Suwa <jjsuwa_sys3175@yahoo.co.jp>
Tue, 17 Jun 2025 06:56:52 +0000 (15:56 +0900)
committerMax Filippov <jcmvbkbc@gmail.com>
Sun, 22 Jun 2025 09:50:20 +0000 (02:50 -0700)
This patch implements bitfield insertion MD pattern using the DEPBITS
machine instruction, the counterpart of the EXTUI instruction, if
available.

     /* example */
     struct foo {
       unsigned int b:10;
       unsigned int r:11;
       unsigned int g:11;
     };
     void test(struct foo *p) {
       p->g >>= 1;
     }

     ;; result (endianness: little)
     test:
      entry sp, 32
      l32i.n a8, a2, 0
      extui a9, a8, 1, 10
      depbits a8, a9, 0, 11
      s32i.n a8, a2, 0
      retw.n

gcc/ChangeLog:

* config/xtensa/xtensa.h (TARGET_DEPBITS): New macro.
* config/xtensa/xtensa.md (insvsi): New insn pattern.

gcc/config/xtensa/xtensa.h
gcc/config/xtensa/xtensa.md

index 9009db0109779dfebeaa2ae88ffde02a2a5e436f..a8a0565c81e73eae0f332a2e31e9a30b985b71ed 100644 (file)
@@ -36,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #define TARGET_MINMAX          XCHAL_HAVE_MINMAX
 #define TARGET_SEXT            XCHAL_HAVE_SEXT
 #define TARGET_CLAMPS          XCHAL_HAVE_CLAMPS
+#define TARGET_DEPBITS         XCHAL_HAVE_DEPBITS
 #define TARGET_BOOLEANS                XCHAL_HAVE_BOOLEANS
 #define TARGET_HARD_FLOAT      XCHAL_HAVE_FP
 #define TARGET_HARD_FLOAT_DIV  XCHAL_HAVE_FP_DIV
index 4c4270ae8bcb700850a791c0b1e7295d9bccd439..029be99e3b4efae4c0fec82dcd669bf67bae9c21 100644 (file)
    (set_attr "length"  "3")])
 
 \f
-;; Field extract instructions.
+;; Field extract and insert instructions.
 
 (define_expand "extvsi"
   [(set (match_operand:SI 0 "register_operand" "")
    (set_attr "mode"    "SI")
    (set_attr "length"  "6")])
 
+(define_insn "insvsi"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+a")
+                        (match_operand:SI 1 "extui_fldsz_operand" "i")
+                        (match_operand:SI 2 "const_int_operand" "i"))
+       (match_operand:SI 3 "register_operand" "r"))]
+  "TARGET_DEPBITS"
+{
+  int shift;
+  if (BITS_BIG_ENDIAN)
+    shift = (32 - (INTVAL (operands[1]) + INTVAL (operands[2]))) & 0x1f;
+  else
+    shift = INTVAL (operands[2]) & 0x1f;
+  operands[2] = GEN_INT (shift);
+  return "depbits\t%0, %3, %2, %1";
+}
+  [(set_attr "type"    "arith")
+   (set_attr "mode"    "SI")
+   (set_attr "length"  "3")])
+
 \f
 ;; Conversions.