Commit 191eb16d by Andreas Krebbel Committed by Andreas Krebbel

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.

From-SVN: r233843
parent 62d3f261
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.
2016-03-01 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
* config/s390/s390.md ("op_type", "atype", "length" attributes):
Remove RRR type. It doesn't really exist.
("RRer", "f0", "v0", "vf", "vd", "op1", "Rf"): Remove mode
......
......@@ -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.
......
......@@ -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)")))
......
......@@ -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;
......
......@@ -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")])
;;
......
;;- 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")
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment