diff options
author | Christoph Müllner <christoph.muellner@vrull.eu> | 2022-07-29 05:19:56 +0200 |
---|---|---|
committer | Philipp Tomsich <philipp.tomsich@vrull.eu> | 2023-03-15 09:56:52 +0100 |
commit | c493fa3892487c22d0bdd817361a02bd523fc2e7 (patch) | |
tree | 6d44dab5ab6d97d00b24c21815512373d039c604 /gcc | |
parent | d328d3a6f8756ed61b3cdf3675b24051f7d3b2ef (diff) | |
download | gcc-c493fa3892487c22d0bdd817361a02bd523fc2e7.zip gcc-c493fa3892487c22d0bdd817361a02bd523fc2e7.tar.gz gcc-c493fa3892487c22d0bdd817361a02bd523fc2e7.tar.bz2 |
riscv: thead: Add support for the XTheadBb ISA extension
This patch adds support for the XTheadBb ISA extension.
Thus, there is a functional overlap of the new instructions with
existing Bitmanip instruction, which allows a good amount of code
sharing. However, the vendor extensions are cleanly separated from
the standard extensions (e.g. by using INSN expand pattern that
will re-emit RTL that matches the patterns of either Bitmanip or
XThead INSNs).
gcc/ChangeLog:
* config/riscv/bitmanip.md (clzdi2): New expand.
(clzsi2): New expand.
(ctz<mode>2): New expand.
(popcount<mode>2): New expand.
(<bitmanip_optab>si2): Rename INSN.
(*<bitmanip_optab>si2): Hide INSN name.
(<bitmanip_optab>di2): Rename INSN.
(*<bitmanip_optab>di2): Hide INSN name.
(rotrsi3): Remove INSN.
(rotr<mode>3): Add expand.
(*rotrsi3): New INSN.
(rotrdi3): Rename INSN.
(*rotrdi3): Hide INSN name.
(rotrsi3_sext): Rename INSN.
(*rotrsi3_sext): Hide INSN name.
(bswap<mode>2): Remove INSN.
(bswapdi2): Add expand.
(bswapsi2): Add expand.
(*bswap<mode>2): Hide INSN name.
* config/riscv/riscv.cc (riscv_rtx_costs): Add costs for sign
extraction.
* config/riscv/riscv.md (extv<mode>): New expand.
(extzv<mode>): New expand.
* config/riscv/thead.md (*th_srri<mode>3): New INSN.
(*th_ext<mode>): New INSN.
(*th_extu<mode>): New INSN.
(*th_clz<mode>2): New INSN.
(*th_rev<mode>2): New INSN.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/xtheadbb-ext.c: New test.
* gcc.target/riscv/xtheadbb-extu-2.c: New test.
* gcc.target/riscv/xtheadbb-extu.c: New test.
* gcc.target/riscv/xtheadbb-ff1.c: New test.
* gcc.target/riscv/xtheadbb-rev.c: New test.
* gcc.target/riscv/xtheadbb-srri.c: New test.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/riscv/bitmanip.md | 52 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.cc | 9 | ||||
-rw-r--r-- | gcc/config/riscv/riscv.md | 20 | ||||
-rw-r--r-- | gcc/config/riscv/thead.md | 61 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c | 20 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c | 22 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c | 18 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c | 45 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c | 25 |
10 files changed, 288 insertions, 6 deletions
diff --git a/gcc/config/riscv/bitmanip.md b/gcc/config/riscv/bitmanip.md index ff9ecb4..7aa5916 100644 --- a/gcc/config/riscv/bitmanip.md +++ b/gcc/config/riscv/bitmanip.md @@ -185,6 +185,26 @@ ;; ZBB extension. +(define_expand "clzdi2" + [(set (match_operand:DI 0 "register_operand") + (clz:DI (match_operand:DI 1 "register_operand")))] + "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)") + +(define_expand "clzsi2" + [(set (match_operand:SI 0 "register_operand") + (clz:SI (match_operand:SI 1 "register_operand")))] + "TARGET_ZBB || (!TARGET_64BIT && TARGET_XTHEADBB)") + +(define_expand "ctz<mode>2" + [(set (match_operand:GPR 0 "register_operand") + (ctz:GPR (match_operand:GPR 1 "register_operand")))] + "TARGET_ZBB") + +(define_expand "popcount<mode>2" + [(set (match_operand:GPR 0 "register_operand") + (popcount:GPR (match_operand:GPR 1 "register_operand")))] + "TARGET_ZBB") + (define_insn "*<optab>_not<mode>" [(set (match_operand:X 0 "register_operand" "=r") (bitmanip_bitwise:X (not:X (match_operand:X 1 "register_operand" "r")) @@ -216,7 +236,7 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "<X:MODE>")]) -(define_insn "<bitmanip_optab>si2" +(define_insn "*<bitmanip_optab>si2" [(set (match_operand:SI 0 "register_operand" "=r") (clz_ctz_pcnt:SI (match_operand:SI 1 "register_operand" "r")))] "TARGET_ZBB" @@ -233,7 +253,7 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "SI")]) -(define_insn "<bitmanip_optab>di2" +(define_insn "*<bitmanip_optab>di2" [(set (match_operand:DI 0 "register_operand" "=r") (clz_ctz_pcnt:DI (match_operand:DI 1 "register_operand" "r")))] "TARGET_64BIT && TARGET_ZBB" @@ -273,7 +293,17 @@ [(set_attr "type" "bitmanip,load") (set_attr "mode" "HI")]) -(define_insn "rotrsi3" +(define_expand "rotr<mode>3" + [(set (match_operand:GPR 0 "register_operand") + (rotatert:GPR (match_operand:GPR 1 "register_operand") + (match_operand:QI 2 "arith_operand")))] + "TARGET_ZBB || TARGET_XTHEADBB" +{ + if (TARGET_XTHEADBB && !immediate_operand (operands[2], VOIDmode)) + FAIL; +}) + +(define_insn "*rotrsi3" [(set (match_operand:SI 0 "register_operand" "=r") (rotatert:SI (match_operand:SI 1 "register_operand" "r") (match_operand:QI 2 "arith_operand" "rI")))] @@ -281,7 +311,7 @@ "ror%i2%~\t%0,%1,%2" [(set_attr "type" "bitmanip")]) -(define_insn "rotrdi3" +(define_insn "*rotrdi3" [(set (match_operand:DI 0 "register_operand" "=r") (rotatert:DI (match_operand:DI 1 "register_operand" "r") (match_operand:QI 2 "arith_operand" "rI")))] @@ -289,7 +319,7 @@ "ror%i2\t%0,%1,%2" [(set_attr "type" "bitmanip")]) -(define_insn "rotrsi3_sext" +(define_insn "*rotrsi3_sext" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (rotatert:SI (match_operand:SI 1 "register_operand" "r") (match_operand:QI 2 "register_operand" "r"))))] @@ -329,7 +359,17 @@ "TARGET_ZBB" "orc.b\t%0,%1") -(define_insn "bswap<mode>2" +(define_expand "bswapdi2" + [(set (match_operand:DI 0 "register_operand") + (bswap:DI (match_operand:DI 1 "register_operand")))] + "TARGET_64BIT && (TARGET_ZBB || TARGET_XTHEADBB)") + +(define_expand "bswapsi2" + [(set (match_operand:SI 0 "register_operand") + (bswap:SI (match_operand:SI 1 "register_operand")))] + "(!TARGET_64BIT && TARGET_ZBB) || TARGET_XTHEADBB") + +(define_insn "*bswap<mode>2" [(set (match_operand:X 0 "register_operand" "=r") (bswap:X (match_operand:X 1 "register_operand" "r")))] "TARGET_ZBB || TARGET_ZBKB" diff --git a/gcc/config/riscv/riscv.cc b/gcc/config/riscv/riscv.cc index 69fb789..217f407 100644 --- a/gcc/config/riscv/riscv.cc +++ b/gcc/config/riscv/riscv.cc @@ -2420,6 +2420,15 @@ riscv_rtx_costs (rtx x, machine_mode mode, int outer_code, int opno ATTRIBUTE_UN *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); return true; } + gcc_fallthrough (); + case SIGN_EXTRACT: + if (TARGET_XTHEADBB && outer_code == SET + && CONST_INT_P (XEXP (x, 1)) + && CONST_INT_P (XEXP (x, 2))) + { + *total = COSTS_N_INSNS (SINGLE_SHIFT_COST); + return true; + } return false; case ASHIFT: diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index 6a99833..c53c1a7 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -3096,6 +3096,26 @@ "prefetch.i\t%a0" ) +(define_expand "extv<mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (sign_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +) + +(define_expand "extzv<mode>" + [(set (match_operand:GPR 0 "register_operand" "=r") + (zero_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +{ + if (TARGET_XTHEADBB + && (INTVAL (operands[2]) < 8) && (INTVAL (operands[3]) == 0)) + FAIL; +}) + (include "bitmanip.md") (include "crypto.md") (include "sync.md") diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index 3842a19..372d460 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -30,6 +30,67 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "<X:MODE>")]) +;; XTheadBb + +(define_insn "*th_srri<mode>3" + [(set (match_operand:GPR 0 "register_operand" "=r") + (rotatert:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand" "n")))] + "TARGET_XTHEADBB && (TARGET_64BIT || <MODE>mode == SImode)" + { + bool wform = TARGET_64BIT && (<MODE>mode == SImode); + operands[2] = GEN_INT (INTVAL (operands[2]) + & (GET_MODE_BITSIZE (<MODE>mode) - 1)); + return wform ? "th.srriw\t%0,%1,%2" : "th.srri\t%0,%1,%2"; + } + [(set_attr "type" "bitmanip") + (set_attr "mode" "<GPR:MODE>")]) + +(define_insn "*th_ext<mode>4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (sign_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +{ + operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); + return "th.ext\t%0,%1,%2,%3"; +} + [(set_attr "type" "bitmanip") + (set_attr "mode" "<GPR:MODE>")]) + +(define_insn "*th_extu<mode>4" + [(set (match_operand:GPR 0 "register_operand" "=r") + (zero_extract:GPR (match_operand:GPR 1 "register_operand" "r") + (match_operand 2 "const_int_operand") + (match_operand 3 "const_int_operand")))] + "TARGET_XTHEADBB" +{ + operands[2] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[3]) - 1); + return "th.extu\t%0,%1,%2,%3"; +} + [(set_attr "type" "bitmanip") + (set_attr "mode" "<GPR:MODE>")]) + +(define_insn "*th_clz<mode>2" + [(set (match_operand:X 0 "register_operand" "=r") + (clz:X (match_operand:X 1 "register_operand" "r")))] + "TARGET_XTHEADBB" + "th.ff1\t%0,%1" + [(set_attr "type" "bitmanip") + (set_attr "mode" "<X:MODE>")]) + +(define_insn "*th_rev<mode>2" + [(set (match_operand:GPR 0 "register_operand" "=r") + (bswap:GPR (match_operand:GPR 1 "register_operand" "r")))] + "TARGET_XTHEADBB && (TARGET_64BIT || <MODE>mode == SImode)" + { + bool wform = TARGET_64BIT && (<MODE>mode == SImode); + return wform ? "th.revw\t%0,%1" : "th.rev\t%0,%1"; + } + [(set_attr "type" "bitmanip") + (set_attr "mode" "<GPR:MODE>")]) + ;; XTheadBs (define_insn "*th_tst<mode>3" diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c new file mode 100644 index 0000000..60fb7d4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +struct bar +{ + long a:9; + long b:26; + long c:22; +}; + +long +foo (struct bar *s) +{ + return s->b; +} + +/* { dg-final { scan-assembler "th.ext\t" } } */ +/* { dg-final { scan-assembler-not "andi" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c new file mode 100644 index 0000000..029be93 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +struct bar +{ + unsigned long a:6; + unsigned long b:26; + unsigned long c:22; +}; + +/* We prefer andi over th.extu because it can be compressed. */ + +unsigned long +foo (struct bar *s) +{ + return s->a; +} + +/* { dg-final { scan-assembler-not "th.extu\t" } } */ +/* { dg-final { scan-assembler "andi\t" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c new file mode 100644 index 0000000..e0492f1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +struct bar +{ + unsigned long a:5; + unsigned long b:26; + unsigned long c:22; +}; + +unsigned long +foo (struct bar *s) +{ + return s->b; +} + +/* { dg-final { scan-assembler "th.extu\t" } } */ +/* { dg-final { scan-assembler-not "andi" } } */ +/* { dg-final { scan-assembler-not "slli" } } */ +/* { dg-final { scan-assembler-not "srli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c new file mode 100644 index 0000000..72038c4 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ff1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +int +foo (unsigned long a) +{ + return __builtin_clzl (a); +} + +int +bar (unsigned long a) +{ + return __builtin_ctzl (a); +} + +/* { dg-final { scan-assembler-times "th.ff1\t" 2 } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c new file mode 100644 index 0000000..411d520 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-rev.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-Og" } } */ + +unsigned int +foo32 (unsigned int x) +{ + return (((x << 24) & 0xff000000) + | ((x << 8) & 0xff0000) + | ((x >> 8) & 0xff00) + | ((x >> 24) & 0xff)); +} + +unsigned int +foo32_1 (unsigned int x) +{ + return __builtin_bswap32 (x); +} + +#if __riscv_xlen == 64 +unsigned long +foo64 (unsigned long x) +{ + return (((x << 56) & 0xff00000000000000ull) + | ((x << 40) & 0xff000000000000ull) + | ((x << 24) & 0xff0000000000ull) + | ((x << 8) & 0xff00000000ull) + | ((x >> 8) & 0xff000000) + | ((x >> 24) & 0xff0000) + | ((x >> 40) & 0xff00) + | ((x >> 56) & 0xff)); +} + +unsigned long +foo64_1 (unsigned long x) +{ + return __builtin_bswap64 (x); +} +#endif + +/* { dg-final { scan-assembler-times "th.rev\t" 2 { target { rv32 } } } } */ + +/* { dg-final { scan-assembler-times "th.revw\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.rev\t" 2 { target { rv64 } } } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c new file mode 100644 index 0000000..973ed17 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-srri.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" } } */ + +unsigned long +foo1 (unsigned long rs1) +{ + unsigned sz = sizeof(unsigned long) * 8; + unsigned shamt = sz - 11; + return (rs1 << shamt) | (rs1 >> (sz - shamt)); +} + +unsigned int +foo2 (unsigned int rs1) +{ + unsigned sz = sizeof(unsigned int) * 8; + unsigned shamt = sz - 11; + return (rs1 << shamt) | (rs1 >> (sz - shamt)); +} + +/* { dg-final { scan-assembler-times "th.srri\t" 2 { target { rv32 } } } } */ + +/* { dg-final { scan-assembler-times "th.srri\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "th.srriw\t" 1 { target { rv64 } } } } */ |