S/390: Memory constraint cleanup
This fixes an issue with the long displacement memory address constraints S and T. These were defined to only accept long displacement addresses. This is wrong since a memory constraint must not reject an address with a 0 displacement. Reload relies on being able to turn an invalid memory address into a valid one by reloading the address into a base register. The S and T constraints would reject such an address. This isn't really a problem for the backend since we used the constraints with that knowledge there but it is a problem for people writing inline assemblies. gcc/ChangeLog: 2016-04-29 Ulrich Weigand <uweigand@de.ibm.com> * config/s390/constraints.md ("U", "W"): Invoke s390_mem_constraint with "ZR" and "ZT". * config/s390/s390.c (s390_check_qrst_address): Reject invalid addresses when using LRA. Accept also short displacements for S and T constraints. Do not check for long displacement target for S and T constraints. (s390_mem_constraint): Remove handling of U and W constraints. * config/s390/s390.md (various patterns): Remove the short displacement constraints (Q and R) if a long displacement constraint is present. Add longdisp as required CPU capability. * config/s390/vector.md: Likewise. * config/s390/vx-builtins.md: Likewise. From-SVN: r235626
This commit is contained in:
parent
849b265de1
commit
3e4be43f69
6 changed files with 274 additions and 230 deletions
|
@ -1,3 +1,18 @@
|
||||||
|
2016-04-29 Ulrich Weigand <uweigand@de.ibm.com>
|
||||||
|
|
||||||
|
* config/s390/constraints.md ("U", "W"): Invoke
|
||||||
|
s390_mem_constraint with "ZR" and "ZT".
|
||||||
|
* config/s390/s390.c (s390_check_qrst_address): Reject invalid
|
||||||
|
addresses when using LRA. Accept also short displacements for S
|
||||||
|
and T constraints. Do not check for long displacement target for
|
||||||
|
S and T constraints.
|
||||||
|
(s390_mem_constraint): Remove handling of U and W constraints.
|
||||||
|
* config/s390/s390.md (various patterns): Remove the short
|
||||||
|
displacement constraints (Q and R) if a long displacement
|
||||||
|
constraint is present. Add longdisp as required CPU capability.
|
||||||
|
* config/s390/vector.md: Likewise.
|
||||||
|
* config/s390/vx-builtins.md: Likewise.
|
||||||
|
|
||||||
2016-04-29 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
|
2016-04-29 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
|
||||||
|
|
||||||
PR target/60040
|
PR target/60040
|
||||||
|
|
|
@ -77,8 +77,8 @@
|
||||||
;; B -- Multiple letter constraint followed by Q, R, S, or T:
|
;; B -- Multiple letter constraint followed by Q, R, S, or T:
|
||||||
;; Memory reference of the type specified by second letter that
|
;; Memory reference of the type specified by second letter that
|
||||||
;; does *not* refer to a literal pool entry.
|
;; does *not* refer to a literal pool entry.
|
||||||
;; U -- Pointer with short displacement. (deprecated - use ZQZR)
|
;; U -- Pointer with short displacement. (deprecated - use ZR)
|
||||||
;; W -- Pointer with long displacement. (deprecated - use ZSZT)
|
;; W -- Pointer with long displacement. (deprecated - use ZT)
|
||||||
;; Y -- Address style operand without index.
|
;; Y -- Address style operand without index.
|
||||||
;; ZQ -- Pointer without index register and with short displacement.
|
;; ZQ -- Pointer without index register and with short displacement.
|
||||||
;; ZR -- Pointer with index register and short displacement.
|
;; ZR -- Pointer with index register and short displacement.
|
||||||
|
@ -455,8 +455,7 @@
|
||||||
; the TARGET_MEM_CONSTRAINT macro.
|
; the TARGET_MEM_CONSTRAINT macro.
|
||||||
(define_memory_constraint "m"
|
(define_memory_constraint "m"
|
||||||
"Matches the most general memory address for pre-z10 machines."
|
"Matches the most general memory address for pre-z10 machines."
|
||||||
(match_test "s390_mem_constraint (\"R\", op)
|
(match_test "s390_mem_constraint (\"T\", op)"))
|
||||||
|| s390_mem_constraint (\"T\", op)"))
|
|
||||||
|
|
||||||
(define_memory_constraint "AQ"
|
(define_memory_constraint "AQ"
|
||||||
"@internal
|
"@internal
|
||||||
|
@ -512,12 +511,12 @@
|
||||||
|
|
||||||
|
|
||||||
(define_address_constraint "U"
|
(define_address_constraint "U"
|
||||||
"Pointer with short displacement. (deprecated - use ZQZR)"
|
"Pointer with short displacement. (deprecated - use ZR)"
|
||||||
(match_test "s390_mem_constraint (\"U\", op)"))
|
(match_test "s390_mem_constraint (\"ZR\", op)"))
|
||||||
|
|
||||||
(define_address_constraint "W"
|
(define_address_constraint "W"
|
||||||
"Pointer with long displacement. (deprecated - use ZSZT)"
|
"Pointer with long displacement. (deprecated - use ZT)"
|
||||||
(match_test "s390_mem_constraint (\"W\", op)"))
|
(match_test "s390_mem_constraint (\"ZT\", op)"))
|
||||||
|
|
||||||
|
|
||||||
(define_address_constraint "ZQ"
|
(define_address_constraint "ZQ"
|
||||||
|
|
|
@ -3116,6 +3116,19 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
|
||||||
decomposed = true;
|
decomposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* With reload, we sometimes get intermediate address forms that are
|
||||||
|
actually invalid as-is, but we need to accept them in the most
|
||||||
|
generic cases below ('R' or 'T'), since reload will in fact fix
|
||||||
|
them up. LRA behaves differently here; we never see such forms,
|
||||||
|
but on the other hand, we need to strictly reject every invalid
|
||||||
|
address form. Perform this check right up front. */
|
||||||
|
if (lra_in_progress)
|
||||||
|
{
|
||||||
|
if (!decomposed && !s390_decompose_address (op, &addr))
|
||||||
|
return 0;
|
||||||
|
decomposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 'Q': /* no index short displacement */
|
case 'Q': /* no index short displacement */
|
||||||
|
@ -3140,25 +3153,17 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S': /* no index long displacement */
|
case 'S': /* no index long displacement */
|
||||||
if (!TARGET_LONG_DISPLACEMENT)
|
|
||||||
return 0;
|
|
||||||
if (!decomposed && !s390_decompose_address (op, &addr))
|
if (!decomposed && !s390_decompose_address (op, &addr))
|
||||||
return 0;
|
return 0;
|
||||||
if (addr.indx)
|
if (addr.indx)
|
||||||
return 0;
|
return 0;
|
||||||
if (s390_short_displacement (addr.disp))
|
|
||||||
return 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T': /* with index long displacement */
|
case 'T': /* with index long displacement */
|
||||||
if (!TARGET_LONG_DISPLACEMENT)
|
|
||||||
return 0;
|
|
||||||
/* Any invalid address here will be fixed up by reload,
|
/* Any invalid address here will be fixed up by reload,
|
||||||
so accept it for the most generic constraint. */
|
so accept it for the most generic constraint. */
|
||||||
if ((decomposed || s390_decompose_address (op, &addr))
|
|
||||||
&& s390_short_displacement (addr.disp))
|
|
||||||
return 0;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3167,7 +3172,7 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
|
||||||
|
|
||||||
|
|
||||||
/* Evaluates constraint strings described by the regular expression
|
/* 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
|
([A|B|Z](Q|R|S|T))|Y and returns 1 if OP is a valid operand for
|
||||||
the constraint given in STR, or 0 else. */
|
the constraint given in STR, or 0 else. */
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -3197,12 +3202,6 @@ s390_mem_constraint (const char *str, rtx op)
|
||||||
if (GET_CODE (op) != MEM)
|
if (GET_CODE (op) != MEM)
|
||||||
return 0;
|
return 0;
|
||||||
return s390_check_qrst_address (c, XEXP (op, 0), true);
|
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':
|
case 'Y':
|
||||||
/* Simply check for the basic form of a shift count. Reload will
|
/* Simply check for the basic form of a shift count. Reload will
|
||||||
take care of making sure we have a proper base register. */
|
take care of making sure we have a proper base register. */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -137,8 +137,8 @@
|
||||||
|
|
||||||
; Full HW vector size moves
|
; Full HW vector size moves
|
||||||
(define_insn "mov<mode>"
|
(define_insn "mov<mode>"
|
||||||
[(set (match_operand:V_128 0 "nonimmediate_operand" "=v, v,QR, v, v, v, v, v,v,d")
|
[(set (match_operand:V_128 0 "nonimmediate_operand" "=v,v,R, v, v, v, v, v,v,d")
|
||||||
(match_operand:V_128 1 "general_operand" " v,QR, v,j00,jm1,jyy,jxx,jKK,d,v"))]
|
(match_operand:V_128 1 "general_operand" " v,R,v,j00,jm1,jyy,jxx,jKK,d,v"))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"@
|
"@
|
||||||
vlr\t%v0,%v1
|
vlr\t%v0,%v1
|
||||||
|
@ -178,8 +178,8 @@
|
||||||
; However, this would probably be slower.
|
; However, this would probably be slower.
|
||||||
|
|
||||||
(define_insn "mov<mode>"
|
(define_insn "mov<mode>"
|
||||||
[(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d, v,QR, v, v, v, v,d, Q, S, Q, S, d, d,d,d,d,R,T")
|
[(set (match_operand:V_8 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, S, Q, S, d, d,d,d,d,R,T")
|
||||||
(match_operand:V_8 1 "general_operand" " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
|
(match_operand:V_8 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
vlr\t%v0,%v1
|
vlr\t%v0,%v1
|
||||||
|
@ -206,8 +206,8 @@
|
||||||
[(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RX,RXY,RIL,RX,RXY")])
|
[(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SI,SIY,SI,SIY,RI,RI,RX,RXY,RIL,RX,RXY")])
|
||||||
|
|
||||||
(define_insn "mov<mode>"
|
(define_insn "mov<mode>"
|
||||||
[(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d, v,QR, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b")
|
[(set (match_operand:V_16 0 "nonimmediate_operand" "=v,v,d,v,R, v, v, v, v,d, Q, Q, d, d,d,d,d,R,T,b")
|
||||||
(match_operand:V_16 1 "general_operand" " v,d,v,QR, v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
|
(match_operand:V_16 1 "general_operand" " v,d,v,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
|
||||||
""
|
""
|
||||||
"@
|
"@
|
||||||
vlr\t%v0,%v1
|
vlr\t%v0,%v1
|
||||||
|
@ -233,8 +233,8 @@
|
||||||
[(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
|
[(set_attr "op_type" "VRR,VRS,VRS,VRX,VRX,VRI,VRI,VRI,VRI,RR,SIL,SIL,RI,RI,RX,RXY,RIL,RX,RXY,RIL")])
|
||||||
|
|
||||||
(define_insn "mov<mode>"
|
(define_insn "mov<mode>"
|
||||||
[(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d, v,QR, f, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b")
|
[(set (match_operand:V_32 0 "nonimmediate_operand" "=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,d,d,d,d,R,T,b")
|
||||||
(match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
|
(match_operand:V_32 1 "general_operand" " f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"@
|
"@
|
||||||
lder\t%v0,%v1
|
lder\t%v0,%v1
|
||||||
|
@ -268,9 +268,9 @@
|
||||||
|
|
||||||
(define_insn "mov<mode>"
|
(define_insn "mov<mode>"
|
||||||
[(set (match_operand:V_64 0 "nonimmediate_operand"
|
[(set (match_operand:V_64 0 "nonimmediate_operand"
|
||||||
"=f,f,f,R,T,v,v,d, v,QR, f, v, v, v, v, Q, Q, d, d,f,d,d,d, d,RT,b")
|
"=f,f,f,R,T,v,v,d,v,R, f, v, v, v, v, Q, Q, d, d,f,d,d,d,d,T,b")
|
||||||
(match_operand:V_64 1 "general_operand"
|
(match_operand:V_64 1 "general_operand"
|
||||||
" f,R,T,f,f,v,d,v,QR, v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,RT, d,d"))]
|
" f,R,T,f,f,v,d,v,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,d,f,b,d,T,d,d"))]
|
||||||
"TARGET_ZARCH"
|
"TARGET_ZARCH"
|
||||||
"@
|
"@
|
||||||
ldr\t%0,%1
|
ldr\t%0,%1
|
||||||
|
@ -322,10 +322,10 @@
|
||||||
; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
|
; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
|
||||||
; that itself?
|
; that itself?
|
||||||
(define_insn "*vec_set<mode>"
|
(define_insn "*vec_set<mode>"
|
||||||
[(set (match_operand:V 0 "register_operand" "=v, v,v")
|
[(set (match_operand:V 0 "register_operand" "=v,v,v")
|
||||||
(unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,QR,K")
|
(unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,R,K")
|
||||||
(match_operand:SI 2 "nonmemory_operand" "an, I,I")
|
(match_operand:SI 2 "nonmemory_operand" "an,I,I")
|
||||||
(match_operand:V 3 "register_operand" "0, 0,0")]
|
(match_operand:V 3 "register_operand" "0,0,0")]
|
||||||
UNSPEC_VEC_SET))]
|
UNSPEC_VEC_SET))]
|
||||||
"TARGET_VX
|
"TARGET_VX
|
||||||
&& (!CONST_INT_P (operands[2])
|
&& (!CONST_INT_P (operands[2])
|
||||||
|
@ -359,9 +359,9 @@
|
||||||
"TARGET_VX")
|
"TARGET_VX")
|
||||||
|
|
||||||
(define_insn "*vec_extract<mode>"
|
(define_insn "*vec_extract<mode>"
|
||||||
[(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,QR")
|
[(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R")
|
||||||
(unspec:<non_vec> [(match_operand:V 1 "register_operand" "v, v")
|
(unspec:<non_vec> [(match_operand:V 1 "register_operand" "v,v")
|
||||||
(match_operand:SI 2 "nonmemory_operand" "an, I")]
|
(match_operand:SI 2 "nonmemory_operand" "an,I")]
|
||||||
UNSPEC_VEC_EXTRACT))]
|
UNSPEC_VEC_EXTRACT))]
|
||||||
"TARGET_VX
|
"TARGET_VX
|
||||||
&& (!CONST_INT_P (operands[2])
|
&& (!CONST_INT_P (operands[2])
|
||||||
|
@ -404,7 +404,7 @@
|
||||||
|
|
||||||
(define_insn "*vec_splats<mode>"
|
(define_insn "*vec_splats<mode>"
|
||||||
[(set (match_operand:V_HW 0 "register_operand" "=v,v,v,v")
|
[(set (match_operand:V_HW 0 "register_operand" "=v,v,v,v")
|
||||||
(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand" "QR,K,v,d")))]
|
(vec_duplicate:V_HW (match_operand:<non_vec> 1 "general_operand" " R,K,v,d")))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"@
|
"@
|
||||||
vlrep<bhfgq>\t%v0,%1
|
vlrep<bhfgq>\t%v0,%1
|
||||||
|
|
|
@ -70,7 +70,7 @@
|
||||||
[(set (match_operand:V_HW_32_64 0 "register_operand" "=v")
|
[(set (match_operand:V_HW_32_64 0 "register_operand" "=v")
|
||||||
(unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand" "0")
|
(unspec:V_HW_32_64 [(match_operand:V_HW_32_64 1 "register_operand" "0")
|
||||||
(match_operand:<tointvec> 2 "register_operand" "v")
|
(match_operand:<tointvec> 2 "register_operand" "v")
|
||||||
(match_operand:BLK 3 "memory_operand" "QR")
|
(match_operand:BLK 3 "memory_operand" "R")
|
||||||
(match_operand:QI 4 "const_mask_operand" "C")]
|
(match_operand:QI 4 "const_mask_operand" "C")]
|
||||||
UNSPEC_VEC_GATHER))]
|
UNSPEC_VEC_GATHER))]
|
||||||
"TARGET_VX && UINTVAL (operands[4]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
|
"TARGET_VX && UINTVAL (operands[4]) < GET_MODE_NUNITS (<V_HW_32_64:MODE>mode)"
|
||||||
|
@ -170,7 +170,7 @@
|
||||||
|
|
||||||
(define_insn "vec_insert_and_zero<mode>"
|
(define_insn "vec_insert_and_zero<mode>"
|
||||||
[(set (match_operand:V_HW 0 "register_operand" "=v")
|
[(set (match_operand:V_HW 0 "register_operand" "=v")
|
||||||
(unspec:V_HW [(match_operand:<non_vec> 1 "memory_operand" "QR")]
|
(unspec:V_HW [(match_operand:<non_vec> 1 "memory_operand" "R")]
|
||||||
UNSPEC_VEC_INSERT_AND_ZERO))]
|
UNSPEC_VEC_INSERT_AND_ZERO))]
|
||||||
"TARGET_VX"
|
"TARGET_VX"
|
||||||
"vllez<bhfgq>\t%v0,%1"
|
"vllez<bhfgq>\t%v0,%1"
|
||||||
|
@ -178,7 +178,7 @@
|
||||||
|
|
||||||
(define_insn "vlbb"
|
(define_insn "vlbb"
|
||||||
[(set (match_operand:V16QI 0 "register_operand" "=v")
|
[(set (match_operand:V16QI 0 "register_operand" "=v")
|
||||||
(unspec:V16QI [(match_operand:BLK 1 "memory_operand" "QR")
|
(unspec:V16QI [(match_operand:BLK 1 "memory_operand" "R")
|
||||||
(match_operand:QI 2 "const_mask_operand" "C")]
|
(match_operand:QI 2 "const_mask_operand" "C")]
|
||||||
UNSPEC_VEC_LOAD_BNDRY))]
|
UNSPEC_VEC_LOAD_BNDRY))]
|
||||||
"TARGET_VX && UINTVAL (operands[2]) < 7"
|
"TARGET_VX && UINTVAL (operands[2]) < 7"
|
||||||
|
|
Loading…
Add table
Reference in a new issue