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
This commit is contained in:
parent
c2db3f3d39
commit
004d38098c
@ -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>
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,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")
|
||||
(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,a")
|
||||
(set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")])
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:SI 0 "s_register_operand" "")
|
||||
|
@ -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
|
||||
;;----------------------------------------------------------------------------
|
||||
|
@ -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")
|
||||
|
Loading…
Reference in New Issue
Block a user