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 5/7] s390: Implement extzv for z10


---
 gcc/config/s390/predicates.md |    4 +++
 gcc/config/s390/s390-protos.h |    1 +
 gcc/config/s390/s390.c        |   16 ++++++++++++
 gcc/config/s390/s390.md       |   55 +++++++++++++++++++++++++++++++++++------
 4 files changed, 68 insertions(+), 8 deletions(-)

diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md
index 333457d..e4632b9 100644
--- a/gcc/config/s390/predicates.md
+++ b/gcc/config/s390/predicates.md
@@ -101,6 +101,10 @@
   return true;
 })
 
+(define_predicate "nonzero_shift_count_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 1, GET_MODE_BITSIZE (mode) - 1)")))
+
 ;;  Return true if OP a valid operand for the LARL instruction.
 
 (define_predicate "larl_operand"
diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h
index 79673d6..97c378f 100644
--- a/gcc/config/s390/s390-protos.h
+++ b/gcc/config/s390/s390-protos.h
@@ -110,5 +110,6 @@ extern bool s390_legitimate_address_without_index_p (rtx);
 extern bool s390_decompose_shift_count (rtx, rtx *, HOST_WIDE_INT *);
 extern int s390_branch_condition_mask (rtx);
 extern int s390_compare_and_branch_condition_mask (rtx);
+extern bool s390_extzv_shift_ok (int, int, unsigned HOST_WIDE_INT);
 
 #endif /* RTX_CODE */
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 4e22100..52138d7 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -1308,6 +1308,22 @@ s390_contiguous_bitmask_p (unsigned HOST_WIDE_INT in, int size,
   return true;
 }
 
+/* Check whether a rotate of ROTL followed by an AND of CONTIG is equivalent
+   to a shift followed by the AND.  In particular, CONTIG should not overlap
+   the (rotated) bit 0/bit 63 gap.  */
+
+bool
+s390_extzv_shift_ok (int bitsize, int rotl, unsigned HOST_WIDE_INT contig)
+{
+  int pos, len;
+  bool ok;
+
+  ok = s390_contiguous_bitmask_p (contig, bitsize, &pos, &len);
+  gcc_assert (ok);
+
+  return (rotl <= pos || rotl >= pos + len + (64 - bitsize));
+}
+
 /* Check whether we can (and want to) split a double-word
    move in mode MODE from SRC to DST into two single-word
    moves, moving the subword FIRST_SUBWORD first.  */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index b6e1535..ae004ac 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -3298,15 +3298,25 @@
   [(set_attr "op_type" "RS,RSY")
    (set_attr "z10prop" "z10_super_E1,z10_super_E1")])
 
+(define_insn "extzv"
+  [(set (match_operand:DI 0 "register_operand" "=d")
+	(zero_extract:DI
+	  (match_operand:DI 1 "register_operand" "d")
+	  (match_operand 2 "const_int_operand" "")
+	  (match_operand 3 "const_int_operand" "")))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_Z10"
+  "risbg\t%0,%1,63-%3-%2,128+63,63-%3-%2"
+  [(set_attr "op_type" "RIE")
+   (set_attr "z10prop" "z10_super_E1")])
 
-(define_insn_and_split "*extzv<mode>"
+(define_insn_and_split "*pre_z10_extzv<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=d")
 	(zero_extract:GPR (match_operand:QI 1 "s_operand" "QS")
-		          (match_operand 2 "const_int_operand" "n")
+		          (match_operand 2 "nonzero_shift_count_operand" "")
 		          (const_int 0)))
    (clobber (reg:CC CC_REGNUM))]
-  "INTVAL (operands[2]) > 0
-   && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
+  "!TARGET_Z10"
   "#"
   "&& reload_completed"
   [(parallel
@@ -3324,14 +3334,13 @@
   operands[3] = GEN_INT (mask);
 })
 
-(define_insn_and_split "*extv<mode>"
+(define_insn_and_split "*pre_z10_extv<mode>"
   [(set (match_operand:GPR 0 "register_operand" "=d")
 	(sign_extract:GPR (match_operand:QI 1 "s_operand" "QS")
-		          (match_operand 2 "const_int_operand" "n")
+		          (match_operand 2 "nonzero_shift_count_operand" "")
 		          (const_int 0)))
    (clobber (reg:CC CC_REGNUM))]
-  "INTVAL (operands[2]) > 0
-   && INTVAL (operands[2]) <= GET_MODE_BITSIZE (SImode)"
+  "!TARGET_Z10"
   "#"
   "&& reload_completed"
   [(parallel
@@ -6034,6 +6043,36 @@
      (clobber (reg:CC CC_REGNUM))])]
   "s390_narrow_logical_operator (AND, &operands[0], &operands[1]);")
 
+;; These two are what combine generates for (ashift (zero_extract)).
+(define_insn "*extzv_<mode>_srl"
+  [(set (match_operand:DSI 0 "register_operand" "=d")
+	(and:DSI (lshiftrt:DSI
+		   (match_operand:DSI 1 "register_operand" "d")
+		   (match_operand:DSI 2 "nonzero_shift_count_operand" ""))
+		(match_operand:DSI 3 "contiguous_bitmask_operand" "")))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_Z10
+   /* Note that even for the SImode pattern, the rotate is always DImode.  */
+   && s390_extzv_shift_ok (<bitsize>, 64 - INTVAL (operands[2]),
+			   INTVAL (operands[3]))"
+  "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,64-%2"
+  [(set_attr "op_type" "RIE")
+   (set_attr "z10prop" "z10_super_E1")])
+
+(define_insn "*extzv_<mode>_sll"
+  [(set (match_operand:DSI 0 "register_operand" "=d")
+	(and:DSI (ashift:DSI
+		  (match_operand:DSI 1 "register_operand" "d")
+		  (match_operand:DSI 2 "nonzero_shift_count_operand" ""))
+		(match_operand:DSI 3 "contiguous_bitmask_operand" "")))
+   (clobber (reg:CC CC_REGNUM))]
+  "TARGET_Z10
+   && s390_extzv_shift_ok (<bitsize>, INTVAL (operands[2]),
+			   INTVAL (operands[3]))"
+  "risbg\t%0,%1,%<bfstart>3,128+%<bfend>3,%2"
+  [(set_attr "op_type" "RIE")
+   (set_attr "z10prop" "z10_super_E1")])
+
 
 ;
 ; andsi3 instruction pattern(s).
-- 
1.7.7.6


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