(define_predicate "logical_shift_operator"
(match_code "ashift,lshiftrt"))
+(define_predicate "addsub_operator"
+ (match_code "plus,minus"))
+
(define_predicate "xtensa_cstoresi_operator"
(match_code "eq,ne,gt,ge,lt,le"))
(set_attr "mode" "SI")
(set_attr "length" "3")])
+(define_insn_and_split "*extzvsi-1bit_ashlsi3"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (and:SI (match_operator:SI 4 "logical_shift_operator"
+ [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "const_int_operand" "i")])
+ (match_operand:SI 3 "const_int_operand" "i")))]
+ "exact_log2 (INTVAL (operands[3])) > 0"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (match_dup 2)))
+ (set (match_dup 0)
+ (ashift:SI (match_dup 0)
+ (match_dup 3)))]
+{
+ int pos = INTVAL (operands[2]),
+ shift = floor_log2 (INTVAL (operands[3]));
+ switch (GET_CODE (operands[4]))
+ {
+ case ASHIFT:
+ pos = shift - pos;
+ break;
+ case LSHIFTRT:
+ pos = shift + pos;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (BITS_BIG_ENDIAN)
+ pos = (32 - (1 + pos)) & 0x1f;
+ operands[2] = GEN_INT (pos);
+ operands[3] = GEN_INT (shift);
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")
+ (set_attr "length" "6")])
+
+(define_insn_and_split "*extzvsi-1bit_addsubx"
+ [(set (match_operand:SI 0 "register_operand" "=a")
+ (match_operator:SI 5 "addsub_operator"
+ [(and:SI (match_operator:SI 6 "logical_shift_operator"
+ [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 3 "const_int_operand" "i")])
+ (match_operand:SI 4 "const_int_operand" "i"))
+ (match_operand:SI 2 "register_operand" "r")]))]
+ "TARGET_ADDX
+ && IN_RANGE (exact_log2 (INTVAL (operands[4])), 1, 3)"
+ "#"
+ "&& 1"
+ [(set (match_dup 0)
+ (zero_extract:SI (match_dup 1)
+ (const_int 1)
+ (match_dup 3)))
+ (set (match_dup 0)
+ (match_op_dup 5
+ [(ashift:SI (match_dup 0)
+ (match_dup 4))
+ (match_dup 2)]))]
+{
+ int pos = INTVAL (operands[3]),
+ shift = floor_log2 (INTVAL (operands[4]));
+ switch (GET_CODE (operands[6]))
+ {
+ case ASHIFT:
+ pos = shift - pos;
+ break;
+ case LSHIFTRT:
+ pos = shift + pos;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ if (BITS_BIG_ENDIAN)
+ pos = (32 - (1 + pos)) & 0x1f;
+ operands[3] = GEN_INT (pos);
+ operands[4] = GEN_INT (shift);
+}
+ [(set_attr "type" "arith")
+ (set_attr "mode" "SI")
+ (set_attr "length" "6")])
+
\f
;; Conversions.