diff mbox

[committed] Update extract and insert patterns on PA

Message ID 20130109031101.GA27027@hiauly1.hia.nrc.ca
State New
Headers show

Commit Message

John David Anglin Jan. 9, 2013, 3:11 a.m. UTC
The attached change updates the extract and insert patterns on HP PA.
It removes the deprecated extzv, extv and insv expanders, replacing them
with SI and DI mode variant.  Operand predicates are tightened in these
and related insn patterns.  Predicates are also tightened some shift
patterns.

Two new shift patterns are introduced which I plan to use to support
misalign loads.

Tested on hppa2.0w-hp-hpux11.11 and hppa64-hp-hpux11.11 with no observed
regressions.

Committed to trunk.

Dave
diff mbox

Patch

Index: config/pa/pa.h
===================================================================
--- config/pa/pa.h	(revision 195003)
+++ config/pa/pa.h	(working copy)
@@ -956,6 +956,9 @@ 
 #define VAL_U5_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) < 0x20)
 #define INT_U5_BITS(X) VAL_U5_BITS_P (INTVAL (X))
 
+#define VAL_U6_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) < 0x40)
+#define INT_U6_BITS(X) VAL_U6_BITS_P (INTVAL (X))
+
 #define VAL_11_BITS_P(X) ((unsigned HOST_WIDE_INT)(X) + 0x400 < 0x800)
 #define INT_11_BITS(X) VAL_11_BITS_P (INTVAL (X))
 
Index: config/pa/predicates.md
===================================================================
--- config/pa/predicates.md	(revision 195003)
+++ config/pa/predicates.md	(working copy)
@@ -32,6 +32,13 @@ 
        (match_test "INT_U5_BITS (op)")))
 
 ;; Return truth value of whether OP is an integer which fits the range
+;; constraining 6-bit unsigned immediate operands in three-address insns.
+
+(define_predicate "uint6_operand"
+  (and (match_code "const_int")
+       (match_test "INT_U6_BITS (op)")))
+
+;; Return truth value of whether OP is an integer which fits the range
 ;; constraining 11-bit signed immediate operands in three-address insns.
 
 (define_predicate "int11_operand"
@@ -125,6 +132,20 @@ 
   (ior (match_operand 0 "register_operand")
        (match_code "const_int")))
 
+;; Return truth value of whether OP can be used as a shift operand in
+;; a shift insn that accepts registers of mode MODE or 5-bit shift amounts.
+
+(define_predicate "shift5_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "uint5_operand")))
+
+;; Return truth value of whether OP can be used as a shift operand in
+;; a shift insn that accepts registers of mode MODE or 6-bit shift amounts.
+
+(define_predicate "shift6_operand"
+  (ior (match_operand 0 "register_operand")
+       (match_operand 0 "uint6_operand")))
+
 ;; True iff OP can be used as an operand in an adddi3 insn.
 
 (define_predicate "adddi3_operand"
Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md	(revision 195003)
+++ config/pa/pa.md	(working copy)
@@ -6584,7 +6584,7 @@ 
 (define_insn "lshrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
-		     (match_operand:SI 2 "arith32_operand" "q,n")))]
+		     (match_operand:SI 2 "shift5_operand" "q,n")))]
   ""
   "@
    {vshd %%r0,%1,%0|shrpw %%r0,%1,%%sar,%0}
@@ -6595,7 +6595,7 @@ 
 (define_insn "lshrdi3"
   [(set (match_operand:DI 0 "register_operand" "=r,r")
 	(lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
-		     (match_operand:DI 2 "arith32_operand" "q,n")))]
+		     (match_operand:DI 2 "shift6_operand" "q,n")))]
   "TARGET_64BIT"
   "@
    shrpd %%r0,%1,%%sar,%0
@@ -6603,10 +6603,40 @@ 
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
+; Shift right pair word 0 to 31 bits.
+(define_insn "shrpsi4"
+  [(set (match_operand:SI 0 "register_operand" "=r,r")
+	(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
+			   (minus:SI (const_int 32)
+			     (match_operand:SI 3 "shift5_operand" "q,n")))
+		(lshiftrt:SI (match_operand:SI 2 "register_operand" "r,r")
+			     (match_dup 3))))]
+  ""
+  "@
+   {vshd %1,%2,%0|shrpw %1,%2,%%sar,%0}
+   {shd|shrpw} %1,%2,%3,%0"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
+; Shift right pair doubleword 0 to 63 bits.
+(define_insn "shrpdi4"
+  [(set (match_operand:DI 0 "register_operand" "=r,r")
+	(ior:DI (ashift:DI (match_operand:SI 1 "register_operand" "r,r")
+			   (minus:DI (const_int 64)
+			     (match_operand:DI 3 "shift6_operand" "q,n")))
+		(lshiftrt:DI (match_operand:DI 2 "register_operand" "r,r")
+			     (match_dup 3))))]
+  "TARGET_64BIT"
+  "@
+   shrpd %1,%2,%%sar,%0
+   shrpd %1,%2,%3,%0"
+  [(set_attr "type" "shift")
+   (set_attr "length" "4")])
+
 (define_insn "rotrsi3"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
 	(rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
-		     (match_operand:SI 2 "arith32_operand" "q,n")))]
+		     (match_operand:SI 2 "shift5_operand" "q,n")))]
   ""
   "*
 {
@@ -8365,21 +8395,22 @@ 
 }")
 
 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
-(define_expand "extzv"
-  [(set (match_operand 0 "register_operand" "")
-	(zero_extract (match_operand 1 "register_operand" "")
-		      (match_operand 2 "uint32_operand" "")
-		      (match_operand 3 "uint32_operand" "")))]
+(define_expand "extzvsi"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(zero_extract:SI (match_operand:SI 1 "register_operand" "")
+			 (match_operand:SI 2 "uint5_operand" "")
+			 (match_operand:SI 3 "uint5_operand" "")))]
   ""
   "
 {
-  HOST_WIDE_INT len = INTVAL (operands[2]);
-  HOST_WIDE_INT pos = INTVAL (operands[3]);
+  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
+  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
 
   /* PA extraction insns don't support zero length bitfields or fields
-     extending beyond the left or right-most bits.  Also, we reject lengths
-     equal to a word as they are better handled by the move patterns.  */
-  if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
+     extending beyond the left or right-most bits.  Also, the predicate
+     rejects lengths equal to a word as they are better handled by
+     the move patterns.  */
+  if (len == 0 || pos + len > 32)
     FAIL;
 
   /* From mips.md: extract_bit_field doesn't verify that our source
@@ -8387,12 +8418,8 @@ 
   if (!register_operand (operands[1], VOIDmode))
     FAIL;
 
-  if (TARGET_64BIT)
-    emit_insn (gen_extzv_64 (operands[0], operands[1],
-			     operands[2], operands[3]));
-  else
-    emit_insn (gen_extzv_32 (operands[0], operands[1],
-			     operands[2], operands[3]));
+  emit_insn (gen_extzv_32 (operands[0], operands[1],
+			   operands[2], operands[3]));
   DONE;
 }")
 
@@ -8401,7 +8428,8 @@ 
 	(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
 			 (match_operand:SI 2 "uint5_operand" "")
 			 (match_operand:SI 3 "uint5_operand" "")))]
-  ""
+  "UINTVAL (operands[2]) > 0
+   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
   "{extru|extrw,u} %1,%3+%2-1,%2,%0"
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
@@ -8416,12 +8444,42 @@ 
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
+(define_expand "extzvdi"
+  [(set (match_operand:DI 0 "register_operand" "")
+	(zero_extract:DI (match_operand:DI 1 "register_operand" "")
+			 (match_operand:DI 2 "uint6_operand" "")
+			 (match_operand:DI 3 "uint6_operand" "")))]
+  "TARGET_64BIT"
+  "
+{
+  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
+  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
+
+  /* PA extraction insns don't support zero length bitfields or fields
+     extending beyond the left or right-most bits.  Also, the predicate
+     rejects lengths equal to a doubleword as they are better handled by
+     the move patterns.  */
+  if (len == 0 || pos + len > 64)
+    FAIL;
+
+  /* From mips.md: extract_bit_field doesn't verify that our source
+     matches the predicate, so check it again here.  */
+  if (!register_operand (operands[1], VOIDmode))
+    FAIL;
+
+  emit_insn (gen_extzv_64 (operands[0], operands[1],
+			   operands[2], operands[3]));
+  DONE;
+}")
+
 (define_insn "extzv_64"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(zero_extract:DI (match_operand:DI 1 "register_operand" "r")
-			 (match_operand:DI 2 "uint32_operand" "")
-			 (match_operand:DI 3 "uint32_operand" "")))]
-  "TARGET_64BIT"
+			 (match_operand:DI 2 "uint6_operand" "")
+			 (match_operand:DI 3 "uint6_operand" "")))]
+  "TARGET_64BIT
+   && UINTVAL (operands[2]) > 0
+   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
   "extrd,u %1,%3+%2-1,%2,%0"
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
@@ -8437,21 +8495,22 @@ 
    (set_attr "length" "4")])
 
 ;;; Operands 2 and 3 are assumed to be CONST_INTs.
-(define_expand "extv"
-  [(set (match_operand 0 "register_operand" "")
-	(sign_extract (match_operand 1 "register_operand" "")
-		      (match_operand 2 "uint32_operand" "")
-		      (match_operand 3 "uint32_operand" "")))]
+(define_expand "extvsi"
+  [(set (match_operand:SI 0 "register_operand" "")
+	(sign_extract:SI (match_operand:SI 1 "register_operand" "")
+			 (match_operand:SI 2 "uint5_operand" "")
+			 (match_operand:SI 3 "uint5_operand" "")))]
   ""
   "
 {
-  HOST_WIDE_INT len = INTVAL (operands[2]);
-  HOST_WIDE_INT pos = INTVAL (operands[3]);
+  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
+  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
 
   /* PA extraction insns don't support zero length bitfields or fields
-     extending beyond the left or right-most bits.  Also, we reject lengths
-     equal to a word as they are better handled by the move patterns.  */
-  if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
+     extending beyond the left or right-most bits.  Also, the predicate
+     rejects lengths equal to a word as they are better handled by
+     the move patterns.  */
+  if (len == 0 || pos + len > 32)
     FAIL;
 
   /* From mips.md: extract_bit_field doesn't verify that our source
@@ -8459,12 +8518,8 @@ 
   if (!register_operand (operands[1], VOIDmode))
     FAIL;
 
-  if (TARGET_64BIT)
-    emit_insn (gen_extv_64 (operands[0], operands[1],
-			    operands[2], operands[3]));
-  else
-    emit_insn (gen_extv_32 (operands[0], operands[1],
-			    operands[2], operands[3]));
+  emit_insn (gen_extv_32 (operands[0], operands[1],
+			  operands[2], operands[3]));
   DONE;
 }")
 
@@ -8473,7 +8528,8 @@ 
 	(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
 			 (match_operand:SI 2 "uint5_operand" "")
 			 (match_operand:SI 3 "uint5_operand" "")))]
-  ""
+  "UINTVAL (operands[2]) > 0
+   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 32"
   "{extrs|extrw,s} %1,%3+%2-1,%2,%0"
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
@@ -8488,12 +8544,42 @@ 
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
+(define_expand "extvdi"
+  [(set (match_operand:DI 0 "register_operand" "")
+	(sign_extract:DI (match_operand:DI 1 "register_operand" "")
+			 (match_operand:DI 2 "uint6_operand" "")
+			 (match_operand:DI 3 "uint6_operand" "")))]
+  "TARGET_64BIT"
+  "
+{
+  unsigned HOST_WIDE_INT len = UINTVAL (operands[2]);
+  unsigned HOST_WIDE_INT pos = UINTVAL (operands[3]);
+
+  /* PA extraction insns don't support zero length bitfields or fields
+     extending beyond the left or right-most bits.  Also, the predicate
+     rejects lengths equal to a doubleword as they are better handled by
+     the move patterns.  */
+  if (len == 0 || pos + len > 64)
+    FAIL;
+
+  /* From mips.md: extract_bit_field doesn't verify that our source
+     matches the predicate, so check it again here.  */
+  if (!register_operand (operands[1], VOIDmode))
+    FAIL;
+
+  emit_insn (gen_extv_64 (operands[0], operands[1],
+			  operands[2], operands[3]));
+  DONE;
+}")
+
 (define_insn "extv_64"
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(sign_extract:DI (match_operand:DI 1 "register_operand" "r")
-			 (match_operand:DI 2 "uint32_operand" "")
-			 (match_operand:DI 3 "uint32_operand" "")))]
-  "TARGET_64BIT"
+			 (match_operand:DI 2 "uint6_operand" "")
+			 (match_operand:DI 3 "uint6_operand" "")))]
+  "TARGET_64BIT
+   && UINTVAL (operands[2]) > 0
+   && UINTVAL (operands[2]) + UINTVAL (operands[3]) <= 64"
   "extrd,s %1,%3+%2-1,%2,%0"
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
@@ -8509,21 +8595,22 @@ 
    (set_attr "length" "4")])
 
 ;;; Operands 1 and 2 are assumed to be CONST_INTs.
-(define_expand "insv"
-  [(set (zero_extract (match_operand 0 "register_operand" "")
-                      (match_operand 1 "uint32_operand" "")
-                      (match_operand 2 "uint32_operand" ""))
-        (match_operand 3 "arith5_operand" ""))]
+(define_expand "insvsi"
+  [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "")
+			 (match_operand:SI 1 "uint5_operand" "")
+			 (match_operand:SI 2 "uint5_operand" ""))
+	(match_operand:SI 3 "arith5_operand" ""))]
   ""
   "
 {
-  HOST_WIDE_INT len = INTVAL (operands[1]);
-  HOST_WIDE_INT pos = INTVAL (operands[2]);
+  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
+  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
 
   /* PA insertion insns don't support zero length bitfields or fields
-     extending beyond the left or right-most bits.  Also, we reject lengths
-     equal to a word as they are better handled by the move patterns.  */
-  if (len <= 0 || len >= BITS_PER_WORD || pos < 0 || pos + len > BITS_PER_WORD)
+     extending beyond the left or right-most bits.  Also, the predicate
+     rejects lengths equal to a word as they are better handled by
+     the move patterns.  */
+  if (len <= 0 || pos + len > 32)
     FAIL;
 
   /* From mips.md: insert_bit_field doesn't verify that our destination
@@ -8531,12 +8618,8 @@ 
   if (!register_operand (operands[0], VOIDmode))
     FAIL;
 
-  if (TARGET_64BIT)
-    emit_insn (gen_insv_64 (operands[0], operands[1],
-			    operands[2], operands[3]));
-  else
-    emit_insn (gen_insv_32 (operands[0], operands[1],
-			    operands[2], operands[3]));
+  emit_insn (gen_insv_32 (operands[0], operands[1],
+			  operands[2], operands[3]));
   DONE;
 }")
 
@@ -8545,7 +8628,8 @@ 
 			 (match_operand:SI 1 "uint5_operand" "")
 			 (match_operand:SI 2 "uint5_operand" ""))
 	(match_operand:SI 3 "arith5_operand" "r,L"))]
-  ""
+  "UINTVAL (operands[1]) > 0
+   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 32"
   "@
    {dep|depw} %3,%2+%1-1,%1,%0
    {depi|depwi} %3,%2+%1-1,%1,%0"
@@ -8568,12 +8652,42 @@ 
   [(set_attr "type" "shift")
    (set_attr "length" "4")])
 
+(define_expand "insvdi"
+  [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "")
+			 (match_operand:DI 1 "uint6_operand" "")
+			 (match_operand:DI 2 "uint6_operand" ""))
+	(match_operand:DI 3 "arith5_operand" ""))]
+  "TARGET_64BIT"
+  "
+{
+  unsigned HOST_WIDE_INT len = UINTVAL (operands[1]);
+  unsigned HOST_WIDE_INT pos = UINTVAL (operands[2]);
+
+  /* PA insertion insns don't support zero length bitfields or fields
+     extending beyond the left or right-most bits.  Also, the predicate
+     rejects lengths equal to a doubleword as they are better handled by
+     the move patterns.  */
+  if (len <= 0 || pos + len > 64)
+    FAIL;
+
+  /* From mips.md: insert_bit_field doesn't verify that our destination
+     matches the predicate, so check it again here.  */
+  if (!register_operand (operands[0], VOIDmode))
+    FAIL;
+
+  emit_insn (gen_insv_64 (operands[0], operands[1],
+			  operands[2], operands[3]));
+  DONE;
+}")
+
 (define_insn "insv_64"
   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r,r")
-			 (match_operand:DI 1 "uint32_operand" "")
-			 (match_operand:DI 2 "uint32_operand" ""))
-	(match_operand:DI 3 "arith32_operand" "r,L"))]
-  "TARGET_64BIT"
+			 (match_operand:DI 1 "uint6_operand" "")
+			 (match_operand:DI 2 "uint6_operand" ""))
+	(match_operand:DI 3 "arith5_operand" "r,L"))]
+  "TARGET_64BIT
+   && UINTVAL (operands[1]) > 0
+   && UINTVAL (operands[1]) + UINTVAL (operands[2]) <= 64"
   "@
    depd %3,%2+%1-1,%1,%0
    depdi %3,%2+%1-1,%1,%0"
@@ -8583,8 +8697,8 @@ 
 ;; Optimize insertion of const_int values of type 1...1xxxx.
 (define_insn ""
   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
-			 (match_operand:DI 1 "uint32_operand" "")
-			 (match_operand:DI 2 "uint32_operand" ""))
+			 (match_operand:DI 1 "uint6_operand" "")
+			 (match_operand:DI 2 "uint6_operand" ""))
 	(match_operand:DI 3 "const_int_operand" ""))]
   "(INTVAL (operands[3]) & 0x10) != 0
    && TARGET_64BIT