This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.


This patch introduces substitution patterns to add PLUS const_int, and
AND operands to patterns and uses this to rewrite the existing rotate
pattern.

gcc/ChangeLog:

2016-01-14  Andreas Krebbel  <krebbel@linux.vnet.ibm.com>

	* config/s390/predicates.md (addrreg_or_constint_operand)
	(const_int_6bitset_operand): New predicates.
	* config/s390/s390.md: Include subst.md.
	("rotl<mode>3"): New expander.
	("rotl<mode>3", "*rotl<mode>3_and"): Merge insn definitions into
	...
	("*rotl<mode>3<addr_style_op><masked_op>"): New insn definition.
	* config/s390/subst.md: New file.
---
 gcc/config/s390/predicates.md | 25 ++++++++++++++++
 gcc/config/s390/s390.md       | 34 +++++++++++-----------
 gcc/config/s390/subst.md      | 66 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 108 insertions(+), 17 deletions(-)
 create mode 100644 gcc/config/s390/subst.md

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index cbc8092..b58cb22 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -115,6 +115,31 @@
   return true;
 })
 
+; Accept single register and immediate operands usable as shift
+; counts.
+(define_predicate "addrreg_or_constint_operand"
+  (match_code "reg, subreg, const_int")
+{
+  if (GET_MODE (op) != VOIDmode
+      && GET_MODE_CLASS (GET_MODE (op)) != MODE_INT)
+    return false;
+
+  while (op && GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+
+  if (REG_P (op)
+      && (REGNO (op) >= FIRST_PSEUDO_REGISTER || ADDR_REG_P (op)))
+    return true;
+
+  if (CONST_INT_P (op))
+    return true;
+
+  return false;
+})
+; An integer operand with the lowest order 6 bit all ones.
+(define_predicate "const_int_6bitset_operand"
+ (and (match_code "const_int")
+      (match_test "(INTVAL (op) & 63) == 63")))
 (define_predicate "nonzero_shift_count_operand"
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 39467ad..3ed10f4 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -739,6 +739,8 @@
 (define_mode_attr asm_fcmp [(CCVEQ "e") (CCVFH "h") (CCVFHE "he")])
 (define_mode_attr insn_cmp [(CCVEQ "eq") (CCVH "h") (CCVHU "hl") (CCVFH "h") (CCVFHE "he")])
 
+;; Subst pattern definitions
+(include "subst.md")
 
 (include "vector.md")
 
@@ -8350,28 +8352,26 @@
 ; rotl(di|si)3 instruction pattern(s).
 ;
 
-; rll, rllg
-(define_insn "rotl<mode>3"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")))]
+(define_expand "rotl<mode>3"
+  [(set (match_operand:GPR 0 "register_operand" "")
+        (rotate:GPR (match_operand:GPR 1 "register_operand" "")
+		    (match_operand:SI 2 "shift_count_or_setmem_operand" "")))]
   "TARGET_CPU_ZARCH"
-  "rll<g>\t%0,%1,%Y2"
-  [(set_attr "op_type"  "RSE")
-   (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+  "")
 
 ; rll, rllg
-(define_insn "*rotl<mode>3_and"
-  [(set (match_operand:GPR 0 "register_operand" "=d")
-	(rotate:GPR (match_operand:GPR 1 "register_operand" "d")
-		    (and:SI (match_operand:SI 2 "shift_count_or_setmem_operand" "Y")
-			    (match_operand:SI 3 "const_int_operand"   "n"))))]
-  "TARGET_CPU_ZARCH && (INTVAL (operands[3]) & 63) == 63"
-  "rll<g>\t%0,%1,%Y2"
+(define_insn "*rotl<mode>3<addr_style_op><masked_op>"
+  [(set (match_operand:GPR             0 "register_operand"           "=d,d")
+	(rotate:GPR (match_operand:GPR 1 "register_operand"            "d,d")
+		    (match_operand:SI  2 "addrreg_or_constint_operand" "a,n")))]
+  "TARGET_CPU_ZARCH"
+  "@
+   rll<g>\t%0,%1,<addr_style_op_op3>(%2)
+   rll<g>\t%0,%1,%Y2"
   [(set_attr "op_type"  "RSE")
    (set_attr "atype"    "reg")
-   (set_attr "z10prop" "z10_super_E1")])
+   (set_attr "disabled" "0,<addr_style_op_disable>")
+   (set_attr "z10prop"  "z10_super_E1")])
 
 
 ;;
diff --git a/gcc/config/s390/subst.md b/gcc/config/s390/subst.md
new file mode 100644
index 0000000..481f33e
--- /dev/null
+++ b/gcc/config/s390/subst.md
@@ -0,0 +1,66 @@
+;;- Machine description for GNU compiler -- S/390 / zSeries version.
+;;  Subst patterns.
+;;  Copyright (C) 2016 Free Software Foundation, Inc.
+;;  Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
+
+;; This file is part of GCC.
+
+;; GCC is free software; you can redistribute it and/or modify it under
+;; the terms of the GNU General Public License as published by the Free
+;; Software Foundation; either version 3, or (at your option) any later
+;; version.
+
+;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+;; WARRANTY; without even the implied warranty of MERCHANTABILITY or
+;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+;; for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+(define_code_iterator SUBST [ashift lshiftrt rotate])
+
+; This expands an register/immediate operand to a register+immediate
+; operand to draw advantage of the address style operand format
+; providing a addition for free.
+(define_subst "addr_style_op_subst"
+  [(set (match_operand:DSI 0 "" "")
+        (SUBST:DSI (match_operand:DSI 1 "" "")
+		   (match_operand:SI 2 "" "")))]
+  "REG_P (operands[2])"
+  [(set (match_dup 0)
+        (SUBST:DSI (match_dup 1)
+		   (plus:SI (match_dup 2)
+			    (match_operand 3 "const_int_operand" "n"))))])
+
+; Use this in the insn name.
+(define_subst_attr "addr_style_op"     "addr_style_op_subst" "" "_plus")
+
+; In the subst pattern the additional const int operand will be used
+; as displacement.  In the normal version the displacements stays just
+; 0.
+(define_subst_attr "addr_style_op_op3" "addr_style_op_subst" "0" "%Y3")
+
+; In the subst pattern we have to disable the alternative where op2 is
+; already a constant.  This attribute is supposed to be used in the
+; "disabled" insn attribute to achieve this.
+(define_subst_attr "addr_style_op_disable" "addr_style_op_subst" "0" "1")
+
+
+; This substitution adds an explicit AND operation to the second
+; operand.  This way previous operations on the now masked out bits
+; might get optimized away.
+(define_subst "masked_op_subst"
+  [(set (match_operand:DSI 0 ""           "")
+        (SUBST:DSI (match_operand:DSI 1 "" "")
+		   (match_operand:SI  2 "" "")))]
+  ""
+  [(set (match_dup 0)
+        (SUBST:DSI (match_dup 1)
+		   (and:SI (match_dup 2)
+			   (match_operand:SI 3 "const_int_6bitset_operand" ""))))])
+
+; Use this in the insn name.
+(define_subst_attr "masked_op" "masked_op_subst" "" "_and")
+
-- 
1.9.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]