@@ -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")
+ (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" "")
@@ -191,6 +191,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")