summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2009-07-22 07:47:04 +0000
committerkrebbel <krebbel@138bc75d-0d04-0410-961f-82ee72b054a4>2009-07-22 07:47:04 +0000
commita7b49046022583de01cb0b2743ab8e97bd2d10ca (patch)
treebc375d66fda821d2492c02adfae74c3d9f2913f5
parent5ba2ce8208e4a70665c5f0d87c7bc788e6e79bac (diff)
downloadgcc-a7b49046022583de01cb0b2743ab8e97bd2d10ca.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@149917 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/s390/constraints.md32
-rw-r--r--gcc/config/s390/s390.c210
-rw-r--r--gcc/config/s390/s390.md67
4 files changed, 185 insertions, 139 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ced279d4adf..7e939cd45a5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/s390/constraints.md b/gcc/config/s390/constraints.md
index 8fec7e124a6..8564b6619a5 100644
--- a/gcc/config/s390/constraints.md
+++ b/gcc/config/s390/constraints.md
@@ -66,9 +66,14 @@
;; 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)"))
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 350850ace36..1454fde2fd8 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -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. */
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index ed08f6ee6a6..b6a54469498 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -1440,7 +1440,7 @@
(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
@@ -1623,7 +1623,7 @@
(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
@@ -1658,7 +1658,7 @@
(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"
"@
@@ -1684,7 +1684,7 @@
(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"
"@
@@ -7402,7 +7402,7 @@
[(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)))]
""
{
@@ -7466,7 +7466,7 @@
(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)
@@ -7673,7 +7673,7 @@
(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)))
@@ -7784,7 +7784,7 @@
;
(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)
@@ -7803,7 +7803,7 @@
;
(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 "" "")))]
""
{
@@ -8025,7 +8025,7 @@
(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"
@@ -8083,7 +8083,7 @@
(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"
@@ -8183,7 +8183,7 @@
(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 "" ""))]
@@ -8709,27 +8709,32 @@
;
(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")])
;