summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-01 09:21:23 +0000
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2016-03-01 09:21:23 +0000
commit6191f2a0a9178047100b5b3977a473d62ea9f845 (patch)
tree7e280c310a8ce6431854ec7979908ba61c019e32 /gcc/config
parente84de992c1616aa1fb534ce3b9931e9313eb19d5 (diff)
downloadgcc-6191f2a0a9178047100b5b3977a473d62ea9f845.tar.gz
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-03-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com> * config/s390/predicates.md (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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@233843 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/s390/constraints.md4
-rw-r--r--gcc/config/s390/predicates.md4
-rw-r--r--gcc/config/s390/s390.c23
-rw-r--r--gcc/config/s390/s390.md31
-rw-r--r--gcc/config/s390/subst.md61
5 files changed, 100 insertions, 23 deletions
diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index c1d2c8ec8f8..60a7edf8b51 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -36,6 +36,7 @@
;; jyy: constant consisting of byte chunks being either 0 or 0xff
;; jKK: constant vector with all elements having the same value and
;; matching K constraint
+;; jm6: An integer operand with the lowest order 6 bits all ones.
;; t -- Access registers 36 and 37.
;; v -- Vector registers v0-v31.
;; C -- A signed 8-bit constant (-128..127)
@@ -415,6 +416,9 @@
(match_test "const_vec_duplicate_p (op)"))
(match_test "satisfies_constraint_K (XVECEXP (op, 0, 0))")))
+(define_constraint "jm6"
+ "@internal An integer operand with the lowest order 6 bits all ones."
+ (match_operand 0 "const_int_6bitset_operand"))
;;
;; Memory constraints follow.
diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index cbc80921479..fefefb32474 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -115,6 +115,10 @@
return true;
})
+; An integer operand with the lowest order 6 bits 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.c b/gcc/config/s390/s390.c
index cd53b15f112..43219dd8f02 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -2994,18 +2994,18 @@ s390_decompose_address (rtx addr, struct s390_address *out)
bool
s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
{
- HOST_WIDE_INT off = 0;
+ rtx off = NULL_RTX;
/* We can have an integer constant, an address register,
or a sum of the two. */
- if (GET_CODE (op) == CONST_INT)
+ if (CONST_SCALAR_INT_P (op))
{
- off = INTVAL (op);
+ off = op;
op = NULL_RTX;
}
- if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+ if (op && GET_CODE (op) == PLUS && CONST_SCALAR_INT_P (XEXP (op, 1)))
{
- off = INTVAL (XEXP (op, 1));
+ off = XEXP (op, 1);
op = XEXP (op, 0);
}
while (op && GET_CODE (op) == SUBREG)
@@ -3015,7 +3015,18 @@ s390_decompose_shift_count (rtx op, rtx *base, HOST_WIDE_INT *offset)
return false;
if (offset)
- *offset = off;
+ {
+ if (off == NULL_RTX)
+ *offset = 0;
+ else if (CONST_INT_P (off))
+ *offset = INTVAL (off);
+ else if (CONST_WIDE_INT_P (off))
+ /* The offset will anyway be cut down to 12 bits so take just
+ the lowest order chunk of the wide int. */
+ *offset = CONST_WIDE_INT_ELT (off, 0);
+ else
+ gcc_unreachable ();
+ }
if (base)
*base = op;
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 65b6ce9085c..b7c037a5229 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -741,6 +741,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")
@@ -8376,28 +8378,23 @@
; 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 "nonmemory_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")
+ (rotate:GPR (match_operand:GPR 1 "register_operand" "d")
+ (match_operand:SI 2 "nonmemory_operand" "an")))]
+ "TARGET_CPU_ZARCH"
+ "rll<g>\t%0,%1,<addr_style_op_ops>"
[(set_attr "op_type" "RSE")
(set_attr "atype" "reg")
- (set_attr "z10prop" "z10_super_E1")])
+ (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 00000000000..c3761a972a2
--- /dev/null
+++ b/gcc/config/s390/subst.md
@@ -0,0 +1,61 @@
+;;- 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 [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 "" "")))]
+ ""
+ [(set (match_dup 0)
+ (SUBST:DSI (match_dup 1)
+ (plus:SI (match_operand:SI 2 "register_operand" "a")
+ (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 %Y is able to print the
+; operand either as displacement or as base register.
+(define_subst_attr "addr_style_op_ops" "addr_style_op_subst" "%Y2" "%Y3(%2)")
+
+
+; 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" "jm6"))))])
+
+; Use this in the insn name.
+(define_subst_attr "masked_op" "masked_op_subst" "" "_and")
+