]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
iterators.md (shiftable_ops): New code iterator.
authorRichard Earnshaw <rearnsha@arm.com>
Thu, 29 May 2014 09:39:07 +0000 (09:39 +0000)
committerRichard Earnshaw <rearnsha@gcc.gnu.org>
Thu, 29 May 2014 09:39:07 +0000 (09:39 +0000)
        * 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

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md
gcc/config/arm/iterators.md
gcc/config/arm/predicates.md

index 1eebdacf6cf1d9f95a5d9d99aa190787a23e65e1..99c1ffc292f225f20aca4323881638a8cae82ec0 100644 (file)
@@ -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>
 
index 48c8091bd6da5165f881745ec017b42ac5398ba2..1117bd49a5a55c29e2c5529c3dfff6752978cec2 100644 (file)
@@ -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);
index 74403fdc7c08582e255c795d42f3c3dfa2245da9..75d054116f31e941dc76ed88c1041be1a2280e1b 100644 (file)
          (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")
 \f
 ;; 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" "")
index 892e5f328b968c84442830dd7a2850e672fd7d69..6fe6eef2736da6a99c7021157dd8f3f6fdb8117c 100644 (file)
 ;; 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
 ;;----------------------------------------------------------------------------
index d74fcb31bc7667ce549e4380a68237ce107c3558..032808c5a6281575c7e1dc330d2a16e0d5d21f91 100644 (file)
                              || ((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")