diff options
author | Richard Earnshaw <rearnsha@arm.com> | 2014-05-29 09:39:07 +0000 |
---|---|---|
committer | Richard Earnshaw <rearnsha@gcc.gnu.org> | 2014-05-29 09:39:07 +0000 |
commit | 004d38098c5e8c2153d07da36b79ceb81f0140b4 (patch) | |
tree | 54a60f968af1ecc6bc7cf4112ee10001cb8cf78d /gcc | |
parent | c2db3f3d39a5e955c0739367332cb4f3ee5ca890 (diff) | |
download | gcc-004d38098c5e8c2153d07da36b79ceb81f0140b4.zip gcc-004d38098c5e8c2153d07da36b79ceb81f0140b4.tar.gz gcc-004d38098c5e8c2153d07da36b79ceb81f0140b4.tar.bz2 |
iterators.md (shiftable_ops): New code iterator.
* arm/iterators.md (shiftable_ops): New code iterator.
(t2_binop0, arith_shift_insn): New code attributes.
* arm/predicates.md (shift_nomul_operator): New predicate.
* arm/arm.md (insn_enabled): Delete.
(enabled): Remove insn_enabled test.
(*arith_shiftsi): Delete. Replace with ...
(*<arith_shift_insn>_multsi): ... new pattern.
(*<arith_shift_insn>_shiftsi): ... new pattern.
* config/arm/arm.c (arm_print_operand): Handle operand format 'b'.
Co-Authored-By: Richard Sandiford <rdsandiford@googlemail.com>
From-SVN: r211050
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 23 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 62 | ||||
-rw-r--r-- | gcc/config/arm/iterators.md | 14 | ||||
-rw-r--r-- | gcc/config/arm/predicates.md | 9 |
5 files changed, 83 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1eebdac..99c1ffc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2014-05-29 Richard Earnshaw <rearnsha@arm.com> + Richard Sandiford <rdsandiford@googlemail.com> + + * arm/iterators.md (shiftable_ops): New code iterator. + (t2_binop0, arith_shift_insn): New code attributes. + * arm/predicates.md (shift_nomul_operator): New predicate. + * arm/arm.md (insn_enabled): Delete. + (enabled): Remove insn_enabled test. + (*arith_shiftsi): Delete. Replace with ... + (*<arith_shift_insn>_multsi): ... new pattern. + (*<arith_shift_insn>_shiftsi): ... new pattern. + * config/arm/arm.c (arm_print_operand): Handle operand format 'b'. + 2014-05-29 Radovan Obradovic <robradovic@mips.com> Tom de Vries <tom@codesourcery.com> diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 48c8091..1117bd4 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -21271,7 +21271,15 @@ arm_print_condition (FILE *stream) } -/* If CODE is 'd', then the X is a condition operand and the instruction +/* Globally reserved letters: acln + Puncutation letters currently used: @_|?().!# + Lower case letters currently used: bcdefhimpqtvwxyz + Upper case letters currently used: ABCDFGHJKLMNOPQRSTU + Letters previously used, but now deprecated/obsolete: sVWXYZ. + + Note that the global reservation for 'c' is only for CONSTANT_ADDRESS_P. + + If CODE is 'd', then the X is a condition operand and the instruction should only be executed if the condition is true. if CODE is 'D', then the X is a condition operand and the instruction should only be executed if the condition is false: however, if the mode @@ -21411,6 +21419,19 @@ arm_print_operand (FILE *stream, rtx x, int code) } return; + case 'b': + /* Print the log2 of a CONST_INT. */ + { + HOST_WIDE_INT val; + + if (!CONST_INT_P (x) + || (val = exact_log2 (INTVAL (x) & 0xffffffff)) < 0) + output_operand_lossage ("Unsupported operand for code '%c'", code); + else + fprintf (stream, "#" HOST_WIDE_INT_PRINT_DEC, val); + } + return; + case 'L': /* The low 16 bits of an immediate constant. */ fprintf (stream, HOST_WIDE_INT_PRINT_DEC, INTVAL(x) & 0xffff); diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 74403fd..75d0541 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -200,17 +200,9 @@ (const_string "yes")] (const_string "no"))) -; Allows an insn to disable certain alternatives for reasons other than -; arch support. -(define_attr "insn_enabled" "no,yes" - (const_string "yes")) - ; Enable all alternatives that are both arch_enabled and insn_enabled. (define_attr "enabled" "no,yes" - (cond [(eq_attr "insn_enabled" "no") - (const_string "no") - - (and (eq_attr "predicable_short_it" "no") + (cond [(and (eq_attr "predicable_short_it" "no") (and (eq_attr "predicated" "yes") (match_test "arm_restrict_it"))) (const_string "no") @@ -9876,38 +9868,34 @@ ;; Patterns to allow combination of arithmetic, cond code and shifts -(define_insn "*arith_shiftsi" - [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") - (match_operator:SI 1 "shiftable_operator" - [(match_operator:SI 3 "shift_operator" - [(match_operand:SI 4 "s_register_operand" "r,r,r,r") - (match_operand:SI 5 "shift_amount_operand" "M,M,M,r")]) - (match_operand:SI 2 "s_register_operand" "rk,rk,r,rk")]))] +(define_insn "*<arith_shift_insn>_multsi" + [(set (match_operand:SI 0 "s_register_operand" "=r,r") + (shiftable_ops:SI + (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") + (match_operand:SI 3 "power_of_two_operand" "")) + (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))] "TARGET_32BIT" - "%i1%?\\t%0, %2, %4%S3" + "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3" + [(set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no") + (set_attr "shift" "4") + (set_attr "arch" "a,t2") + (set_attr "type" "alu_shift_imm")]) + +(define_insn "*<arith_shift_insn>_shiftsi" + [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") + (shiftable_ops:SI + (match_operator:SI 2 "shift_nomul_operator" + [(match_operand:SI 3 "s_register_operand" "r,r,r") + (match_operand:SI 4 "shift_amount_operand" "M,M,r")]) + (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))] + "TARGET_32BIT && GET_CODE (operands[3]) != MULT" + "<arith_shift_insn>%?\\t%0, %1, %3%S2" [(set_attr "predicable" "yes") (set_attr "predicable_short_it" "no") (set_attr "shift" "4") - (set_attr "arch" "a,t2,t2,a") - ;; Thumb2 doesn't allow the stack pointer to be used for - ;; operand1 for all operations other than add and sub. In this case - ;; the minus operation is a candidate for an rsub and hence needs - ;; to be disabled. - ;; We have to make sure to disable the fourth alternative if - ;; the shift_operator is MULT, since otherwise the insn will - ;; also match a multiply_accumulate pattern and validate_change - ;; will allow a replacement of the constant with a register - ;; despite the checks done in shift_operator. - (set_attr_alternative "insn_enabled" - [(const_string "yes") - (if_then_else - (match_operand:SI 1 "add_operator" "") - (const_string "yes") (const_string "no")) - (const_string "yes") - (if_then_else - (match_operand:SI 3 "mult_operator" "") - (const_string "no") (const_string "yes"))]) - (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_imm,alu_shift_reg")]) + (set_attr "arch" "a,t2,a") + (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")]) (define_split [(set (match_operand:SI 0 "s_register_operand" "") diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 892e5f3..6fe6eef 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -194,6 +194,20 @@ ;; Right shifts (define_code_iterator rshifts [ashiftrt lshiftrt]) +;; Binary operators whose second operand can be shifted. +(define_code_iterator shiftable_ops [plus minus ior xor and]) + +;; plus and minus are the only shiftable_ops for which Thumb2 allows +;; a stack pointer opoerand. The minus operation is a candidate for an rsub +;; and hence only plus is supported. +(define_code_attr t2_binop0 + [(plus "rk") (minus "r") (ior "r") (xor "r") (and "r")]) + +;; The instruction to use when a shiftable_ops has a shift operation as +;; its first operand. +(define_code_attr arith_shift_insn + [(plus "add") (minus "rsb") (ior "orr") (xor "eor") (and "and")]) + ;;---------------------------------------------------------------------------- ;; Int iterators ;;---------------------------------------------------------------------------- diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index d74fcb3..032808c 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -291,6 +291,15 @@ || ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) (match_test "mode == GET_MODE (op)"))) +(define_special_predicate "shift_nomul_operator" + (and (ior (and (match_code "rotate") + (match_test "CONST_INT_P (XEXP (op, 1)) + && ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32")) + (and (match_code "ashift,ashiftrt,lshiftrt,rotatert") + (match_test "!CONST_INT_P (XEXP (op, 1)) + || ((unsigned HOST_WIDE_INT) INTVAL (XEXP (op, 1))) < 32"))) + (match_test "mode == GET_MODE (op)"))) + ;; True for shift operators which can be used with saturation instructions. (define_special_predicate "sat_shift_operator" (and (ior (and (match_code "mult") |