;; to use the same template.
(define_code_iterator any_extend [sign_extend zero_extend])
+;; These code iterators allow unsigned and signed extraction to be generated
+;; from the same template.
+(define_code_iterator any_extract [sign_extract zero_extract])
+(define_code_attr extract_sidi_shift [(sign_extract "sraiw")
+ (zero_extract "srliw")])
+
;; This code iterator allows the two right shift instructions to be
;; generated from the same template.
(define_code_iterator any_shiftrt [ashiftrt lshiftrt])
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
-;; Canonical form for a zero-extend of a logical right shift.
-(define_insn "*lshrsi3_zero_extend_2"
+;; Canonical form for a sign/zero-extend of a logical right shift.
+;; Special case: extract MSB bits of lower 32-bit word
+(define_insn "*lshrsi3_extend_2"
[(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extract:DI (match_operand:DI 1 "register_operand" " r")
+ (any_extract:DI (match_operand:DI 1 "register_operand" " r")
(match_operand 2 "const_int_operand")
(match_operand 3 "const_int_operand")))]
"(TARGET_64BIT && (INTVAL (operands[3]) > 0)
&& (INTVAL (operands[2]) + INTVAL (operands[3]) == 32))"
{
- return "srliw\t%0,%1,%3";
+ return "<extract_sidi_shift>\t%0,%1,%3";
}
[(set_attr "type" "shift")
(set_attr "mode" "SI")])
}
/* { dg-final { scan-assembler "sraiw\ta\[0-9\],a\[0-9\],31" } } */
+signed char
+sub2 (long i)
+{
+ return i >> 24;
+}
+/* { dg-final { scan-assembler "sraiw\ta\[0-9\],a\[0-9\],24" } } */
+
+signed short
+sub3 (long i)
+{
+ return i >> 16;
+}
+/* { dg-final { scan-assembler "sraiw\ta\[0-9\],a\[0-9\],16" } } */
+
/* { dg-final { scan-assembler-not "srai\t" } } */
/* { dg-final { scan-assembler-not "srli\t" } } */
/* { dg-final { scan-assembler-not "srliw\t" } } */