From: Andreas Krebbel Date: Fri, 24 Mar 2017 14:02:51 +0000 (+0000) Subject: S/390: arch12: Support the mul/add/subtract X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7d2fd07577b71f2ef3143ffb80ca6223d06dd396;p=gcc.git S/390: arch12: Support the mul/add/subtract instructions. gcc/ChangeLog: 2017-03-24 Andreas Krebbel * config/s390/s390.md ("*adddi3_sign", "*subdi3_sign", "mulditi3") ("mulditi3_2", "*muldi3_sign"): New patterns. ("muldi3", "*muldi3", "mulsi3", "*mulsi3"): Add an expander and rename the pattern definition. gcc/testsuite/ChangeLog: 2017-03-24 Andreas Krebbel * gcc.target/s390/arch12/aghsghmgh-1.c: New test. * gcc.target/s390/arch12/mul-1.c: New test. * gcc.target/s390/arch12/mul-2.c: New test. From-SVN: r246457 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 72afffad7f4..ca127058bd5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2017-03-24 Andreas Krebbel + + * config/s390/s390.md ("*adddi3_sign", "*subdi3_sign", "mulditi3") + ("mulditi3_2", "*muldi3_sign"): New patterns. + ("muldi3", "*muldi3", "mulsi3", "*mulsi3"): Add an expander and + rename the pattern definition. + 2017-03-24 Andreas Krebbel * config/s390/s390.md ("indirect_jump"): Turn insn definition into diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 32753ef746d..93a0bc6767e 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -5795,6 +5795,15 @@ (set_attr "cpu_facility" "*,z196,extimm,z10") (set_attr "z10prop" "z10_super_E1,*,z10_super_E1,z10_super_E1")]) +(define_insn "*adddi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T")) + (match_operand:DI 1 "register_operand" "0"))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ARCH12" + "agh\t%0,%2" + [(set_attr "op_type" "RXY")]) + ; ; add(tf|df|sf|td|dd)3 instruction pattern(s). ; @@ -6226,6 +6235,15 @@ (set_attr "cpu_facility" "*,z196,*,longdisp") (set_attr "z10prop" "z10_super_c_E1,*,z10_super_E1,z10_super_E1")]) +(define_insn "*subdi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (sign_extend:DI (match_operand:HI 2 "memory_operand" "T")))) + (clobber (reg:CC CC_REGNUM))] + "TARGET_ARCH12" + "sgh\t%0,%2" + [(set_attr "op_type" "RXY")]) + ; ; sub(tf|df|sf|td|dd)3 instruction pattern(s). @@ -6565,6 +6583,14 @@ ; muldi3 instruction pattern(s). ; +(define_expand "muldi3" + [(parallel + [(set (match_operand:DI 0 "register_operand") + (mult:DI (match_operand:DI 1 "nonimmediate_operand") + (match_operand:DI 2 "general_operand"))) + (clobber (reg:CC CC_REGNUM))])] + "TARGET_ZARCH") + (define_insn "*muldi3_sign" [(set (match_operand:DI 0 "register_operand" "=d,d") (mult:DI (sign_extend:DI (match_operand:SI 2 "general_operand" "d,T")) @@ -6576,24 +6602,68 @@ [(set_attr "op_type" "RRE,RXY") (set_attr "type" "imuldi")]) -(define_insn "muldi3" - [(set (match_operand:DI 0 "register_operand" "=d,d,d,d") - (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,0") - (match_operand:DI 2 "general_operand" "d,K,T,Os")))] +(define_insn "*muldi3" + [(set (match_operand:DI 0 "register_operand" "=d,d,d,d,d") + (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%0,d,0,0,0") + (match_operand:DI 2 "general_operand" "d,d,K,T,Os"))) + (clobber (match_scratch:CC 3 "=X,c,X,X,X"))] "TARGET_ZARCH" "@ msgr\t%0,%2 + msgrkc\t%0,%1,%2 mghi\t%0,%h2 msg\t%0,%2 msgfi\t%0,%2" - [(set_attr "op_type" "RRE,RI,RXY,RIL") + [(set_attr "op_type" "RRE,RRF,RI,RXY,RIL") (set_attr "type" "imuldi") - (set_attr "cpu_facility" "*,*,*,z10")]) + (set_attr "cpu_facility" "*,arch12,*,*,z10")]) + +(define_insn "mulditi3" + [(set (match_operand:TI 0 "register_operand" "=d,d") + (mult:TI (sign_extend:TI + (match_operand:DI 1 "register_operand" "%d,0")) + (sign_extend:TI + (match_operand:DI 2 "nonimmediate_operand" " d,T"))))] + "TARGET_ARCH12" + "@ + mgrk\t%0,%1,%2 + mg\t%0,%2" + [(set_attr "op_type" "RRF,RXY")]) + +; Combine likes op1 and op2 to be swapped sometimes. +(define_insn "mulditi3_2" + [(set (match_operand:TI 0 "register_operand" "=d,d") + (mult:TI (sign_extend:TI + (match_operand:DI 1 "nonimmediate_operand" "%d,T")) + (sign_extend:TI + (match_operand:DI 2 "register_operand" " d,0"))))] + "TARGET_ARCH12" + "@ + mgrk\t%0,%1,%2 + mg\t%0,%1" + [(set_attr "op_type" "RRF,RXY")]) + +(define_insn "*muldi3_sign" + [(set (match_operand:DI 0 "register_operand" "=d") + (mult:DI (sign_extend:DI (match_operand:HI 2 "memory_operand" "T")) + (match_operand:DI 1 "register_operand" "0")))] + "TARGET_ARCH12" + "mgh\t%0,%2" + [(set_attr "op_type" "RXY")]) + ; ; mulsi3 instruction pattern(s). ; +(define_expand "mulsi3" + [(parallel + [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d") + (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0") + (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os"))) + (clobber (reg:CC CC_REGNUM))])] + "") + (define_insn "*mulsi3_sign" [(set (match_operand:SI 0 "register_operand" "=d,d") (mult:SI (sign_extend:SI (match_operand:HI 2 "memory_operand" "R,T")) @@ -6606,20 +6676,22 @@ (set_attr "type" "imulhi") (set_attr "cpu_facility" "*,z10")]) -(define_insn "mulsi3" - [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d") - (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,0,0,0") - (match_operand:SI 2 "general_operand" "d,K,R,T,Os")))] +(define_insn "*mulsi3" + [(set (match_operand:SI 0 "register_operand" "=d,d,d,d,d,d") + (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%0,d,0,0,0,0") + (match_operand:SI 2 "general_operand" "d,d,K,R,T,Os"))) + (clobber (match_scratch:CC 3 "=X,c,X,X,X,X"))] "" "@ msr\t%0,%2 + msrkc\t%0,%1,%2 mhi\t%0,%h2 ms\t%0,%2 msy\t%0,%2 msfi\t%0,%2" - [(set_attr "op_type" "RRE,RI,RX,RXY,RIL") - (set_attr "type" "imulsi,imulhi,imulsi,imulsi,imulsi") - (set_attr "cpu_facility" "*,*,*,longdisp,z10")]) + [(set_attr "op_type" "RRE,RRF,RI,RX,RXY,RIL") + (set_attr "type" "imulsi,*,imulhi,imulsi,imulsi,imulsi") + (set_attr "cpu_facility" "*,arch12,*,*,longdisp,z10")]) ; ; mulsidi3 instruction pattern(s). diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4405d367e77..914b4b53fd8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-03-24 Andreas Krebbel + + * gcc.target/s390/arch12/aghsghmgh-1.c: New test. + * gcc.target/s390/arch12/mul-1.c: New test. + * gcc.target/s390/arch12/mul-2.c: New test. + 2017-03-24 Andreas Krebbel * gcc.target/s390/vxe/vllezlf-1.c: New test. diff --git a/gcc/testsuite/gcc.target/s390/arch12/aghsghmgh-1.c b/gcc/testsuite/gcc.target/s390/arch12/aghsghmgh-1.c new file mode 100644 index 00000000000..fc844c3e404 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/arch12/aghsghmgh-1.c @@ -0,0 +1,23 @@ +/* { dg-compile } */ + +long long +agh (long long a, short int *p) +{ + return a + *p; +} + +long long +sgh (long long a, short int *p) +{ + return a - *p; +} + +long long +mgh (long long a, short int *p) +{ + return a * *p; +} + +/* { dg-final { scan-assembler-times "\tagh\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tsgh\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmgh\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/arch12/mul-1.c b/gcc/testsuite/gcc.target/s390/arch12/mul-1.c new file mode 100644 index 00000000000..ef395356b72 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/arch12/mul-1.c @@ -0,0 +1,30 @@ +/* { dg-compile } */ + +int +msrkc (int unused, int a, int b) +{ + return a * b; +} + +long long +msgrkc (int unused, long long a, long long b) +{ + return a * b; +} + +/* Make sure the 2 operand version are still being used. */ + +int +msr (int a, int b) +{ + return a * b; +} + +long long +msgr (long long a, long long b) +{ + return a * b; +} + +/* { dg-final { scan-assembler-times "\tmsrkc\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmsgrkc\t" 1 } } */ diff --git a/gcc/testsuite/gcc.target/s390/arch12/mul-2.c b/gcc/testsuite/gcc.target/s390/arch12/mul-2.c new file mode 100644 index 00000000000..ad3b11ed6bc --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/arch12/mul-2.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target int128 } } */ + +__int128 +mgrk (long long a, long long b) +{ + return (__int128)a * (__int128)b; +} + +__int128 +mg (long long a, long long *b) +{ + return (__int128)a * (__int128)*b; +} + +/* { dg-final { scan-assembler-times "\tmgrk\t" 1 } } */ +/* { dg-final { scan-assembler-times "\tmg\t" 1 } } */