This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
- From: Andreas Krebbel <krebbel at linux dot vnet dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 14 Jan 2016 17:33:28 +0100
- Subject: [PATCH 3/9] S/390: Get rid of Y constraint in rotate patterns.
- Authentication-results: sourceware.org; auth=none
- References: <1452789254-12603-1-git-send-email-krebbel at linux dot vnet dot ibm dot com>
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