From 19b63d8ecd5c81353990274b249fced229e89e24 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Mon, 11 Oct 2004 14:33:25 +0000 Subject: [PATCH] s390-protos.h (s390_offset_p): Add prototype. * config/s390/s390-protos.h (s390_offset_p): Add prototype. * config/s390/s390.c (s390_offset_p): New function. * config/s390/s390.md ("*cmpdi_cct", "*cmpsi_cct", "*cmpdi_ccu", "*cmpsi_ccu", "*cmphi_ccu", "*cmpqi_ccu"): Use splitter to transform Q->Q alternatives to *clc pattern. ("*clc"): Move. ("movti", "*movdi_64", "*movdi_31", "*movsi_zarch", "*movsi_esa", "*movhi", "*movqi", "*movdf_64", "*movdf_31", "movsf"): Use splitter to transform Q->Q alternatives to *mvc pattern. ("*mvc"): Move. Add peephole to merge adjacent MVCs. ("*anddi3", "*andsi3_zarch", "*andsi3_esa", "*andhi3_zarch", "*andhi3_esa", "*andqi3_zarch", "*andqi3_esa"): Use splitter to transform Q->Q alternatives to *nc pattern. ("*nc"): New insn. New peephole to merge adjacent NCs. ("*iordi3", "*iorsi3_zarch", "*iorsi3_esa", "*iorhi3_zarch", "*iorhi3_esa", "*iorqi3_zarch", "*iorqi3_esa"): Use splitter to transform Q->Q alternatives to *oc pattern. ("*oc"): New insn. New peephole to merge adjacent OCs. ("*xordi3", "*xorsi3", "*xorhi3", "*xorqi3"): Use splitter to transform Q->Q alternatives to *xc pattern. ("*xc"): New insn. New peephole to merge adjacent XCs. ("*xc_zero"): Move. Add peephole to merge adjacent XCs. From-SVN: r88878 --- gcc/ChangeLog | 25 +++ gcc/config/s390/s390-protos.h | 1 + gcc/config/s390/s390.c | 22 +++ gcc/config/s390/s390.md | 385 +++++++++++++++++++++++++++++++++++------- 4 files changed, 370 insertions(+), 63 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5b3d9d1..4df3fea 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2004-10-11 Ulrich Weigand + + * config/s390/s390-protos.h (s390_offset_p): Add prototype. + * config/s390/s390.c (s390_offset_p): New function. + * config/s390/s390.md ("*cmpdi_cct", "*cmpsi_cct", "*cmpdi_ccu", + "*cmpsi_ccu", "*cmphi_ccu", "*cmpqi_ccu"): Use splitter to + transform Q->Q alternatives to *clc pattern. + ("*clc"): Move. + ("movti", "*movdi_64", "*movdi_31", "*movsi_zarch", "*movsi_esa", + "*movhi", "*movqi", "*movdf_64", "*movdf_31", "movsf"): Use splitter + to transform Q->Q alternatives to *mvc pattern. + ("*mvc"): Move. Add peephole to merge adjacent MVCs. + ("*anddi3", "*andsi3_zarch", "*andsi3_esa", "*andhi3_zarch", + "*andhi3_esa", "*andqi3_zarch", "*andqi3_esa"): Use splitter to + transform Q->Q alternatives to *nc pattern. + ("*nc"): New insn. New peephole to merge adjacent NCs. + ("*iordi3", "*iorsi3_zarch", "*iorsi3_esa", "*iorhi3_zarch", + "*iorhi3_esa", "*iorqi3_zarch", "*iorqi3_esa"): Use splitter to + transform Q->Q alternatives to *oc pattern. + ("*oc"): New insn. New peephole to merge adjacent OCs. + ("*xordi3", "*xorsi3", "*xorhi3", "*xorqi3"): Use splitter to + transform Q->Q alternatives to *xc pattern. + ("*xc"): New insn. New peephole to merge adjacent XCs. + ("*xc_zero"): Move. Add peephole to merge adjacent XCs. + 2004-10-11 Andrew Pinski * gimplify.c (gimple_push_condition): Make sure that we don't diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 4e88c1d..4b405f2 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -44,6 +44,7 @@ extern int store_multiple_operation (rtx, enum machine_mode); extern int s390_single_part (rtx, enum machine_mode, enum machine_mode, int); extern unsigned HOST_WIDE_INT s390_extract_part (rtx, enum machine_mode, int); extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int); +extern bool s390_offset_p (rtx, rtx, rtx); extern int tls_symbolic_operand (rtx); extern int s390_match_ccmode (rtx, enum machine_mode); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 1d4d813..2a65365 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1096,6 +1096,28 @@ s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword) return true; } +/* Check whether the address of memory reference MEM2 equals exactly + the address of memory reference MEM1 plus DELTA. Return true if + we can prove this to be the case, false otherwise. */ + +bool +s390_offset_p (rtx mem1, rtx mem2, rtx delta) +{ + rtx addr1, addr2, addr_delta; + + if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM) + return false; + + addr1 = XEXP (mem1, 0); + addr2 = XEXP (mem2, 0); + + addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1); + if (!addr_delta || !rtx_equal_p (addr_delta, delta)) + return false; + + return true; +} + /* Expand logical operator CODE in mode MODE with operands OPERANDS. */ void diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 7d59f0c..8d43779 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -534,7 +534,7 @@ cghi\t%0,%c1 cg\t%0,%1 cg\t%1,%0 - clc\t%O0(8,%R0),%1" + #" [(set_attr "op_type" "RRE,RI,RXY,RXY,SS")]) (define_insn "*cmpsi_cct" @@ -550,7 +550,7 @@ cy\t%0,%1 c\t%1,%0 cy\t%1,%0 - clc\t%O0(4,%R0),%1" + #" [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS")]) @@ -621,7 +621,7 @@ "@ clgr\t%0,%1 clg\t%0,%1 - clc\t%O0(8,%R0),%1" + #" [(set_attr "op_type" "RRE,RXY,SS")]) (define_insn "*cmpsi_ccu" @@ -634,7 +634,7 @@ clr\t%0,%1 cl\t%0,%1 cly\t%0,%1 - clc\t%O0(4,%R0),%1" + #" [(set_attr "op_type" "RR,RX,RXY,SS")]) (define_insn "*cmphi_ccu" @@ -647,7 +647,7 @@ "@ clm\t%0,3,%1 clmy\t%0,3,%1 - clc\t%O0(2,%R0),%1" + #" [(set_attr "op_type" "RS,RSY,SS")]) (define_insn "*cmpqi_ccu" @@ -662,10 +662,45 @@ clmy\t%0,1,%1 cli\t%0,%b1 cliy\t%0,%b1 - clc\t%O0(1,%R0),%1" + #" [(set_attr "op_type" "RS,RSY,SI,SIY,SS")]) +; Block compare (CLC) instruction patterns. + +(define_insn "*clc" + [(set (reg 33) + (compare (match_operand:BLK 0 "memory_operand" "=Q") + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n"))] + "s390_match_ccmode (insn, CCUmode) + && INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "clc\t%O0(%2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) + +(define_split + [(set (reg 33) + (compare (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" "")))] + "reload_completed + && s390_match_ccmode (insn, CCUmode) + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 2))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); + + operands[1] = gen_rtx_COMPARE (GET_MODE (SET_DEST (PATTERN (curr_insn))), + operands[0], operands[1]); + operands[0] = SET_DEST (PATTERN (curr_insn)); +}) + + ; DF instructions (define_insn "*cmpdf_ccs_0" @@ -769,7 +804,7 @@ stmg\t%1,%N1,%0 # # - mvc\t%O0(16,%R0),%1" + #" [(set_attr "op_type" "RSY,RSY,NN,NN,SS") (set_attr "type" "lm,stm,*,*,cs")]) @@ -869,7 +904,7 @@ ldy\t%0,%1 std\t%1,%0 stdy\t%1,%0 - mvc\t%O0(8,%R0),%1" + #" [(set_attr "op_type" "RI,RI,RI,RI,RI,RXY,RRE,RXY,RXY,RR,RX,RXY,RX,RXY,SS") (set_attr "type" "*,*,*,*,*,la,lr,load,store,floadd,floadd,floadd, fstored,fstored,cs")]) @@ -888,7 +923,7 @@ ldy\t%0,%1 std\t%1,%0 stdy\t%1,%0 - mvc\t%O0(8,%R0),%1" + #" [(set_attr "op_type" "RS,RS,NN,NN,RR,RX,RXY,RX,RXY,SS") (set_attr "type" "lm,stm,*,*,floadd,floadd,floadd,fstored,fstored,cs")]) @@ -1045,7 +1080,7 @@ ley\t%0,%1 ste\t%1,%0 stey\t%1,%0 - mvc\t%O0(4,%R0),%1" + #" [(set_attr "op_type" "RI,RI,RI,RXY,RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") (set_attr "type" "*,*,*,la,lr,load,load,store,store,floads,floads,floads,fstores,fstores,cs")]) @@ -1061,7 +1096,7 @@ ler\t%0,%1 le\t%0,%1 ste\t%1,%0 - mvc\t%O0(4,%R0),%1" + #" [(set_attr "op_type" "RI,RR,RX,RX,RR,RX,RX,SS") (set_attr "type" "*,lr,load,store,floads,floads,fstores,cs")]) @@ -1189,7 +1224,7 @@ lhy\t%0,%1 sth\t%1,%0 sthy\t%1,%0 - mvc\t%O0(2,%R0),%1" + #" [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SS") (set_attr "type" "lr,*,*,*,store,store,cs")]) @@ -1238,7 +1273,7 @@ stcy\t%1,%0 mvi\t%0,%b1 mviy\t%0,%b1 - mvc\t%O0(1,%R0),%1" + #" [(set_attr "op_type" "RR,RI,RX,RXY,RX,RXY,SI,SIY,SS") (set_attr "type" "lr,*,*,*,store,store,store,store,cs")]) @@ -1317,7 +1352,7 @@ lgr\t%0,%1 lg\t%0,%1 stg\t%1,%0 - mvc\t%O0(8,%R0),%1" + #" [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RRE,RXY,RXY,SS") (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lr,load,store,cs")]) @@ -1335,7 +1370,7 @@ stm\t%1,%N1,%0 # # - mvc\t%O0(8,%R0),%1" + #" [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RS,RS,NN,NN,SS") (set_attr "type" "floadd,floadd,floadd,fstored,fstored,lm,stm,*,*,cs")]) @@ -1411,11 +1446,59 @@ ly\t%0,%1 st\t%1,%0 sty\t%1,%0 - mvc\t%O0(4,%R0),%1" + #" [(set_attr "op_type" "RR,RX,RXY,RX,RXY,RR,RX,RXY,RX,RXY,SS") (set_attr "type" "floads,floads,floads,fstores,fstores,lr,load,load,store,store,cs")]) ; +; Block move (MVC) patterns. +; + +(define_insn "*mvc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (match_operand:BLK 1 "memory_operand" "Q")) + (use (match_operand 2 "const_int_operand" "n"))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "mvc\t%O0(%2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (match_operand 1 "memory_operand" ""))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (match_dup 1)) + (use (match_dup 2))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (match_operand:BLK 1 "memory_operand" "")) + (use (match_operand 2 "const_int_operand" ""))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (match_operand:BLK 4 "memory_operand" "")) + (use (match_operand 5 "const_int_operand" ""))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (match_dup 7)) + (use (match_dup 8))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") + + +; ; load_multiple pattern(s). ; ; ??? Due to reload problems with replacing registers inside match_parallel @@ -1776,15 +1859,6 @@ (use (const_int 1))])] "operands[4] = gen_label_rtx ();") -(define_insn "*mvc" - [(set (match_operand:BLK 0 "memory_operand" "=Q") - (match_operand:BLK 1 "memory_operand" "Q")) - (use (match_operand 2 "const_int_operand" "n"))] - "" - "mvc\t%O0(%2,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "type" "cs")]) - ; Move a block of arbitrary length. (define_expand "movmem_long" @@ -1942,16 +2016,6 @@ (clobber (reg:CC 33))])] "operands[3] = gen_label_rtx ();") -(define_insn "*xc_zero" - [(set (match_operand:BLK 0 "memory_operand" "=Q") - (const_int 0)) - (use (match_operand 1 "const_int_operand" "n")) - (clobber (reg:CC 33))] - "" - "xc\t%O0(%1,%R0),%0" - [(set_attr "op_type" "SS") - (set_attr "type" "cs")]) - ; Clear a block of arbitrary length. (define_expand "clrmem_long" @@ -2092,16 +2156,6 @@ (use (const_int 1))])] "operands[4] = gen_label_rtx ();") -(define_insn "*clc" - [(set (reg:CCU 33) - (compare:CCU (match_operand:BLK 0 "memory_operand" "=Q") - (match_operand:BLK 1 "memory_operand" "Q"))) - (use (match_operand 2 "const_int_operand" "n"))] - "" - "clc\t%O0(%2,%R0),%1" - [(set_attr "op_type" "SS") - (set_attr "type" "cs")]) - ; Compare a block of arbitrary length. (define_expand "cmpmem_long" @@ -5155,7 +5209,7 @@ ngr\t%0,%2 ng\t%0,%2 # - nc\t%O0(8,%R0),%2" + #" [(set_attr "op_type" "RRE,RXE,RI,RI,RI,RI,RRE,RXY,SI,SS")]) (define_split @@ -5226,7 +5280,7 @@ n\t%0,%2 ny\t%0,%2 # - nc\t%O0(4,%R0),%2" + #" [(set_attr "op_type" "RRE,RXE,RI,RI,RR,RX,RXY,SI,SS")]) (define_insn "*andsi3_esa" @@ -5239,7 +5293,7 @@ nr\t%0,%2 n\t%0,%2 # - nc\t%O0(4,%R0),%2" + #" [(set_attr "op_type" "RR,RX,SI,SS")]) (define_split @@ -5274,7 +5328,7 @@ nr\t%0,%2 nill\t%0,%x2 # - nc\t%O0(2,%R0),%2" + #" [(set_attr "op_type" "RR,RI,SI,SS")]) (define_insn "*andhi3_esa" @@ -5286,7 +5340,7 @@ "@ nr\t%0,%2 # - nc\t%O0(2,%R0),%2" + #" [(set_attr "op_type" "RR,SI,SS")]) (define_split @@ -5322,7 +5376,7 @@ nill\t%0,%b2 ni\t%0,%b2 niy\t%0,%b2 - nc\t%O0(1,%R0),%2" + #" [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) (define_insn "*andqi3_esa" @@ -5334,7 +5388,7 @@ "@ nr\t%0,%2 ni\t%0,%b2 - nc\t%O0(1,%R0),%2" + #" [(set_attr "op_type" "RR,SI,SS")]) (define_expand "andqi3" @@ -5345,6 +5399,63 @@ "" "s390_expand_logical_operator (AND, QImode, operands); DONE;") +; +; Block and (NC) patterns. +; + +(define_insn "*nc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (and:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n")) + (clobber (reg:CC 33))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "nc\t%O0(%2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (and (match_dup 0) + (match_operand 1 "memory_operand" ""))) + (clobber (reg:CC 33))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (and:BLK (match_dup 0) (match_dup 1))) + (use (match_dup 2)) + (clobber (reg:CC 33))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (and:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (clobber (reg:CC 33))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (and:BLK (match_dup 3) + (match_operand:BLK 4 "memory_operand" ""))) + (use (match_operand 5 "const_int_operand" "")) + (clobber (reg:CC 33))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7))) + (use (match_dup 8)) + (clobber (reg:CC 33))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") + ;; ;;- Bit set (inclusive or) instructions. @@ -5394,7 +5505,7 @@ ogr\t%0,%2 og\t%0,%2 # - oc\t%O0(8,%R0),%2" + #" [(set_attr "op_type" "RI,RI,RI,RI,RRE,RXY,SI,SS")]) (define_split @@ -5459,7 +5570,7 @@ o\t%0,%2 oy\t%0,%2 # - oc\t%O0(4,%R0),%2" + #" [(set_attr "op_type" "RI,RI,RR,RX,RXY,SI,SS")]) (define_insn "*iorsi3_esa" @@ -5472,7 +5583,7 @@ or\t%0,%2 o\t%0,%2 # - oc\t%O0(4,%R0),%2" + #" [(set_attr "op_type" "RR,RX,SI,SS")]) (define_split @@ -5507,7 +5618,7 @@ or\t%0,%2 oill\t%0,%x2 # - oc\t%O0(2,%R0),%2" + #" [(set_attr "op_type" "RR,RI,SI,SS")]) (define_insn "*iorhi3_esa" @@ -5519,7 +5630,7 @@ "@ or\t%0,%2 # - oc\t%O0(2,%R0),%2" + #" [(set_attr "op_type" "RR,SI,SS")]) (define_split @@ -5555,7 +5666,7 @@ oill\t%0,%b2 oi\t%0,%b2 oiy\t%0,%b2 - oc\t%O0(1,%R0),%2" + #" [(set_attr "op_type" "RR,RI,SI,SIY,SS")]) (define_insn "*iorqi3_esa" @@ -5567,7 +5678,7 @@ "@ or\t%0,%2 oi\t%0,%b2 - oc\t%O0(1,%R0),%2" + #" [(set_attr "op_type" "RR,SI,SS")]) (define_expand "iorqi3" @@ -5578,6 +5689,63 @@ "" "s390_expand_logical_operator (IOR, QImode, operands); DONE;") +; +; Block inclusive or (OC) patterns. +; + +(define_insn "*oc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (ior:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n")) + (clobber (reg:CC 33))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "oc\t%O0(%2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (ior (match_dup 0) + (match_operand 1 "memory_operand" ""))) + (clobber (reg:CC 33))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (ior:BLK (match_dup 0) (match_dup 1))) + (use (match_dup 2)) + (clobber (reg:CC 33))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (ior:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (clobber (reg:CC 33))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (ior:BLK (match_dup 3) + (match_operand:BLK 4 "memory_operand" ""))) + (use (match_operand 5 "const_int_operand" "")) + (clobber (reg:CC 33))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7))) + (use (match_dup 8)) + (clobber (reg:CC 33))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") + ;; ;;- Xor instructions. @@ -5622,7 +5790,7 @@ xgr\t%0,%2 xg\t%0,%2 # - xc\t%O0(8,%R0),%2" + #" [(set_attr "op_type" "RRE,RXY,SI,SS")]) (define_split @@ -5685,7 +5853,7 @@ x\t%0,%2 xy\t%0,%2 # - xc\t%O0(4,%R0),%2" + #" [(set_attr "op_type" "RR,RX,RXY,SI,SS")]) (define_split @@ -5719,7 +5887,7 @@ "@ xr\t%0,%2 # - xc\t%O0(2,%R0),%2" + #" [(set_attr "op_type" "RR,SI,SS")]) (define_split @@ -5754,7 +5922,7 @@ xr\t%0,%2 xi\t%0,%b2 xiy\t%0,%b2 - xc\t%O0(1,%R0),%2" + #" [(set_attr "op_type" "RR,SI,SIY,SS")]) (define_expand "xorqi3" @@ -5765,6 +5933,97 @@ "" "s390_expand_logical_operator (XOR, QImode, operands); DONE;") +; +; Block exclusive or (XC) patterns. +; + +(define_insn "*xc" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (xor:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" "Q"))) + (use (match_operand 2 "const_int_operand" "n")) + (clobber (reg:CC 33))] + "INTVAL (operands[2]) >= 1 && INTVAL (operands[2]) <= 256" + "xc\t%O0(%2,%R0),%1" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) + +(define_split + [(set (match_operand 0 "memory_operand" "") + (xor (match_dup 0) + (match_operand 1 "memory_operand" ""))) + (clobber (reg:CC 33))] + "reload_completed + && GET_MODE (operands[0]) == GET_MODE (operands[1]) + && GET_MODE_SIZE (GET_MODE (operands[0])) > 0" + [(parallel + [(set (match_dup 0) (xor:BLK (match_dup 0) (match_dup 1))) + (use (match_dup 2)) + (clobber (reg:CC 33))])] +{ + operands[2] = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[0]))); + operands[0] = adjust_address (operands[0], BLKmode, 0); + operands[1] = adjust_address (operands[1], BLKmode, 0); +}) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (xor:BLK (match_dup 0) + (match_operand:BLK 1 "memory_operand" ""))) + (use (match_operand 2 "const_int_operand" "")) + (clobber (reg:CC 33))]) + (parallel + [(set (match_operand:BLK 3 "memory_operand" "") + (xor:BLK (match_dup 3) + (match_operand:BLK 4 "memory_operand" ""))) + (use (match_operand 5 "const_int_operand" "")) + (clobber (reg:CC 33))])] + "s390_offset_p (operands[0], operands[3], operands[2]) + && s390_offset_p (operands[1], operands[4], operands[2]) + && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" + [(parallel + [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7))) + (use (match_dup 8)) + (clobber (reg:CC 33))])] + "operands[6] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); + operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") + +; +; Block xor (XC) patterns with src == dest. +; + +(define_insn "*xc_zero" + [(set (match_operand:BLK 0 "memory_operand" "=Q") + (const_int 0)) + (use (match_operand 1 "const_int_operand" "n")) + (clobber (reg:CC 33))] + "INTVAL (operands[1]) >= 1 && INTVAL (operands[1]) <= 256" + "xc\t%O0(%1,%R0),%0" + [(set_attr "op_type" "SS") + (set_attr "type" "cs")]) + +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "memory_operand" "") + (const_int 0)) + (use (match_operand 1 "const_int_operand" "")) + (clobber (reg:CC 33))]) + (parallel + [(set (match_operand:BLK 2 "memory_operand" "") + (const_int 0)) + (use (match_operand 3 "const_int_operand" "")) + (clobber (reg:CC 33))])] + "s390_offset_p (operands[0], operands[2], operands[1]) + && INTVAL (operands[1]) + INTVAL (operands[3]) <= 256" + [(parallel + [(set (match_dup 4) (const_int 0)) + (use (match_dup 5)) + (clobber (reg:CC 33))])] + "operands[4] = gen_rtx_MEM (BLKmode, XEXP (operands[0], 0)); + operands[5] = GEN_INT (INTVAL (operands[1]) + INTVAL (operands[3]));") + ;; ;;- Negate instructions. -- 2.7.4