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.
#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
(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.