From: Paul Brook Date: Sat, 15 Mar 2008 16:58:09 +0000 (+0000) Subject: arm.md (insv): Use gen_insv_t2 and gen_insv_zero. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ef87d898649555989d8dc35fa08ac792cb017417;p=gcc.git arm.md (insv): Use gen_insv_t2 and gen_insv_zero. 2008-03-15 Paul Brook * config/arm/arm.md (insv): Use gen_insv_t2 and gen_insv_zero. (extzv): Use gen_extzv_t2. (insv_t2, insv_zero, extv, extzv_t2): New patterns. From-SVN: r133254 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba568d83e6b..7c10c75f5db 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-03-15 Paul Brook + + * config/arm/arm.md (insv): Use gen_insv_t2 and gen_insv_zero. + (extzv): Use gen_extzv_t2. + (insv_t2, insv_zero, extv, extzv_t2): New patterns. + 2008-03-15 Richard Guenther * tree-ssa-ccp.c (get_symbol_constant_value): Export. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 5b40449cee1..dcac1346281 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -2145,13 +2145,12 @@ ;;; the value before we insert. This loses some of the advantage of having ;;; this insv pattern, so this pattern needs to be reevalutated. -; ??? Use Thumb-2 bitfield insert/extract instructions (define_expand "insv" [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "") (match_operand:SI 1 "general_operand" "") (match_operand:SI 2 "general_operand" "")) (match_operand:SI 3 "reg_or_int_operand" ""))] - "TARGET_ARM" + "TARGET_ARM || arm_arch_thumb2" " { int start_bit = INTVAL (operands[2]); @@ -2159,6 +2158,37 @@ HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1; rtx target, subtarget; + if (arm_arch_thumb2) + { + bool use_bfi = TRUE; + + if (GET_CODE (operands[3]) == CONST_INT) + { + HOST_WIDE_INT val = INTVAL (operands[3]) & mask; + + if (val == 0) + { + emit_insn (gen_insv_zero (operands[0], operands[1], + operands[2])); + DONE; + } + + /* See if the set can be done with a single orr instruction. */ + if (val == mask && const_ok_for_arm (val << start_bit)) + use_bfi = FALSE; + } + + if (use_bfi) + { + if (GET_CODE (operands[3]) != REG) + operands[3] = force_reg (SImode, operands[3]); + + emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2], + operands[3])); + DONE; + } + } + target = operands[0]; /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical subreg as the final target. */ @@ -2282,6 +2312,28 @@ }" ) +(define_insn "insv_zero" + [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") + (match_operand:SI 1 "const_int_operand" "M") + (match_operand:SI 2 "const_int_operand" "M")) + (const_int 0))] + "arm_arch_thumb2" + "bfc%?\t%0, %2, %1" + [(set_attr "length" "4") + (set_attr "predicable" "yes")] +) + +(define_insn "insv_t2" + [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") + (match_operand:SI 1 "const_int_operand" "M") + (match_operand:SI 2 "const_int_operand" "M")) + (match_operand:SI 3 "s_register_operand" "r"))] + "arm_arch_thumb2" + "bfi%?\t%0, %3, %2, %1" + [(set_attr "length" "4") + (set_attr "predicable" "yes")] +) + ; constants for op 2 will never be given to these patterns. (define_insn_and_split "*anddi_notdi_di" [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") @@ -3287,12 +3339,19 @@ (set (match_operand:SI 0 "register_operand" "") (lshiftrt:SI (match_dup 4) (match_operand:SI 3 "const_int_operand" "")))] - "TARGET_THUMB1" + "TARGET_THUMB1 || arm_arch_thumb2" " { HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]); HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]); + if (arm_arch_thumb2) + { + emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2], + operands[3])); + DONE; + } + operands[3] = GEN_INT (rshift); if (lshift == 0) @@ -3306,6 +3365,28 @@ }" ) +(define_insn "extv" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "const_int_operand" "M") + (match_operand:SI 3 "const_int_operand" "M")))] + "arm_arch_thumb2" + "sbfx%?\t%0, %1, %3, %2" + [(set_attr "length" "4") + (set_attr "predicable" "yes")] +) + +(define_insn "extzv_t2" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "const_int_operand" "M") + (match_operand:SI 3 "const_int_operand" "M")))] + "arm_arch_thumb2" + "ubfx%?\t%0, %1, %3, %2" + [(set_attr "length" "4") + (set_attr "predicable" "yes")] +) + ;; Unary arithmetic insns