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>
|
||||
|
||||
PR target/60040
|
||||
|
|
|
@ -77,8 +77,8 @@
|
|||
;; 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. (deprecated - use ZQZR)
|
||||
;; W -- Pointer with long displacement. (deprecated - use ZSZT)
|
||||
;; U -- Pointer with short displacement. (deprecated - use ZR)
|
||||
;; W -- Pointer with long displacement. (deprecated - use ZT)
|
||||
;; Y -- Address style operand without index.
|
||||
;; ZQ -- Pointer without index register and with short displacement.
|
||||
;; ZR -- Pointer with index register and short displacement.
|
||||
|
@ -455,8 +455,7 @@
|
|||
; the TARGET_MEM_CONSTRAINT macro.
|
||||
(define_memory_constraint "m"
|
||||
"Matches the most general memory address for pre-z10 machines."
|
||||
(match_test "s390_mem_constraint (\"R\", op)
|
||||
|| s390_mem_constraint (\"T\", op)"))
|
||||
(match_test "s390_mem_constraint (\"T\", op)"))
|
||||
|
||||
(define_memory_constraint "AQ"
|
||||
"@internal
|
||||
|
@ -512,12 +511,12 @@
|
|||
|
||||
|
||||
(define_address_constraint "U"
|
||||
"Pointer with short displacement. (deprecated - use ZQZR)"
|
||||
(match_test "s390_mem_constraint (\"U\", op)"))
|
||||
"Pointer with short displacement. (deprecated - use ZR)"
|
||||
(match_test "s390_mem_constraint (\"ZR\", op)"))
|
||||
|
||||
(define_address_constraint "W"
|
||||
"Pointer with long displacement. (deprecated - use ZSZT)"
|
||||
(match_test "s390_mem_constraint (\"W\", op)"))
|
||||
"Pointer with long displacement. (deprecated - use ZT)"
|
||||
(match_test "s390_mem_constraint (\"ZT\", op)"))
|
||||
|
||||
|
||||
(define_address_constraint "ZQ"
|
||||
|
|
|
@ -3116,6 +3116,19 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
|
|||
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)
|
||||
{
|
||||
case 'Q': /* no index short displacement */
|
||||
|
@ -3140,25 +3153,17 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
|
|||
break;
|
||||
|
||||
case 'S': /* no index long displacement */
|
||||
if (!TARGET_LONG_DISPLACEMENT)
|
||||
return 0;
|
||||
if (!decomposed && !s390_decompose_address (op, &addr))
|
||||
return 0;
|
||||
if (addr.indx)
|
||||
return 0;
|
||||
if (s390_short_displacement (addr.disp))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case 'T': /* with index long displacement */
|
||||
if (!TARGET_LONG_DISPLACEMENT)
|
||||
return 0;
|
||||
/* 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;
|
||||
}
|
||||
|
@ -3167,7 +3172,7 @@ s390_check_qrst_address (char c, rtx op, bool lit_pool_ok)
|
|||
|
||||
|
||||
/* 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. */
|
||||
|
||||
int
|
||||
|
@ -3197,12 +3202,6 @@ s390_mem_constraint (const char *str, rtx op)
|
|||
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. */
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -137,8 +137,8 @@
|
|||
|
||||
; Full HW vector size moves
|
||||
(define_insn "mov<mode>"
|
||||
[(set (match_operand:V_128 0 "nonimmediate_operand" "=v, v,QR, v, v, v, v, v,v,d")
|
||||
(match_operand:V_128 1 "general_operand" " v,QR, v,j00,jm1,jyy,jxx,jKK,d,v"))]
|
||||
[(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,R,v,j00,jm1,jyy,jxx,jKK,d,v"))]
|
||||
"TARGET_VX"
|
||||
"@
|
||||
vlr\t%v0,%v1
|
||||
|
@ -178,8 +178,8 @@
|
|||
; However, this would probably be slower.
|
||||
|
||||
(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")
|
||||
(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"))]
|
||||
[(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,R,v,j00,jm1,jyy,jxx,d,j00,j00,jm1,jm1,j00,jm1,R,T,b,d,d"))]
|
||||
""
|
||||
"@
|
||||
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")])
|
||||
|
||||
(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")
|
||||
(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"))]
|
||||
[(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,R,v,j00,jm1,jyy,jxx,d,j00,jm1,j00,jm1,R,T,b,d,d,d"))]
|
||||
""
|
||||
"@
|
||||
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")])
|
||||
|
||||
(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")
|
||||
(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"))]
|
||||
[(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,R,v,j00,j00,jm1,jyy,jxx,j00,jm1,j00,jm1,b,d,R,T,d,d,d"))]
|
||||
"TARGET_VX"
|
||||
"@
|
||||
lder\t%v0,%v1
|
||||
|
@ -268,9 +268,9 @@
|
|||
|
||||
(define_insn "mov<mode>"
|
||||
[(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"
|
||||
" 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"
|
||||
"@
|
||||
ldr\t%0,%1
|
||||
|
@ -322,10 +322,10 @@
|
|||
; up with vl vlvgg vst. Shouldn't the middle-end be able to handle
|
||||
; that itself?
|
||||
(define_insn "*vec_set<mode>"
|
||||
[(set (match_operand:V 0 "register_operand" "=v, v,v")
|
||||
(unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,QR,K")
|
||||
(match_operand:SI 2 "nonmemory_operand" "an, I,I")
|
||||
(match_operand:V 3 "register_operand" "0, 0,0")]
|
||||
[(set (match_operand:V 0 "register_operand" "=v,v,v")
|
||||
(unspec:V [(match_operand:<non_vec> 1 "general_operand" "d,R,K")
|
||||
(match_operand:SI 2 "nonmemory_operand" "an,I,I")
|
||||
(match_operand:V 3 "register_operand" "0,0,0")]
|
||||
UNSPEC_VEC_SET))]
|
||||
"TARGET_VX
|
||||
&& (!CONST_INT_P (operands[2])
|
||||
|
@ -359,9 +359,9 @@
|
|||
"TARGET_VX")
|
||||
|
||||
(define_insn "*vec_extract<mode>"
|
||||
[(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,QR")
|
||||
(unspec:<non_vec> [(match_operand:V 1 "register_operand" "v, v")
|
||||
(match_operand:SI 2 "nonmemory_operand" "an, I")]
|
||||
[(set (match_operand:<non_vec> 0 "nonimmediate_operand" "=d,R")
|
||||
(unspec:<non_vec> [(match_operand:V 1 "register_operand" "v,v")
|
||||
(match_operand:SI 2 "nonmemory_operand" "an,I")]
|
||||
UNSPEC_VEC_EXTRACT))]
|
||||
"TARGET_VX
|
||||
&& (!CONST_INT_P (operands[2])
|
||||
|
@ -404,7 +404,7 @@
|
|||
|
||||
(define_insn "*vec_splats<mode>"
|
||||
[(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"
|
||||
"@
|
||||
vlrep<bhfgq>\t%v0,%1
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
[(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")
|
||||
(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")]
|
||||
UNSPEC_VEC_GATHER))]
|
||||
"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>"
|
||||
[(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))]
|
||||
"TARGET_VX"
|
||||
"vllez<bhfgq>\t%v0,%1"
|
||||
|
@ -178,7 +178,7 @@
|
|||
|
||||
(define_insn "vlbb"
|
||||
[(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")]
|
||||
UNSPEC_VEC_LOAD_BNDRY))]
|
||||
"TARGET_VX && UINTVAL (operands[2]) < 7"
|
||||
|
|
Loading…
Add table
Reference in a new issue