OSDN Git Service

2009-07-22 Andreas Krebbel <krebbel1@de.ibm.com>
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 07:47:04 +0000 (07:47 +0000)
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 22 Jul 2009 07:47:04 +0000 (07:47 +0000)
* config/s390/constraints.md (ZQ, ZR, ZS, ZT): New constraints.
(U, W): Constraints are now deprecated and will be removed if we
run out of letters.
* config/s390/s390.md (U, W): Replaced with ZQZR, ZSZT throughout
the file.
("prefetch"): Add the stcmh instruction for prefetching.
* config/s390/s390.c (s390_symref_operand_p): Function moved. No
changes.
(s390_short_displacement): Return always true if compiling for
machines not providing the long displacement facility.
(s390_mem_constraint): Support the new constraint letter Z.
(s390_check_qrst_address): New function.

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

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

index ced279d..7e939cd 100644 (file)
@@ -1,3 +1,18 @@
+2009-07-22  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * config/s390/constraints.md (ZQ, ZR, ZS, ZT): New constraints.
+       (U, W): Constraints are now deprecated and will be removed if we
+       run out of letters.     
+       * config/s390/s390.md (U, W): Replaced with ZQZR, ZSZT throughout
+       the file.
+       ("prefetch"): Add the stcmh instruction for prefetching.
+       * config/s390/s390.c (s390_symref_operand_p): Function moved. No
+       changes.
+       (s390_short_displacement): Return always true if compiling for
+       machines not providing the long displacement facility.
+       (s390_mem_constraint): Support the new constraint letter Z.
+       (s390_check_qrst_address): New function.
+
 2009-07-21  DJ Delorie  <dj@redhat.com>
 
        * config/mep/mep.c (mep_legitimize_arg): Leave control registers
index 8fec7e1..8564b66 100644 (file)
 ;;    B -- Multiple letter constraint followed by Q, R, S, or T:
 ;;         Memory reference of the type specified by second letter that
 ;;         does *not* refer to a literal pool entry.
-;;    U -- Pointer with short displacement.
-;;    W -- Pointer with long displacement.
+;;    U -- Pointer with short displacement. (deprecated - use ZQZR)
+;;    W -- Pointer with long displacement. (deprecated - use ZSZT)
 ;;    Y -- Shift count operand.
+;;    ZQ -- Pointer without index register and with short displacement.
+;;    ZR -- Pointer with index register and short displacement.
+;;    ZS -- Pointer without index register but with long displacement.
+;;    ZT -- Pointer with index register and long displacement.
+;;
 ;;
 
 
@@ -462,11 +467,26 @@ constraint."
 
 
 (define_address_constraint "U"
-  "Pointer with short displacement"
+  "Pointer with short displacement. (deprecated - use ZQZR)"
   (match_test "s390_mem_constraint (\"U\", op)"))
 
-
-
 (define_address_constraint "W"
-  "Pointer with long displacement"
+  "Pointer with long displacement. (deprecated - use ZSZT)"
   (match_test "s390_mem_constraint (\"W\", op)"))
+
+
+(define_address_constraint "ZQ"
+  "Pointer without index register and with short displacement."
+  (match_test "s390_mem_constraint (\"ZQ\", op)"))
+
+(define_address_constraint "ZR"
+  "Pointer with index register and short displacement."
+  (match_test "s390_mem_constraint (\"ZR\", op)"))
+
+(define_address_constraint "ZS"
+  "Pointer without index register but with long displacement."
+  (match_test "s390_mem_constraint (\"ZS\", op)"))
+
+(define_address_constraint "ZT"
+  "Pointer with index register and long displacement."
+  (match_test "s390_mem_constraint (\"ZT\", op)"))
index 350850a..1454fde 100644 (file)
@@ -1664,6 +1664,11 @@ s390_short_displacement (rtx disp)
   if (!disp)
     return true;
 
+  /* Without the long displacement facility we don't need to
+     distingiush between long and short displacement.  */
+  if (!TARGET_LONG_DISPLACEMENT)
+    return true;
+
   /* Integer displacement in range.  */
   if (GET_CODE (disp) == CONST_INT)
     return INTVAL (disp) >= 0 && INTVAL (disp) < 4096;
@@ -2032,79 +2037,93 @@ s390_legitimate_address_without_index_p (rtx op)
 }
 
 
-/* Evaluates constraint strings described by the regular expression
-   ([A|B](Q|R|S|T))|U|W and returns 1 if OP is a valid operand for the
-   constraint given in STR, or 0 else.  */
+/* Return true if ADDR is of kind symbol_ref or symbol_ref + const_int
+   and return these parts in SYMREF and ADDEND.  You can pass NULL in
+   SYMREF and/or ADDEND if you are not interested in these values.  */
 
-int
-s390_mem_constraint (const char *str, rtx op)
+static bool
+s390_symref_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
 {
-  struct s390_address addr;
-  char c = str[0];
+  HOST_WIDE_INT tmpaddend = 0;
 
-  /* Check for offsettable variants of memory constraints.  */
-  if (c == 'A')
+  if (GET_CODE (addr) == CONST)
+    addr = XEXP (addr, 0);
+
+  if (GET_CODE (addr) == PLUS)
     {
-      /* Only accept non-volatile MEMs.  */
-      if (!MEM_P (op) || MEM_VOLATILE_P (op))
-       return 0;
+      if (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
+         && CONST_INT_P (XEXP (addr, 1)))
+       {
+         tmpaddend = INTVAL (XEXP (addr, 1));
+         addr = XEXP (addr, 0);
+       }
+      else
+       return false;
+    }
+  else
+    if (GET_CODE (addr) != SYMBOL_REF)
+       return false;
 
-      if ((reload_completed || reload_in_progress)
-         ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
-       return 0;
+  if (symref)
+    *symref = addr;
+  if (addend)
+    *addend = tmpaddend;
 
-      c = str[1];
-    }
+  return true;
+}
+
+
+/* Return true if the address in OP is valid for constraint letter C
+   if wrapped in a MEM rtx.  Set LIT_POOL_OK to true if it literal
+   pool MEMs should be accepted.  Only the Q, R, S, T constraint
+   letters are allowed for C.  */
 
-  /* Check for non-literal-pool variants of memory constraints.  */
-  else if (c == 'B')
+static int
+s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
+{
+  struct s390_address addr;
+  bool decomposed = false;
+
+  /* This check makes sure that no symbolic address (except literal
+     pool references) are accepted by the R or T constraints.  */
+  if (s390_symref_operand_p (op, NULL, NULL))
     {
-      if (GET_CODE (op) != MEM)
+      if (!lit_pool_ok)
        return 0;
-      if (!s390_decompose_address (XEXP (op, 0), &addr))
+      if (!s390_decompose_address (op, &addr))
        return 0;
-      if (addr.literal_pool)
+      if (!addr.literal_pool)
        return 0;
-
-      c = str[1];
+      decomposed = true;
     }
 
   switch (c)
     {
-    case 'Q':
-      if (GET_CODE (op) != MEM)
-       return 0;
-      if (!s390_decompose_address (XEXP (op, 0), &addr))
+    case 'Q': /* no index short displacement */
+      if (!decomposed && !s390_decompose_address (op, &addr))
        return 0;
       if (addr.indx)
        return 0;
-
-      if (TARGET_LONG_DISPLACEMENT)
-       {
-         if (!s390_short_displacement (addr.disp))
-           return 0;
-       }
-      break;
-
-    case 'R':
-      if (GET_CODE (op) != MEM)
+      if (!s390_short_displacement (addr.disp))
        return 0;
+      break;
 
+    case 'R': /* with index short displacement */
       if (TARGET_LONG_DISPLACEMENT)
        {
-         if (!s390_decompose_address (XEXP (op, 0), &addr))
+         if (!decomposed && !s390_decompose_address (op, &addr))
            return 0;
          if (!s390_short_displacement (addr.disp))
            return 0;
        }
+      /* Any invalid address here will be fixed up by reload,
+        so accept it for the most generic constraint.  */
       break;
 
-    case 'S':
+    case 'S': /* no index long displacement */
       if (!TARGET_LONG_DISPLACEMENT)
        return 0;
-      if (GET_CODE (op) != MEM)
-       return 0;
-      if (!s390_decompose_address (XEXP (op, 0), &addr))
+      if (!decomposed && !s390_decompose_address (op, &addr))
        return 0;
       if (addr.indx)
        return 0;
@@ -2112,52 +2131,74 @@ s390_mem_constraint (const char *str, rtx op)
        return 0;
       break;
 
-    case 'T':
+    case 'T': /* with index long displacement */
       if (!TARGET_LONG_DISPLACEMENT)
        return 0;
-      if (GET_CODE (op) != MEM)
-       return 0;
-      if (!s390_decompose_address (XEXP (op, 0), &addr))
-       return 0;
-      if (s390_short_displacement (addr.disp))
+      /* Any invalid address here will be fixed up by reload,
+        so accept it for the most generic constraint.  */
+      if ((decomposed || s390_decompose_address (op, &addr))
+         && s390_short_displacement (addr.disp))
        return 0;
       break;
+    default:
+      return 0;
+    }
+  return 1;
+}
 
-    case 'U':
-      if (TARGET_LONG_DISPLACEMENT)
-       {
-         if (!s390_decompose_address (op, &addr))
-           return 0;
-         if (!s390_short_displacement (addr.disp))
-           return 0;
-       }
-      break;
 
-    case 'W':
-      if (!TARGET_LONG_DISPLACEMENT)
+/* Evaluates constraint strings described by the regular expression
+   ([A|B|Z](Q|R|S|T))|U|W|Y and returns 1 if OP is a valid operand for
+   the constraint given in STR, or 0 else.  */
+
+int
+s390_mem_constraint (const char *str, rtx op)
+{
+  char c = str[0];
+
+  switch (c)
+    {
+    case 'A':
+      /* Check for offsettable variants of memory constraints.  */
+      if (!MEM_P (op) || MEM_VOLATILE_P (op))
        return 0;
-      if (!s390_decompose_address (op, &addr))
+      if ((reload_completed || reload_in_progress)
+         ? !offsettable_memref_p (op) : !offsettable_nonstrict_memref_p (op))
        return 0;
-      if (s390_short_displacement (addr.disp))
+      return s390_check_qrst_address (str[1], XEXP (op, 0), true);
+    case 'B':
+      /* Check for non-literal-pool variants of memory constraints.  */
+      if (!MEM_P (op))
        return 0;
-      break;
-
+      return s390_check_qrst_address (str[1], XEXP (op, 0), false);
+    case 'Q':
+    case 'R':
+    case 'S':
+    case 'T':
+      if (GET_CODE (op) != MEM)
+       return 0;
+      return s390_check_qrst_address (c, XEXP (op, 0), true);
+    case 'U':
+      return (s390_check_qrst_address ('Q', op, true)
+             || s390_check_qrst_address ('R', op, true));
+    case 'W':
+      return (s390_check_qrst_address ('S', op, true)
+             || s390_check_qrst_address ('T', op, true));
     case 'Y':
       /* Simply check for the basic form of a shift count.  Reload will
         take care of making sure we have a proper base register.  */
       if (!s390_decompose_shift_count (op, NULL, NULL))
        return 0;
       break;
-
+    case 'Z':
+      return s390_check_qrst_address (str[1], op, true);
     default:
       return 0;
     }
-
   return 1;
 }
 
 
-
 /* Evaluates constraint strings starting with letter O.  Input
    parameter C is the second letter following the "O" in the constraint
    string. Returns 1 if VALUE meets the respective constraint and 0
@@ -2775,41 +2816,6 @@ s390_preferred_reload_class (rtx op, enum reg_class rclass)
   return rclass;
 }
 
-/* Return true if ADDR is of kind symbol_ref or symbol_ref + const_int
-   and return these parts in SYMREF and ADDEND.  You can pass NULL in
-   SYMREF and/or ADDEND if you are not interested in these values.  */
-
-static bool
-s390_symref_operand_p (rtx addr, rtx *symref, HOST_WIDE_INT *addend)
-{
-  HOST_WIDE_INT tmpaddend = 0;
-
-  if (GET_CODE (addr) == CONST)
-    addr = XEXP (addr, 0);
-
-  if (GET_CODE (addr) == PLUS)
-    {
-      if (GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
-         && CONST_INT_P (XEXP (addr, 1)))
-       {
-         tmpaddend = INTVAL (XEXP (addr, 1));
-         addr = XEXP (addr, 0);
-       }
-      else
-       return false;
-    }
-  else
-    if (GET_CODE (addr) != SYMBOL_REF)
-       return false;
-
-  if (symref)
-    *symref = addr;
-  if (addend)
-    *addend = tmpaddend;
-
-  return true;
-}
-
 /* Return true if ADDR is SYMBOL_REF + addend with addend being a
    multiple of ALIGNMENT and the SYMBOL_REF being naturally
    aligned.  */
index ed08f6e..b6a5446 100644 (file)
 
 (define_insn "*la_64"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
-        (match_operand:QI 1 "address_operand" "U,W"))]
+        (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
   "TARGET_64BIT"
   "@
    la\t%0,%a1
 
 (define_insn "*la_31"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (match_operand:QI 1 "address_operand" "U,W"))]
+        (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))]
   "!TARGET_64BIT && legitimate_la_operand_p (operands[1])"
   "@
    la\t%0,%a1
 
 (define_insn "*la_31_and"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (and:SI (match_operand:QI 1 "address_operand" "U,W")
+        (and:SI (match_operand:QI 1 "address_operand" "ZQZR,ZSZT")
                 (const_int 2147483647)))]
   "!TARGET_64BIT"
   "@
 
 (define_insn "force_la_31"
   [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (match_operand:QI 1 "address_operand" "U,W"))
+        (match_operand:QI 1 "address_operand" "ZQZR,ZSZT"))
    (use (const_int 0))]
   "!TARGET_64BIT"
   "@
   [(set (pc)
         (if_then_else
           (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
-          (match_operand 0 "address_operand" "U")
+          (match_operand 0 "address_operand" "ZQZR")
           (pc)))]
   ""
 {
         (if_then_else
           (match_operator 1 "s390_comparison" [(reg CC_REGNUM) (const_int 0)])
           (pc)
-          (match_operand 0 "address_operand" "U")))]
+          (match_operand 0 "address_operand" "ZQZR")))]
   ""
 {
   if (get_attr_op_type (insn) == OP_TYPE_RR)
         (if_then_else
           (ne (match_operand:SI 1 "register_operand" "d")
               (const_int 1))
-          (match_operand 0 "address_operand" "U")
+          (match_operand 0 "address_operand" "ZQZR")
           (pc)))
    (set (match_operand:SI 2 "register_operand" "=1")
         (plus:SI (match_dup 1) (const_int -1)))
 ;
 
 (define_insn "indirect_jump"
- [(set (pc) (match_operand 0 "address_operand" "U"))]
+ [(set (pc) (match_operand 0 "address_operand" "ZQZR"))]
   ""
 {
   if (get_attr_op_type (insn) == OP_TYPE_RR)
 ;
 
 (define_insn "casesi_jump"
- [(set (pc) (match_operand 0 "address_operand" "U"))
+ [(set (pc) (match_operand 0 "address_operand" "ZQZR"))
    (use (label_ref (match_operand 1 "" "")))]
   ""
 {
    (set_attr "type"    "jsr")])
 
 (define_insn "*basr"
-  [(call (mem:QI (match_operand 0 "address_operand" "U"))
+  [(call (mem:QI (match_operand 0 "address_operand" "ZQZR"))
          (match_operand 1 "const_int_operand" "n"))
    (clobber (match_operand 2 "register_operand" "=r"))]
   "!SIBLING_CALL_P (insn) && GET_MODE (operands[2]) == Pmode"
 
 (define_insn "*basr_r"
   [(set (match_operand 0 "" "")
-        (call (mem:QI (match_operand 1 "address_operand" "U"))
+        (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
               (match_operand 2 "const_int_operand" "n")))
    (clobber (match_operand 3 "register_operand" "=r"))]
   "!SIBLING_CALL_P (insn) && GET_MODE (operands[3]) == Pmode"
 
 (define_insn "*basr_tls"
   [(set (match_operand 0 "" "")
-        (call (mem:QI (match_operand 1 "address_operand" "U"))
+        (call (mem:QI (match_operand 1 "address_operand" "ZQZR"))
               (match_operand 2 "const_int_operand" "n")))
    (clobber (match_operand 3 "register_operand" "=r"))
    (use (match_operand 4 "" ""))]
 ;
 
 (define_insn "prefetch"
-  [(prefetch (match_operand 0 "address_operand" "UW,X")
-            (match_operand:SI 1 "const_int_operand" "n,n")
-            (match_operand:SI 2 "const_int_operand" "n,n"))]
-  "TARGET_Z10"
+  [(prefetch (match_operand 0    "address_operand"   "ZQZS,ZRZT,X")
+            (match_operand:SI 1 "const_int_operand" "   n,   n,n")
+            (match_operand:SI 2 "const_int_operand" "   n,   n,n"))]
+  "TARGET_ZARCH && s390_tune == PROCESSOR_2097_Z10"
 {
-  if (larl_operand (operands[0], Pmode))
-    return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
-
-  if (s390_mem_constraint ("W", operands[0])
-      || s390_mem_constraint ("U", operands[0]))
-    return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
-
-  /* This point might be reached if op0 is a larl operand with an
-     uneven addend.  In this case we simply omit issuing a prefetch
-     instruction.  */
-
-  return "";
+  switch (which_alternative)
+    {
+      case 0:
+        return INTVAL (operands[1]) == 1 ? "stcmh\t2,0,%a0" : "stcmh\t1,0,%a0";
+      case 1:
+        return INTVAL (operands[1]) == 1 ? "pfd\t2,%a0" : "pfd\t1,%a0";
+      case 2:
+        if (larl_operand (operands[0], Pmode))
+         return INTVAL (operands[1]) == 1 ? "pfdrl\t2,%a0" : "pfdrl\t1,%a0";
+      default:
+
+        /* This might be reached for symbolic operands with an odd
+           addend.  We simply omit the prefetch for such rare cases.  */
+
+        return "";
+     }
 }
-  [(set_attr "type" "load,larl")
-   (set_attr "op_type" "RXY,RIL")
-   (set_attr "z10prop" "z10_super")])
+  [(set_attr "type" "store,load,larl")
+   (set_attr "op_type" "RSY,RXY,RIL")
+   (set_attr "z10prop" "z10_super")
+   (set_attr "cpu_facility" "*,z10,z10")])
 
 
 ;