@@ -6256,6 +6256,39 @@ (define_insn "*branch_bit<bbv><mode>_inverted"
}
[(set_attr "type" "branch")
(set_attr "branch_likely" "no")])
+
+(define_insn_and_split "*branch_on_bit<mode>"
+ [(set (pc)
+ (if_then_else
+ (match_operator 0 "equality_operator"
+ [(zero_extract:GPR (match_operand:GPR 2 "register_operand" "d")
+ (const_int 1)
+ (match_operand:GPR 3 "const_int_operand"))
+ (const_int 0)])
+ (label_ref (match_operand 1))
+ (pc)))]
+ "!ISA_HAS_BBIT && !ISA_HAS_EXT_INS && !TARGET_MIPS16 && UINTVAL (operands[3]) >= 16"
+ "#"
+ "&& !reload_completed"
+ [(set (match_dup 4)
+ (ashift:GPR (match_dup 2) (match_dup 3)))
+ (set (pc)
+ (if_then_else
+ (match_op_dup 0 [(match_dup 4) (const_int 0)])
+ (label_ref (match_operand 1))
+ (pc)))]
+{
+ int shift = GET_MODE_BITSIZE (<MODE>mode) - 1 - INTVAL (operands[3]);
+ operands[3] = GEN_INT (shift);
+ operands[4] = gen_reg_rtx (<MODE>mode);
+
+ if (GET_CODE (operands[0]) == EQ)
+ operands[0] = gen_rtx_GE (<MODE>mode, operands[4], const0_rtx);
+ else
+ operands[0] = gen_rtx_LT (<MODE>mode, operands[4], const0_rtx);
+}
+[(set_attr "type" "branch")])
+
;;
;; ....................
new file mode 100644
@@ -0,0 +1,55 @@
+/* { dg-options "-mips3 -mgp64" } */
+/* FIXME: -Os fails due to rtx_cost: PR115473. */
+/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-Os" } { "" } } */
+/* { dg-final { scan-assembler "f32_15:.*andi\t\\\$4,\\\$4,0x8000" } } */
+/* { dg-final { scan-assembler "f32:.*sll\t\\\$4,\\\$4,15" } } */
+/* { dg-final { scan-assembler "f64_15:.*andi\t\\\$4,\\\$4,0x8000" } } */
+/* { dg-final { scan-assembler "f64:.*dsll\t\\\$4,\\\$4,47" } } */
+
+/* Test to make sure we can use sll+bgtz to test one bit.
+ See PR111376. */
+
+int f1();
+int f2();
+
+/* If the bits is < 16, we can use andi+beqz. */
+NOMIPS16 int
+f32_15(int a)
+{
+ int p = (a & (1<<15));
+ if (p)
+ return f1();
+ else
+ return f2();
+}
+
+/* If the bits >= 16, we can use sll+bgez. */
+NOMIPS16 int
+f32(int a)
+{
+ int p = (a & (1<<16));
+ if (p)
+ return f1();
+ else
+ return f2();
+}
+
+NOMIPS16 int
+f64_15(long long a)
+{
+ long long p = (a & (1LL<<15));
+ if (p)
+ return f1();
+ else
+ return f2();
+}
+
+NOMIPS16 int
+f64(long long a)
+{
+ long long p = (a & (1LL<<16));
+ if (p)
+ return f1();
+ else
+ return f2();
+}