diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 2bc2684b82c35a44e0a2cea6e3aaf32d939f8cdf..6a4494a9a370139313cc8e57447717aafa14da2d 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -943,12 +943,28 @@ (define_insn "*cb1" (const_int 1)))] ) -(define_insn "*tb1" +(define_expand "tbranch4" [(set (pc) (if_then_else - (EQL (zero_extract:DI (match_operand:GPI 0 "register_operand" "r") - (const_int 1) - (match_operand 1 - "aarch64_simd_shift_imm_" "n")) + (match_operator 0 "aarch64_comparison_operator" + [(match_operand:ALLI 1 "register_operand") + (match_operand:ALLI 2 "aarch64_simd_shift_imm_")]) + (label_ref (match_operand 3 "" "")) + (pc)))] + "optimize > 0" +{ + rtx bitvalue = gen_reg_rtx (DImode); + emit_insn (gen_extzv (bitvalue, operands[1], const1_rtx, operands[2])); + operands[2] = const0_rtx; + operands[1] = aarch64_gen_compare_reg (GET_CODE (operands[0]), bitvalue, + operands[2]); +}) + +(define_insn "*tb1" + [(set (pc) (if_then_else + (EQL (zero_extract:GPI (match_operand:ALLI 0 "register_operand" "r") + (const_int 1) + (match_operand 1 + "aarch64_simd_shift_imm_" "n")) (const_int 0)) (label_ref (match_operand 2 "" "")) (pc))) @@ -959,15 +975,15 @@ (define_insn "*tb1" { if (get_attr_far_branch (insn) == 1) return aarch64_gen_far_branch (operands, 2, "Ltb", - "\\t%0, %1, "); + "\\t%0, %1, "); else { operands[1] = GEN_INT (HOST_WIDE_INT_1U << UINTVAL (operands[1])); - return "tst\t%0, %1\;\t%l2"; + return "tst\t%0, %1\;\t%l2"; } } else - return "\t%0, %1, %l2"; + return "\t%0, %1, %l2"; } [(set_attr "type" "branch") (set (attr "length") @@ -5752,39 +5768,19 @@ (define_expand "" ) -(define_insn "*" +(define_insn "*" [(set (match_operand:GPI 0 "register_operand" "=r") - (ANY_EXTRACT:GPI (match_operand:GPI 1 "register_operand" "r") + (ANY_EXTRACT:GPI (match_operand:ALLI 1 "register_operand" "r") (match_operand 2 - "aarch64_simd_shift_imm_offset_" "n") + "aarch64_simd_shift_imm_offset_" "n") (match_operand 3 - "aarch64_simd_shift_imm_" "n")))] + "aarch64_simd_shift_imm_" "n")))] "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), - 1, GET_MODE_BITSIZE (mode) - 1)" - "bfx\\t%0, %1, %3, %2" + 1, GET_MODE_BITSIZE (mode))" + "bfx\\t%0, %1, %3, %2" [(set_attr "type" "bfx")] ) -;; When the bit position and width add up to 32 we can use a W-reg LSR -;; instruction taking advantage of the implicit zero-extension of the X-reg. -(define_split - [(set (match_operand:DI 0 "register_operand") - (zero_extract:DI (match_operand:DI 1 "register_operand") - (match_operand 2 - "aarch64_simd_shift_imm_offset_di") - (match_operand 3 - "aarch64_simd_shift_imm_di")))] - "IN_RANGE (INTVAL (operands[2]) + INTVAL (operands[3]), 1, - GET_MODE_BITSIZE (DImode) - 1) - && (INTVAL (operands[2]) + INTVAL (operands[3])) - == GET_MODE_BITSIZE (SImode)" - [(set (match_dup 0) - (zero_extend:DI (lshiftrt:SI (match_dup 4) (match_dup 3))))] - { - operands[4] = gen_lowpart (SImode, operands[1]); - } -) - ;; Bitfield Insert (insv) (define_expand "insv" [(set (zero_extract:GPI (match_operand:GPI 0 "register_operand") diff --git a/gcc/testsuite/gcc.target/aarch64/tbz_1.c b/gcc/testsuite/gcc.target/aarch64/tbz_1.c new file mode 100644 index 0000000000000000000000000000000000000000..86f5d3e23cf7f1ea6f3596549ce1a0cff6774463 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/tbz_1.c @@ -0,0 +1,95 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O2 -std=c99 -fno-unwind-tables -fno-asynchronous-unwind-tables" } */ +/* { dg-final { check-function-bodies "**" "" "" { target { le } } } } */ + +#include + +void h(void); + +/* +** g1: +** tbnz x[0-9]+, #?0, .L([0-9]+) +** ret +** ... +*/ +void g1(bool x) +{ + if (__builtin_expect (x, 0)) + h (); +} + +/* +** g2: +** tbz x[0-9]+, #?0, .L([0-9]+) +** b h +** ... +*/ +void g2(bool x) +{ + if (__builtin_expect (x, 1)) + h (); +} + +/* +** g3_ge: +** tbnz w[0-9]+, #?31, .L[0-9]+ +** b h +** ... +*/ +void g3_ge(int x) +{ + if (__builtin_expect (x >= 0, 1)) + h (); +} + +/* +** g3_gt: +** cmp w[0-9]+, 0 +** ble .L[0-9]+ +** b h +** ... +*/ +void g3_gt(int x) +{ + if (__builtin_expect (x > 0, 1)) + h (); +} + +/* +** g3_lt: +** tbz w[0-9]+, #?31, .L[0-9]+ +** b h +** ... +*/ +void g3_lt(int x) +{ + if (__builtin_expect (x < 0, 1)) + h (); +} + +/* +** g3_le: +** cmp w[0-9]+, 0 +** bgt .L[0-9]+ +** b h +** ... +*/ +void g3_le(int x) +{ + if (__builtin_expect (x <= 0, 1)) + h (); +} + +/* +** g5: +** mov w[0-9]+, 65279 +** tst w[0-9]+, w[0-9]+ +** beq .L[0-9]+ +** b h +** ... +*/ +void g5(int x) +{ + if (__builtin_expect (x & 0xfeff, 1)) + h (); +}