diff options
Diffstat (limited to 'gcc/config/s390/s390.md')
-rw-r--r-- | gcc/config/s390/s390.md | 731 |
1 files changed, 558 insertions, 173 deletions
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 453191457d6..84e58d7838d 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -47,6 +47,13 @@ ;; has a value different from its other parts. If the letter x ;; is specified instead of a part number, the constraint matches ;; if there is any single part with non-default value. +;; O -- Multiple letter constraint followed by 1 parameter. +;; s: Signed extended immediate value (-2G .. 2G-1). +;; p: Positive extended immediate value (0 .. 4G-1). +;; n: Negative extended immediate value (-4G .. -1). +;; These constraints do not accept any operand if the machine does +;; not provide the extended-immediate facility. +;; P -- Any integer constant that can be loaded without literal pool. ;; Q -- Memory reference without index register and with short displacement. ;; R -- Memory reference with index register and short displacement. ;; S -- Memory reference without index register but with long displacement. @@ -122,7 +129,12 @@ (UNSPEC_TLS_LOAD 512) ; String Functions - (UNSPEC_SRST 600) + (UNSPEC_SRST 600) + (UNSPEC_MVST 601) + + ; Stack Smashing Protector + (UNSPEC_SP_SET 700) + (UNSPEC_SP_TEST 701) ]) ;; @@ -244,7 +256,7 @@ ;; distinguish between g5 and g6, but there are differences between the two ;; CPUs could in theory be modeled. -(define_attr "cpu" "g5,g6,z900,z990" +(define_attr "cpu" "g5,g6,z900,z990,z9_109" (const (symbol_ref "s390_tune"))) ;; Pipeline description for z900. For lack of anything better, @@ -433,13 +445,36 @@ "ltgfr\t%2,%0" [(set_attr "op_type" "RRE")]) +(define_insn "*tstdi_extimm" + [(set (reg CC_REGNUM) + (compare (match_operand:DI 0 "nonimmediate_operand" "d,m") + (match_operand:DI 1 "const0_operand" ""))) + (set (match_operand:DI 2 "register_operand" "=d,d") + (match_dup 0))] + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && TARGET_EXTIMM" + "@ + ltgr\t%2,%0 + ltg\t%2,%0" + [(set_attr "op_type" "RRE,RXY")]) + +(define_insn "*tstdi_cconly_extimm" + [(set (reg CC_REGNUM) + (compare (match_operand:DI 0 "nonimmediate_operand" "d,m") + (match_operand:DI 1 "const0_operand" ""))) + (clobber (match_scratch:DI 2 "=X,d"))] + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && TARGET_EXTIMM" + "@ + ltgr\t%0,%0 + ltg\t%2,%0" + [(set_attr "op_type" "RRE,RXY")]) + (define_insn "*tstdi" [(set (reg CC_REGNUM) (compare (match_operand:DI 0 "register_operand" "d") (match_operand:DI 1 "const0_operand" ""))) (set (match_operand:DI 2 "register_operand" "=d") (match_dup 0))] - "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" + "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT && !TARGET_EXTIMM" "ltgr\t%2,%0" [(set_attr "op_type" "RRE")]) @@ -460,6 +495,28 @@ [(set_attr "op_type" "RS") (set_attr "atype" "reg")]) +(define_insn "*tstsi_extimm" + [(set (reg CC_REGNUM) + (compare (match_operand:SI 0 "nonimmediate_operand" "d,m") + (match_operand:SI 1 "const0_operand" ""))) + (set (match_operand:SI 2 "register_operand" "=d,d") + (match_dup 0))] + "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" + "@ + ltr\t%2,%0 + lt\t%2,%0" + [(set_attr "op_type" "RR,RXY")]) + +(define_insn "*tstsi_cconly_extimm" + [(set (reg CC_REGNUM) + (compare (match_operand:SI 0 "nonimmediate_operand" "d,m") + (match_operand:SI 1 "const0_operand" ""))) + (clobber (match_scratch:SI 2 "=X,d"))] + "s390_match_ccmode(insn, CCSmode) && TARGET_EXTIMM" + "@ + ltr\t%0,%0 + lt\t%2,%0" + [(set_attr "op_type" "RR,RXY")]) (define_insn "*tstsi" [(set (reg CC_REGNUM) @@ -467,7 +524,7 @@ (match_operand:SI 1 "const0_operand" ""))) (set (match_operand:SI 2 "register_operand" "=d,d,d") (match_dup 0))] - "s390_match_ccmode(insn, CCSmode)" + "s390_match_ccmode(insn, CCSmode) && !TARGET_EXTIMM" "@ ltr\t%2,%0 icm\t%2,15,%S0 @@ -558,28 +615,30 @@ (define_insn "*cmpdi_cct" [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,Q") - (match_operand:DI 1 "general_operand" "d,K,m,BQ")))] + (compare (match_operand:DI 0 "nonimmediate_operand" "%d,d,d,d,Q") + (match_operand:DI 1 "general_operand" "d,K,Os,m,BQ")))] "s390_match_ccmode (insn, CCTmode) && TARGET_64BIT" "@ cgr\t%0,%1 cghi\t%0,%h1 + cgfi\t%0,%1 cg\t%0,%1 #" - [(set_attr "op_type" "RRE,RI,RXY,SS")]) + [(set_attr "op_type" "RRE,RI,RIL,RXY,SS")]) (define_insn "*cmpsi_cct" [(set (reg CC_REGNUM) - (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,Q") - (match_operand:SI 1 "general_operand" "d,K,R,T,BQ")))] + (compare (match_operand:SI 0 "nonimmediate_operand" "%d,d,d,d,d,Q") + (match_operand:SI 1 "general_operand" "d,K,Os,R,T,BQ")))] "s390_match_ccmode (insn, CCTmode)" "@ cr\t%0,%1 chi\t%0,%h1 + cfi\t%0,%1 c\t%0,%1 cy\t%0,%1 #" - [(set_attr "op_type" "RR,RI,RX,RXY,SS")]) + [(set_attr "op_type" "RR,RI,RIL,RX,RXY,SS")]) ; Compare (signed) instructions @@ -596,14 +655,15 @@ (define_insn "*cmpdi_ccs" [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "register_operand" "d,d,d") - (match_operand:DI 1 "general_operand" "d,K,m")))] + (compare (match_operand:DI 0 "register_operand" "d,d,d,d") + (match_operand:DI 1 "general_operand" "d,K,Os,m")))] "s390_match_ccmode(insn, CCSmode) && TARGET_64BIT" "@ cgr\t%0,%1 cghi\t%0,%h1 + cgfi\t%0,%1 cg\t%0,%1" - [(set_attr "op_type" "RRE,RI,RXY")]) + [(set_attr "op_type" "RRE,RI,RIL,RXY")]) (define_insn "*cmpsi_ccs_sign" [(set (reg CC_REGNUM) @@ -617,15 +677,16 @@ (define_insn "*cmpsi_ccs" [(set (reg CC_REGNUM) - (compare (match_operand:SI 0 "register_operand" "d,d,d,d") - (match_operand:SI 1 "general_operand" "d,K,R,T")))] + (compare (match_operand:SI 0 "register_operand" "d,d,d,d,d") + (match_operand:SI 1 "general_operand" "d,K,Os,R,T")))] "s390_match_ccmode(insn, CCSmode)" "@ cr\t%0,%1 chi\t%0,%h1 + cfi\t%0,%1 c\t%0,%1 cy\t%0,%1" - [(set_attr "op_type" "RR,RI,RX,RXY")]) + [(set_attr "op_type" "RR,RI,RIL,RX,RXY")]) ; Compare (unsigned) instructions @@ -642,28 +703,30 @@ (define_insn "*cmpdi_ccu" [(set (reg CC_REGNUM) - (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,Q,BQ") - (match_operand:DI 1 "general_operand" "d,m,BQ,Q")))] + (compare (match_operand:DI 0 "nonimmediate_operand" "d,d,d,Q,BQ") + (match_operand:DI 1 "general_operand" "d,Op,m,BQ,Q")))] "s390_match_ccmode (insn, CCUmode) && TARGET_64BIT" "@ clgr\t%0,%1 + clgfi\t%0,%1 clg\t%0,%1 # #" - [(set_attr "op_type" "RRE,RXY,SS,SS")]) + [(set_attr "op_type" "RRE,RIL,RXY,SS,SS")]) (define_insn "*cmpsi_ccu" [(set (reg CC_REGNUM) - (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,Q,BQ") - (match_operand:SI 1 "general_operand" "d,R,T,BQ,Q")))] + (compare (match_operand:SI 0 "nonimmediate_operand" "d,d,d,d,Q,BQ") + (match_operand:SI 1 "general_operand" "d,Os,R,T,BQ,Q")))] "s390_match_ccmode (insn, CCUmode)" "@ clr\t%0,%1 + clfi\t%0,%o1 cl\t%0,%1 cly\t%0,%1 # #" - [(set_attr "op_type" "RR,RX,RXY,SS,SS")]) + [(set_attr "op_type" "RR,RIL,RX,RXY,SS,SS")]) (define_insn "*cmphi_ccu" [(set (reg CC_REGNUM) @@ -781,7 +844,7 @@ (define_insn "movti" [(set (match_operand:TI 0 "nonimmediate_operand" "=d,QS,d,o,Q") - (match_operand:TI 1 "general_operand" "QS,d,dKm,d,Q"))] + (match_operand:TI 1 "general_operand" "QS,d,dPm,d,Q"))] "TARGET_64BIT" "@ lmg\t%0,%N0,%S1 @@ -868,12 +931,46 @@ [(set_attr "op_type" "RIL") (set_attr "type" "larl")]) +(define_insn "*movdi_64extimm" + [(set (match_operand:DI 0 "nonimmediate_operand" + "=d,d,d,d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") + (match_operand:DI 1 "general_operand" + "K,N0HD0,N1HD0,N2HD0,N3HD0,Os,N0SD0,N1SD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] + "TARGET_64BIT && TARGET_EXTIMM" + "@ + lghi\t%0,%h1 + llihh\t%0,%i1 + llihl\t%0,%i1 + llilh\t%0,%i1 + llill\t%0,%i1 + lgfi\t%0,%1 + llihf\t%0,%k1 + llilf\t%0,%k1 + lay\t%0,%a1 + lgr\t%0,%1 + lg\t%0,%1 + stg\t%1,%0 + ldr\t%0,%1 + ld\t%0,%1 + ldy\t%0,%1 + std\t%1,%0 + stdy\t%1,%0 + # + # + stam\t%1,%N1,%S0 + lam\t%0,%N0,%S1 + #" + [(set_attr "op_type" "RI,RI,RI,RI,RI,RIL,RIL,RIL,RXY,RRE,RXY,RXY, + RR,RX,RXY,RX,RXY,*,*,RS,RS,SS") + (set_attr "type" "*,*,*,*,*,*,*,*,la,lr,load,store, + floaddf,floaddf,floaddf,fstoredf,fstoredf,*,*,*,*,*")]) + (define_insn "*movdi_64" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,m,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") (match_operand:DI 1 "general_operand" "K,N0HD0,N1HD0,N2HD0,N3HD0,L,d,m,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] - "TARGET_64BIT" + "TARGET_64BIT && !TARGET_EXTIMM" "@ lghi\t%0,%h1 llihh\t%0,%i1 @@ -933,12 +1030,14 @@ s390_split_access_reg (operands[0], &operands[3], &operands[4]);") (define_insn "*movdi_31" - [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!*f,!R,!T,Q") - (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,R,T,*f,*f,Q"))] + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,Q,S,d,o,!*f,!*f,!*f,!R,!T,Q") + (match_operand:DI 1 "general_operand" "Q,S,d,d,dPm,d,*f,R,T,*f,*f,Q"))] "!TARGET_64BIT" "@ lm\t%0,%N0,%S1 + lmy\t%0,%N0,%S1 stm\t%1,%N1,%S0 + stmy\t%1,%N1,%S0 # # ldr\t%0,%1 @@ -947,8 +1046,8 @@ std\t%1,%0 stdy\t%1,%0 #" - [(set_attr "op_type" "RS,RS,*,*,RR,RX,RXY,RX,RXY,SS") - (set_attr "type" "lm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")]) + [(set_attr "op_type" "RS,RSY,RS,RSY,*,*,RR,RX,RXY,RX,RXY,SS") + (set_attr "type" "lm,lm,stm,stm,*,*,floaddf,floaddf,floaddf,fstoredf,fstoredf,*")]) (define_split [(set (match_operand:DI 0 "nonimmediate_operand" "") @@ -1085,14 +1184,15 @@ (define_insn "*movsi_zarch" [(set (match_operand:SI 0 "nonimmediate_operand" - "=d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") + "=d,d,d,d,d,d,d,d,R,T,!*f,!*f,!*f,!R,!T,d,t,Q,t,?Q") (match_operand:SI 1 "general_operand" - "K,N0HS0,N1HS0,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] + "K,N0HS0,N1HS0,Os,L,d,R,T,d,d,*f,R,T,*f,*f,t,d,t,Q,?Q"))] "TARGET_ZARCH" "@ lhi\t%0,%h1 llilh\t%0,%i1 llill\t%0,%i1 + iilf\t%0,%o1 lay\t%0,%a1 lr\t%0,%1 l\t%0,%1 @@ -1109,9 +1209,9 @@ stam\t%1,%1,%S0 lam\t%0,%0,%S1 #" - [(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY, + [(set_attr "op_type" "RI,RI,RI,RIL,RXY,RR,RX,RXY,RX,RXY, RR,RX,RXY,RX,RXY,RRE,RRE,RS,RS,SS") - (set_attr "type" "*,*,*,la,lr,load,load,store,store, + (set_attr "type" "*,*,*,*,la,lr,load,load,store,store, floadsf,floadsf,floadsf,fstoresf,fstoresf,*,*,*,*,*")]) (define_insn "*movsi_esa" @@ -1393,8 +1493,8 @@ (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,lr,load,store,*")]) (define_insn "*movdf_31" - [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,Q,d,o,Q") - (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,d,dKm,d,Q"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,f,f,R,T,d,d,Q,S,d,o,Q") + (match_operand:DF 1 "general_operand" "G,f,R,T,f,f,Q,S,d,d,dPm,d,Q"))] "!TARGET_64BIT" "@ lzdr\t%0 @@ -1404,12 +1504,15 @@ std\t%1,%0 stdy\t%1,%0 lm\t%0,%N0,%S1 + lmy\t%0,%N0,%S1 stm\t%1,%N1,%S0 + stmy\t%1,%N1,%S0 # # #" - [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RS,*,*,SS") - (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,lm,stm,*,*,*")]) + [(set_attr "op_type" "RRE,RR,RX,RXY,RX,RXY,RS,RSY,RS,RSY,*,*,SS") + (set_attr "type" "fsimpdf,floaddf,floaddf,floaddf,fstoredf,fstoredf,\ + lm,lm,stm,stm,*,*,*")]) (define_split [(set (match_operand:DF 0 "nonimmediate_operand" "") @@ -1842,6 +1945,48 @@ (set_attr "type" "vs")]) ; +; movstr instruction pattern. +; + +(define_expand "movstr" + [(set (reg:SI 0) (const_int 0)) + (parallel + [(clobber (match_dup 3)) + (set (match_operand:BLK 1 "memory_operand" "") + (match_operand:BLK 2 "memory_operand" "")) + (set (match_operand 0 "register_operand" "") + (unspec [(match_dup 1) + (match_dup 2) + (reg:SI 0)] UNSPEC_MVST)) + (clobber (reg:CC CC_REGNUM))])] + "" +{ + rtx addr1 = gen_reg_rtx (Pmode); + rtx addr2 = gen_reg_rtx (Pmode); + + emit_move_insn (addr1, force_operand (XEXP (operands[1], 0), NULL_RTX)); + emit_move_insn (addr2, force_operand (XEXP (operands[2], 0), NULL_RTX)); + operands[1] = replace_equiv_address_nv (operands[1], addr1); + operands[2] = replace_equiv_address_nv (operands[2], addr2); + operands[3] = addr2; +}) + +(define_insn "*movstr" + [(clobber (match_operand:P 2 "register_operand" "=d")) + (set (mem:BLK (match_operand:P 1 "register_operand" "0")) + (mem:BLK (match_operand:P 3 "register_operand" "2"))) + (set (match_operand:P 0 "register_operand" "=d") + (unspec [(mem:BLK (match_dup 1)) + (mem:BLK (match_dup 3)) + (reg:SI 0)] UNSPEC_MVST)) + (clobber (reg:CC CC_REGNUM))] + "" + "mvst\t%1,%2\;jo\t.-4" + [(set_attr "length" "8") + (set_attr "type" "vs")]) + + +; ; movmemM instruction pattern(s). ; @@ -2057,7 +2202,7 @@ [(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))])] @@ -2083,7 +2228,7 @@ (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))] @@ -2375,7 +2520,6 @@ [(set (match_operand:DI 0 "register_operand" "") (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] "" - " { if (!TARGET_64BIT) { @@ -2385,8 +2529,7 @@ emit_insn (gen_ashrdi3 (operands[0], operands[0], GEN_INT (32))); DONE; } -} -") +}) (define_insn "*extendsidi2" [(set (match_operand:DI 0 "register_operand" "=d,d") @@ -2403,9 +2546,8 @@ (define_expand "extend<mode>di2" [(set (match_operand:DI 0 "register_operand" "") - (sign_extend:DI (match_operand:HQI 1 "register_operand" "")))] + (sign_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))] "" - " { if (!TARGET_64BIT) { @@ -2414,7 +2556,7 @@ emit_insn (gen_extendsidi2 (operands[0], tmp)); DONE; } - else + else if (!TARGET_EXTIMM) { rtx bitcount = GEN_INT (GET_MODE_BITSIZE (DImode) - GET_MODE_BITSIZE (<MODE>mode)); @@ -2423,8 +2565,16 @@ emit_insn (gen_ashrdi3 (operands[0], operands[0], bitcount)); DONE; } -} -") +}) + +(define_insn "*extendhidi2_extimm" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "d,m")))] + "TARGET_64BIT && TARGET_EXTIMM" + "@ + lghr\t%0,%1 + lgh\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) (define_insn "*extendhidi2" [(set (match_operand:DI 0 "register_operand" "=d") @@ -2433,6 +2583,15 @@ "lgh\t%0,%1" [(set_attr "op_type" "RXY")]) +(define_insn "*extendqidi2_extimm" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] + "TARGET_64BIT && TARGET_EXTIMM" + "@ + lgbr\t%0,%1 + lgb\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) + (define_insn "*extendqidi2" [(set (match_operand:DI 0 "register_operand" "=d") (sign_extend:DI (match_operand:QI 1 "memory_operand" "m")))] @@ -2461,32 +2620,52 @@ (define_expand "extend<mode>si2" [(set (match_operand:SI 0 "register_operand" "") - (sign_extend:SI (match_operand:HQI 1 "register_operand" "")))] + (sign_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))] "" - " { - rtx bitcount = GEN_INT (GET_MODE_BITSIZE(SImode) - - GET_MODE_BITSIZE(<MODE>mode)); - operands[1] = gen_lowpart (SImode, operands[1]); - emit_insn (gen_ashlsi3 (operands[0], operands[1], bitcount)); - emit_insn (gen_ashrsi3 (operands[0], operands[0], bitcount)); - DONE; -} -") + if (!TARGET_EXTIMM) + { + rtx bitcount = GEN_INT (GET_MODE_BITSIZE(SImode) - + GET_MODE_BITSIZE(<MODE>mode)); + operands[1] = gen_lowpart (SImode, operands[1]); + emit_insn (gen_ashlsi3 (operands[0], operands[1], bitcount)); + emit_insn (gen_ashrsi3 (operands[0], operands[0], bitcount)); + DONE; + } +}) + +(define_insn "*extendhisi2_extimm" + [(set (match_operand:SI 0 "register_operand" "=d,d,d") + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "d,R,T")))] + "TARGET_EXTIMM" + "@ + lhr\t%0,%1 + lh\t%0,%1 + lhy\t%0,%1" + [(set_attr "op_type" "RRE,RX,RXY")]) (define_insn "*extendhisi2" [(set (match_operand:SI 0 "register_operand" "=d,d") (sign_extend:SI (match_operand:HI 1 "memory_operand" "R,T")))] - "" + "!TARGET_EXTIMM" "@ lh\t%0,%1 lhy\t%0,%1" [(set_attr "op_type" "RX,RXY")]) +(define_insn "*extendqisi2_extimm" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "d,m")))] + "TARGET_EXTIMM" + "@ + lbr\t%0,%1 + lb\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) + (define_insn "*extendqisi2" [(set (match_operand:SI 0 "register_operand" "=d") (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] - "TARGET_LONG_DISPLACEMENT" + "TARGET_LONG_DISPLACEMENT && !TARGET_EXTIMM" "lb\t%0,%1" [(set_attr "op_type" "RXY")]) @@ -2518,7 +2697,6 @@ [(set (match_operand:DI 0 "register_operand" "") (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))] "" - " { if (!TARGET_64BIT) { @@ -2527,8 +2705,7 @@ emit_move_insn (gen_highpart (SImode, operands[0]), const0_rtx); DONE; } -} -") +}) (define_insn "*zero_extendsidi2" [(set (match_operand:DI 0 "register_operand" "=d,d") @@ -2545,9 +2722,8 @@ (define_expand "zero_extend<mode>di2" [(set (match_operand:DI 0 "register_operand" "") - (zero_extend:DI (match_operand:HQI 1 "register_operand" "")))] + (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "")))] "" - " { if (!TARGET_64BIT) { @@ -2556,7 +2732,7 @@ emit_insn (gen_zero_extendsidi2 (operands[0], tmp)); DONE; } - else + else if (!TARGET_EXTIMM) { rtx bitcount = GEN_INT (GET_MODE_BITSIZE(DImode) - GET_MODE_BITSIZE(<MODE>mode)); @@ -2565,13 +2741,21 @@ emit_insn (gen_lshrdi3 (operands[0], operands[0], bitcount)); DONE; } -} -") +}) + +(define_insn "*zero_extend<mode>di2_extimm" + [(set (match_operand:DI 0 "register_operand" "=d,d") + (zero_extend:DI (match_operand:HQI 1 "nonimmediate_operand" "d,m")))] + "TARGET_64BIT && TARGET_EXTIMM" + "@ + llg<hc>r\t%0,%1 + llg<hc>\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) (define_insn "*zero_extend<mode>di2" [(set (match_operand:DI 0 "register_operand" "=d") (zero_extend:DI (match_operand:HQI 1 "memory_operand" "m")))] - "TARGET_64BIT" + "TARGET_64BIT && !TARGET_EXTIMM" "llg<hc>\t%0,%1" [(set_attr "op_type" "RXY")]) @@ -2604,7 +2788,7 @@ [(set (match_operand:SI 0 "register_operand" "=d,d") (and:SI (match_operand:SI 1 "nonimmediate_operand" "d,m") (const_int 2147483647)))] - "TARGET_64BIT" + "TARGET_ZARCH" "@ llgtr\t%0,%1 llgt\t%0,%1" @@ -2625,7 +2809,7 @@ (and:GPR (match_operand:GPR 1 "nonimmediate_operand" "") (const_int 2147483647))) (clobber (reg:CC CC_REGNUM))] - "TARGET_64BIT && reload_completed" + "TARGET_ZARCH && reload_completed" [(set (match_dup 0) (and:GPR (match_dup 1) (const_int 2147483647)))] @@ -2637,21 +2821,31 @@ (define_expand "zero_extend<mode>si2" [(set (match_operand:SI 0 "register_operand" "") - (zero_extend:SI (match_operand:HQI 1 "register_operand" "")))] + (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "")))] "" - " { - operands[1] = gen_lowpart (SImode, operands[1]); - emit_insn (gen_andsi3 (operands[0], operands[1], - GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1))); - DONE; + if (!TARGET_EXTIMM) + { + operands[1] = gen_lowpart (SImode, operands[1]); + emit_insn (gen_andsi3 (operands[0], operands[1], + GEN_INT ((1 << GET_MODE_BITSIZE(<MODE>mode)) - 1))); + DONE; } -") +}) + +(define_insn "*zero_extend<mode>si2_extimm" + [(set (match_operand:SI 0 "register_operand" "=d,d") + (zero_extend:SI (match_operand:HQI 1 "nonimmediate_operand" "d,m")))] + "TARGET_EXTIMM" + "@ + ll<hc>r\t%0,%1 + ll<hc>\t%0,%1" + [(set_attr "op_type" "RRE,RXY")]) (define_insn "*zero_extend<mode>si2_64" [(set (match_operand:SI 0 "register_operand" "=d") (zero_extend:SI (match_operand:HQI 1 "memory_operand" "m")))] - "TARGET_ZARCH" + "TARGET_ZARCH && !TARGET_EXTIMM" "llg<hc>\t%0,%1" [(set_attr "op_type" "RXY")]) @@ -2685,19 +2879,17 @@ (define_expand "zero_extendqihi2" [(set (match_operand:HI 0 "register_operand" "") (zero_extend:HI (match_operand:QI 1 "register_operand" "")))] - "TARGET_ZARCH" - " + "TARGET_ZARCH && !TARGET_EXTIMM" { operands[1] = gen_lowpart (HImode, operands[1]); emit_insn (gen_andhi3 (operands[0], operands[1], GEN_INT (0xff))); DONE; -} -") +}) (define_insn "*zero_extendqihi2_64" [(set (match_operand:HI 0 "register_operand" "=d") (zero_extend:HI (match_operand:QI 1 "memory_operand" "m")))] - "TARGET_ZARCH" + "TARGET_ZARCH && !TARGET_EXTIMM" "llgc\t%0,%1" [(set_attr "op_type" "RXY")]) @@ -3080,29 +3272,34 @@ (define_insn "*adddi3_imm_cc" [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:DI 2 "const_int_operand" "K")) + (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") + (match_operand:DI 2 "const_int_operand" "K,Os")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d") + (set (match_operand:DI 0 "register_operand" "=d,d") (plus:DI (match_dup 1) (match_dup 2)))] "TARGET_64BIT && s390_match_ccmode (insn, CCAmode) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")" - "aghi\t%0,%h2" - [(set_attr "op_type" "RI")]) + && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\") + || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\"))" + "@ + aghi\t%0,%h2 + agfi\t%0,%2" + [(set_attr "op_type" "RI,RIL")]) (define_insn "*adddi3_carry1_cc" [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) + (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:DI 2 "general_operand" "d,Op,On,m")) (match_dup 1))) - (set (match_operand:DI 0 "register_operand" "=d,d") + (set (match_operand:DI 0 "register_operand" "=d,d,d,d") (plus:DI (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT" "@ algr\t%0,%2 + algfi\t%0,%2 + slgfi\t%0,%n2 alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) + [(set_attr "op_type" "RRE,RIL,RIL,RXY")]) (define_insn "*adddi3_carry1_cconly" [(set (reg CC_REGNUM) @@ -3118,16 +3315,18 @@ (define_insn "*adddi3_carry2_cc" [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) + (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:DI 2 "general_operand" "d,Op,On,m")) (match_dup 2))) - (set (match_operand:DI 0 "register_operand" "=d,d") + (set (match_operand:DI 0 "register_operand" "=d,d,d,d") (plus:DI (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode) && TARGET_64BIT" "@ algr\t%0,%2 + algfi\t%0,%2 + slgfi\t%0,%n2 alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) + [(set_attr "op_type" "RRE,RIL,RIL,RXY")]) (define_insn "*adddi3_carry2_cconly" [(set (reg CC_REGNUM) @@ -3143,16 +3342,18 @@ (define_insn "*adddi3_cc" [(set (reg CC_REGNUM) - (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0") - (match_operand:DI 2 "general_operand" "d,m")) + (compare (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:DI 2 "general_operand" "d,Op,On,m")) (const_int 0))) - (set (match_operand:DI 0 "register_operand" "=d,d") + (set (match_operand:DI 0 "register_operand" "=d,d,d,d") (plus:DI (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCLmode) && TARGET_64BIT" "@ algr\t%0,%2 + algfi\t%0,%2 + slgfi\t%0,%n2 alg\t%0,%2" - [(set_attr "op_type" "RRE,RXY")]) + [(set_attr "op_type" "RRE,RIL,RIL,RXY")]) (define_insn "*adddi3_cconly" [(set (reg CC_REGNUM) @@ -3178,16 +3379,18 @@ [(set_attr "op_type" "RRE,RXY")]) (define_insn "*adddi3_64" - [(set (match_operand:DI 0 "register_operand" "=d,d,d") - (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:DI 2 "general_operand" "d,K,m") ) ) + [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d") + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:DI 2 "general_operand" "d,K,Op,On,m") ) ) (clobber (reg:CC CC_REGNUM))] "TARGET_64BIT" "@ agr\t%0,%2 aghi\t%0,%h2 + algfi\t%0,%2 + slgfi\t%0,%n2 ag\t%0,%2" - [(set_attr "op_type" "RRE,RI,RXY")]) + [(set_attr "op_type" "RRE,RI,RIL,RIL,RXY")]) (define_insn_and_split "*adddi3_31z" [(set (match_operand:DI 0 "register_operand" "=&d") @@ -3260,29 +3463,34 @@ (define_insn "*addsi3_imm_cc" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0") - (match_operand:SI 2 "const_int_operand" "K")) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") + (match_operand:SI 2 "const_int_operand" "K,Os")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d") + (set (match_operand:SI 0 "register_operand" "=d,d") (plus:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCAmode) - && CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\")" - "ahi\t%0,%h2" - [(set_attr "op_type" "RI")]) + && (CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'K', \"K\") + || CONST_OK_FOR_CONSTRAINT_P (INTVAL (operands[2]), 'O', \"Os\")) + && INTVAL (operands[2]) != -((HOST_WIDE_INT)1 << 31)" + "@ + ahi\t%0,%h2 + afi\t%0,%2" + [(set_attr "op_type" "RI,RIL")]) (define_insn "*addsi3_carry1_cc" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "d,Os,R,T")) (match_dup 1))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (plus:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode)" "@ alr\t%0,%2 + alfi\t%0,%o2 al\t%0,%2 aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RR,RIL,RX,RXY")]) (define_insn "*addsi3_carry1_cconly" [(set (reg CC_REGNUM) @@ -3299,17 +3507,18 @@ (define_insn "*addsi3_carry2_cc" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "d,Os,R,T")) (match_dup 2))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (plus:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCL1mode)" "@ alr\t%0,%2 + alfi\t%0,%o2 al\t%0,%2 aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RR,RIL,RX,RXY")]) (define_insn "*addsi3_carry2_cconly" [(set (reg CC_REGNUM) @@ -3326,17 +3535,18 @@ (define_insn "*addsi3_cc" [(set (reg CC_REGNUM) - (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "d,Os,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (plus:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode (insn, CCLmode)" "@ alr\t%0,%2 + alfi\t%0,%o2 al\t%0,%2 aly\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RR,RIL,RX,RXY")]) (define_insn "*addsi3_cconly" [(set (reg CC_REGNUM) @@ -3375,17 +3585,18 @@ [(set_attr "op_type" "RX,RXY")]) (define_insn "addsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,d,d") - (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:SI 2 "general_operand" "d,K,R,T"))) + [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d") + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:SI 2 "general_operand" "d,K,Os,R,T"))) (clobber (reg:CC CC_REGNUM))] "" "@ ar\t%0,%2 ahi\t%0,%h2 + afi\t%0,%2 a\t%0,%2 ay\t%0,%2" - [(set_attr "op_type" "RR,RI,RX,RXY")]) + [(set_attr "op_type" "RR,RI,RIL,RX,RXY")]) ; ; add(df|sf)3 instruction pattern(s). @@ -4663,6 +4874,29 @@ ng\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) +(define_insn "*anddi3_extimm" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,d,d,AQ,Q") + (and:DI (match_operand:DI 1 "nonimmediate_operand" + "%d,o,0,0,0,0,0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" + "M,M,N0HDF,N1HDF,N2HDF,N3HDF,N0SDF,N1SDF,d,m,NxQDF,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" + "@ + # + # + nihh\t%0,%j2 + nihl\t%0,%j2 + nilh\t%0,%j2 + nill\t%0,%j2 + nihf\t%0,%m2 + nilf\t%0,%m2 + ngr\t%0,%2 + ng\t%0,%2 + # + #" + [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")]) + (define_insn "*anddi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") (and:DI (match_operand:DI 1 "nonimmediate_operand" @@ -4670,7 +4904,7 @@ (match_operand:DI 2 "general_operand" "M,M,N0HDF,N1HDF,N2HDF,N3HDF,d,m,NxQDF,Q"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_64BIT && s390_logical_operator_ok_p (operands)" + "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" "@ # # @@ -4701,39 +4935,41 @@ (define_insn "*andsi3_cc" [(set (reg CC_REGNUM) - (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (and:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode)" "@ + nilf\t%0,%o2 nr\t%0,%2 n\t%0,%2 ny\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*andsi3_cconly" [(set (reg CC_REGNUM) - (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "s390_match_ccmode(insn, CCTmode) /* Do not steal TM patterns. */ && s390_single_part (operands[2], SImode, HImode, 0) < 0" "@ + nilf\t%0,%o2 nr\t%0,%2 n\t%0,%2 ny\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*andsi3_zarch" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,AQ,Q") + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") (and:SI (match_operand:SI 1 "nonimmediate_operand" - "%d,o,0,0,0,0,0,0,0") + "%d,o,0,0,0,0,0,0,0,0") (match_operand:SI 2 "general_operand" - "M,M,N0HSF,N1HSF,d,R,T,NxQSF,Q"))) + "M,M,N0HSF,N1HSF,Os,d,R,T,NxQSF,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ @@ -4741,12 +4977,13 @@ # nilh\t%0,%j2 nill\t%0,%j2 + nilf\t%0,%o2 nr\t%0,%2 n\t%0,%2 ny\t%0,%2 # #" - [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY,SI,SS")]) + [(set_attr "op_type" "RRE,RXE,RI,RI,RIL,RR,RX,RXY,SI,SS")]) (define_insn "*andsi3_esa" [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q") @@ -4938,13 +5175,33 @@ og\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) +(define_insn "*iordi3_extimm" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,d,d,AQ,Q") + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" + "N0HD0,N1HD0,N2HD0,N3HD0,N0SD0,N1SD0,d,m,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" + "@ + oihh\t%0,%i2 + oihl\t%0,%i2 + oilh\t%0,%i2 + oill\t%0,%i2 + oihf\t%0,%k2 + oilf\t%0,%k2 + ogr\t%0,%2 + og\t%0,%2 + # + #" + [(set_attr "op_type" "RI,RI,RI,RI,RIL,RIL,RRE,RXY,SI,SS")]) + (define_insn "*iordi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q") (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0") (match_operand:DI 2 "general_operand" "N0HD0,N1HD0,N2HD0,N3HD0,d,m,NxQD0,Q"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_64BIT && s390_logical_operator_ok_p (operands)" + "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" "@ oihh\t%0,%i2 oihl\t%0,%i2 @@ -4972,46 +5229,49 @@ (define_insn "*iorsi3_cc" [(set (reg CC_REGNUM) - (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (ior:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode)" "@ + oilf\t%0,%o2 or\t%0,%2 o\t%0,%2 oy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*iorsi3_cconly" [(set (reg CC_REGNUM) - (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "s390_match_ccmode(insn, CCTmode)" "@ + oilf\t%0,%o2 or\t%0,%2 o\t%0,%2 oy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*iorsi3_zarch" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,AQ,Q") - (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0") - (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,d,R,T,NxQS0,Q"))) + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,d,d,AQ,Q") + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0,0,0") + (match_operand:SI 2 "general_operand" "N0HS0,N1HS0,Os,d,R,T,NxQS0,Q"))) (clobber (reg:CC CC_REGNUM))] "TARGET_ZARCH && s390_logical_operator_ok_p (operands)" "@ oilh\t%0,%i2 oill\t%0,%i2 + oilf\t%0,%o2 or\t%0,%2 o\t%0,%2 oy\t%0,%2 # #" - [(set_attr "op_type" "RI,RI,RR,RX,RXY,SI,SS")]) + [(set_attr "op_type" "RI,RI,RIL,RR,RX,RXY,SI,SS")]) (define_insn "*iorsi3_esa" [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,AQ,Q") @@ -5203,12 +5463,27 @@ xr\t%0,%2" [(set_attr "op_type" "RRE,RXY")]) +(define_insn "*xordi3_extimm" + [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q") + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0,0,0") + (match_operand:DI 2 "general_operand" "N0SD0,N1SD0,d,m,NxQD0,Q"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_64BIT && TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" + "@ + xihf\t%0,%k2 + xilf\t%0,%k2 + xgr\t%0,%2 + xg\t%0,%2 + # + #" + [(set_attr "op_type" "RIL,RIL,RRE,RXY,SI,SS")]) + (define_insn "*xordi3" [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,AQ,Q") (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") (match_operand:DI 2 "general_operand" "d,m,NxQD0,Q"))) (clobber (reg:CC CC_REGNUM))] - "TARGET_64BIT && s390_logical_operator_ok_p (operands)" + "TARGET_64BIT && !TARGET_EXTIMM && s390_logical_operator_ok_p (operands)" "@ xgr\t%0,%2 xg\t%0,%2 @@ -5232,44 +5507,47 @@ (define_insn "*xorsi3_cc" [(set (reg CC_REGNUM) - (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (set (match_operand:SI 0 "register_operand" "=d,d,d") + (set (match_operand:SI 0 "register_operand" "=d,d,d,d") (xor:SI (match_dup 1) (match_dup 2)))] "s390_match_ccmode(insn, CCTmode)" "@ + xilf\t%0,%o2 xr\t%0,%2 x\t%0,%2 xy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*xorsi3_cconly" [(set (reg CC_REGNUM) - (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T")) + (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T")) (const_int 0))) - (clobber (match_scratch:SI 0 "=d,d,d"))] + (clobber (match_scratch:SI 0 "=d,d,d,d"))] "s390_match_ccmode(insn, CCTmode)" "@ + xilf\t%0,%o2 xr\t%0,%2 x\t%0,%2 xy\t%0,%2" - [(set_attr "op_type" "RR,RX,RXY")]) + [(set_attr "op_type" "RIL,RR,RX,RXY")]) (define_insn "*xorsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,AQ,Q") - (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0") - (match_operand:SI 2 "general_operand" "d,R,T,NxQS0,Q"))) + [(set (match_operand:SI 0 "nonimmediate_operand" "=d,d,d,d,AQ,Q") + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0,0") + (match_operand:SI 2 "general_operand" "Os,d,R,T,NxQS0,Q"))) (clobber (reg:CC CC_REGNUM))] "s390_logical_operator_ok_p (operands)" "@ + xilf\t%0,%o2 xr\t%0,%2 x\t%0,%2 xy\t%0,%2 # #" - [(set_attr "op_type" "RR,RX,RXY,SI,SS")]) + [(set_attr "op_type" "RIL,RR,RX,RXY,SI,SS")]) (define_split [(set (match_operand:SI 0 "s_operand" "") @@ -5286,16 +5564,17 @@ ; (define_insn "*xorhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "=d,AQ,Q") - (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0") - (match_operand:HI 2 "general_operand" "d,NxQH0,Q"))) + [(set (match_operand:HI 0 "nonimmediate_operand" "=d,d,AQ,Q") + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,0,0") + (match_operand:HI 2 "general_operand" "Os,d,NxQH0,Q"))) (clobber (reg:CC CC_REGNUM))] "s390_logical_operator_ok_p (operands)" "@ + xilf\t%0,%x2 xr\t%0,%2 # #" - [(set_attr "op_type" "RR,SI,SS")]) + [(set_attr "op_type" "RIL,RR,SI,SS")]) (define_split [(set (match_operand:HI 0 "s_operand" "") @@ -5312,17 +5591,18 @@ ; (define_insn "*xorqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "=d,Q,S,Q") - (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:QI 2 "general_operand" "d,n,n,Q"))) + [(set (match_operand:QI 0 "nonimmediate_operand" "=d,d,Q,S,Q") + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,0,0") + (match_operand:QI 2 "general_operand" "Os,d,n,n,Q"))) (clobber (reg:CC CC_REGNUM))] "s390_logical_operator_ok_p (operands)" "@ + xilf\t%0,%b2 xr\t%0,%2 xi\t%S0,%b2 xiy\t%S0,%b2 #" - [(set_attr "op_type" "RR,SI,SIY,SS")]) + [(set_attr "op_type" "RIL,RR,SI,SIY,SS")]) ; ; Block exclusive or (XC) patterns. @@ -5791,6 +6071,49 @@ ;; +;; Find leftmost bit instructions. +;; + +(define_expand "clzdi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (clz:DI (match_operand:DI 1 "register_operand" "d")))] + "TARGET_EXTIMM && TARGET_64BIT" +{ + rtx insn, clz_equal; + rtx wide_reg = gen_reg_rtx (TImode); + rtx msb = gen_rtx_CONST_INT (DImode, (unsigned HOST_WIDE_INT) 1 << 63); + + clz_equal = gen_rtx_CLZ (DImode, operands[1]); + + emit_insn (gen_clztidi2 (wide_reg, operands[1], msb)); + + insn = emit_move_insn (operands[0], gen_highpart (DImode, wide_reg)); + REG_NOTES (insn) = + gen_rtx_EXPR_LIST (REG_EQUAL, clz_equal, REG_NOTES (insn)); + + DONE; +}) + +(define_insn "clztidi2" + [(set (match_operand:TI 0 "register_operand" "=d") + (ior:TI + (ashift:TI + (zero_extend:TI + (xor:DI (match_operand:DI 1 "register_operand" "d") + (lshiftrt (match_operand:DI 2 "const_int_operand" "") + (subreg:SI (clz:DI (match_dup 1)) 4)))) + + (const_int 64)) + (zero_extend:TI (clz:DI (match_dup 1))))) + (clobber (reg:CC CC_REGNUM))] + "(unsigned HOST_WIDE_INT) INTVAL (operands[2]) + == (unsigned HOST_WIDE_INT) 1 << 63 + && TARGET_EXTIMM && TARGET_64BIT" + "flogr\t%0,%1" + [(set_attr "op_type" "RRE")]) + + +;; ;;- Rotate instructions. ;; @@ -7140,3 +7463,65 @@ DONE; }) +; +; Stack Protector Patterns +; + +(define_expand "stack_protect_set" + [(set (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" ""))] + "" +{ +#ifdef TARGET_THREAD_SSP_OFFSET + operands[1] + = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), + GEN_INT (TARGET_THREAD_SSP_OFFSET))); +#endif + if (TARGET_64BIT) + emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); + else + emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); + + DONE; +}) + +(define_insn "stack_protect_set<mode>" + [(set (match_operand:DSI 0 "memory_operand" "=Q") + (unspec:DSI [(match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_SET))] + "" + "mvc\t%O0(%G0,%R0),%S1" + [(set_attr "op_type" "SS")]) + +(define_expand "stack_protect_test" + [(set (reg:CC CC_REGNUM) + (compare (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" ""))) + (match_operand 2 "" "")] + "" +{ +#ifdef TARGET_THREAD_SSP_OFFSET + operands[1] + = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, s390_get_thread_pointer (), + GEN_INT (TARGET_THREAD_SSP_OFFSET))); +#endif + s390_compare_op0 = operands[0]; + s390_compare_op1 = operands[1]; + s390_compare_emitted = gen_rtx_REG (CCZmode, CC_REGNUM); + + if (TARGET_64BIT) + emit_insn (gen_stack_protect_testdi (operands[0], operands[1])); + else + emit_insn (gen_stack_protect_testsi (operands[0], operands[1])); + + emit_jump_insn (gen_beq (operands[2])); + + DONE; +}) + +(define_insn "stack_protect_test<mode>" + [(set (reg:CCZ CC_REGNUM) + (unspec:CCZ [(match_operand:DSI 0 "memory_operand" "Q") + (match_operand:DSI 1 "memory_operand" "Q")] UNSPEC_SP_TEST))] + "" + "clc\t%O0(%G0,%R0),%S1" + [(set_attr "op_type" "SS")]) |