OSDN Git Service

2005-08-12 Andreas Krebbel <krebbel1@de.ibm.com>
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Aug 2005 12:24:05 +0000 (12:24 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 12 Aug 2005 12:24:05 +0000 (12:24 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103028 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 8378a7f..9b8cf8a 100644 (file)
@@ -1,5 +1,15 @@
 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):
        Type cast added.
        (s390_const_ok_for_constraint_p): Added SImode to the N constraint.
index fb8a9a4..05ef8c8 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 551ffed..277006f 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 ee87cf6..c09df12 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))]