diff options
Diffstat (limited to 'gcc/config/arm')
-rw-r--r-- | gcc/config/arm/constraints.md | 7 | ||||
-rw-r--r-- | gcc/config/arm/thumb2.md | 26 |
2 files changed, 25 insertions, 8 deletions
diff --git a/gcc/config/arm/constraints.md b/gcc/config/arm/constraints.md index cb75558984c..77883e6a34d 100644 --- a/gcc/config/arm/constraints.md +++ b/gcc/config/arm/constraints.md @@ -31,7 +31,7 @@ ;; The following multi-letter normal constraints have been used: ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy ;; in Thumb-1 state: Pa, Pb -;; in Thumb-2 state: Ps, Pt +;; in Thumb-2 state: Ps, Pt, Pu ;; The following memory constraints have been used: ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us @@ -158,6 +158,11 @@ (and (match_code "const_int") (match_test "TARGET_THUMB2 && ival >= -7 && ival <= 7"))) +(define_constraint "Pu" + "@internal In Thumb-2 state a constant in the range +1 to +8" + (and (match_code "const_int") + (match_test "TARGET_THUMB2 && ival >= 1 && ival <= 8"))) + (define_constraint "G" "In ARM/Thumb-2 state a valid FPA immediate constant." (and (match_code "const_double") diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md index e97715ff595..30291b30e21 100644 --- a/gcc/config/arm/thumb2.md +++ b/gcc/config/arm/thumb2.md @@ -1460,13 +1460,14 @@ [(set (pc) (if_then_else (match_operator 0 "equality_operator" - [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l,?h") - (match_operand:SI 2 "const_int_operand" "i,i") + [(zero_extract:SI (match_operand:SI 1 "s_register_operand" "l,h,h") + (match_operand:SI 2 "const_int_operand" "i,Pu,i") (const_int 0)) (const_int 0)]) (label_ref (match_operand 3 "" "")) (pc))) - (clobber (match_scratch:SI 4 "=l,X"))] + (clobber (match_scratch:SI 4 "=l,X,r")) + (clobber (reg:CC CC_REGNUM))] "TARGET_THUMB2" "* { @@ -1487,11 +1488,22 @@ } else { - rtx op[2]; - op[0] = operands[1]; - op[1] = GEN_INT ((1 << INTVAL (operands[2])) - 1); + rtx op[3]; + + if (which_alternative == 1) + { + op[0] = operands[1]; + op[1] = GEN_INT ((1 << INTVAL (operands[2])) - 1); + output_asm_insn (\"tst\\t%0, %1\", op); + } + else + { + op[0] = operands[4]; + op[1] = operands[1]; + op[2] = GEN_INT (32 - INTVAL (operands[2])); + output_asm_insn (\"lsls\\t%0, %1, %2\", op); + } - output_asm_insn (\"tst\\t%0, %1\", op); switch (get_attr_length (insn)) { case 6: return \"b%d0\\t%l3\"; |