predicates.md (setmem_operand): New predicate.
authorAndreas Krebbel <krebbel1@de.ibm.com>
Fri, 12 Aug 2005 12:24:05 +0000 (12:24 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Fri, 12 Aug 2005 12:24:05 +0000 (12:24 +0000)
2005-08-12  Andreas Krebbel  <krebbel1@de.ibm.com>

* config/s390/predicates.md (setmem_operand): New predicate.
(shift_count_operand): Accept ANDs with special constants as
operand.
* config/s390/s390.c (print_shift_count_operand): Skip ANDs
with special constants.
* config/s390/s390.md ("setmem_long", "*setmem_long"): Replaced
shift_count_operand with setmem_operand.

From-SVN: r103028

gcc/ChangeLog
gcc/config/s390/predicates.md
gcc/config/s390/s390.c
gcc/config/s390/s390.md

index 8378a7f504edb27160e0ca16b13f9eadb33122af..9b8cf8a3cf685e03aa5d94b07cb8a68a59c2cd8c 100644 (file)
@@ -1,3 +1,13 @@
+2005-08-12  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * config/s390/predicates.md (setmem_operand): New predicate.
+       (shift_count_operand): Accept ANDs with special constants as
+       operand.
+       * config/s390/s390.c (print_shift_count_operand): Skip ANDs
+       with special constants.
+       * config/s390/s390.md ("setmem_long", "*setmem_long"): Replaced
+       shift_count_operand with setmem_operand.
+
 2005-08-12  Andreas Krebbel  <krebbel1@de.ibm.com>
 
        * config/s390/s390.c (s390_extract_part, s390_single_part):
index fb8a9a400851881ba2735aff7f69fa1ddce03590..05ef8c87a15b5a1685c962820ce8623e8a9c9e34 100644 (file)
        (and (match_test "mode == Pmode")
            (match_test "!legitimate_la_operand_p (op)"))))
 
+;; Return true if OP is a valid operand for setmem.
+
+(define_predicate "setmem_operand"
+  (match_code "reg, subreg, plus, const_int")
+{
+  HOST_WIDE_INT offset = 0;
+
+  /* The padding byte operand of the mvcle instruction is always truncated
+     to the 8 least significant bits.  */
+  if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT
+      && (INTVAL (XEXP (op, 1)) & 255) == 255)
+    op = XEXP (op, 0);
+
+  /* We can have an integer constant, an address register,
+     or a sum of the two.  Note that reload already checks
+     that any register present is an address register, so
+     we just check for any register here.  */
+  if (GET_CODE (op) == CONST_INT)
+    {
+      offset = INTVAL (op);
+      op = NULL_RTX;
+    }
+  if (op && GET_CODE (op) == PLUS && GET_CODE (XEXP (op, 1)) == CONST_INT)
+    {
+      offset = INTVAL (XEXP (op, 1));
+      op = XEXP (op, 0);
+    }
+  while (op && GET_CODE (op) == SUBREG)
+    op = SUBREG_REG (op);
+  if (op && GET_CODE (op) != REG)
+    return false;
+
+  /* Unfortunately we have to reject constants that are invalid
+     for an address, or else reload will get confused.  */
+  if (!DISP_IN_RANGE (offset))
+    return false;
+
+  return true;
+})
+
 ;; Return true if OP is a valid shift count operand.
 
 (define_predicate "shift_count_operand"
-  (match_code "reg, subreg, plus, const_int")
+  (match_code "reg, subreg, plus, const_int, and")
 {
   HOST_WIDE_INT offset = 0;
 
+  /* Shift count operands are always truncated to the 6 least significant bits.
+     So we can accept pointless ANDs here.  */
+  if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT
+      && (INTVAL (XEXP (op, 1)) & 63) == 63)
+    op = XEXP (op, 0);
+
   /* We can have an integer constant, an address register,
      or a sum of the two.  Note that reload already checks
      that any register present is an address register, so
index 551ffedbc8008972fded6989cc23728a798f6302..277006f6473115b7fbf7334f599c3e32f4413985 100644 (file)
@@ -3758,6 +3758,17 @@ print_shift_count_operand (FILE *file, rtx op)
 {
   HOST_WIDE_INT offset = 0;
 
+  /* Shift count operands are always truncated to the 6 least significant bits and
+     the setmem padding byte to the least 8 significant bits.  Hence we can drop
+     pointless ANDs.  */
+  if (GET_CODE (op) == AND && GET_CODE (XEXP (op, 1)) == CONST_INT)
+    {
+      if ((INTVAL (XEXP (op, 1)) & 63) != 63)
+       gcc_unreachable ();
+
+      op = XEXP (op, 0);
+    }
+
   /* We can have an integer constant, an address register,
      or a sum of the two.  */
   if (GET_CODE (op) == CONST_INT)
index ee87cf6938b72e8fef26d791a39f05b0930e1ba0..c09df126c03bc53f099e9385ffeeaa89c2354b60 100644 (file)
   [(parallel
     [(clobber (match_dup 1))
      (set (match_operand:BLK 0 "memory_operand" "")
-          (match_operand 2 "shift_count_operand" ""))
+          (match_operand 2 "setmem_operand" ""))
      (use (match_operand 1 "general_operand" ""))
      (use (match_dup 3))
      (clobber (reg:CC CC_REGNUM))])]
 (define_insn "*setmem_long"
   [(clobber (match_operand:<DBL> 0 "register_operand" "=d"))
    (set (mem:BLK (subreg:P (match_operand:<DBL> 3 "register_operand" "0") 0))
-        (match_operand 2 "shift_count_operand" "Y"))
+        (match_operand 2 "setmem_operand" "Y"))
    (use (match_dup 3))
    (use (match_operand:<DBL> 1 "register_operand" "d"))
    (clobber (reg:CC CC_REGNUM))]