diff options
author | Christoph Müllner <christoph.muellner@vrull.eu> | 2023-03-15 10:45:11 +0100 |
---|---|---|
committer | Kito Cheng <kito.cheng@sifive.com> | 2023-07-12 16:05:50 +0800 |
commit | d05c8b016fb96cdcc445406469867b757776894e (patch) | |
tree | 1aab1ee7a3b34ba3b33e2c75e725815b1f1b8c12 /gcc | |
parent | 13c556d6ae84be3ee2bc245a56eafa58221de86a (diff) | |
download | gcc-d05c8b016fb96cdcc445406469867b757776894e.zip gcc-d05c8b016fb96cdcc445406469867b757776894e.tar.gz gcc-d05c8b016fb96cdcc445406469867b757776894e.tar.bz2 |
riscv: xtheadbb: Add sign/zero extension support for th.ext and th.extu
The current support of the bitfield-extraction instructions
th.ext and th.extu (XTheadBb extension) only covers sign_extract
and zero_extract. This patch add support for sign_extend and
zero_extend to avoid any shifts for sign or zero extensions.
gcc/ChangeLog:
* config/riscv/riscv.md: No base-ISA extension splitter for XThead*.
* config/riscv/thead.md (*extend<SHORT:mode><SUPERQI:mode>2_th_ext):
New XThead extension INSN.
(*zero_extendsidi2_th_extu): New XThead extension INSN.
(*zero_extendhi<GPR:mode>2_th_extu): New XThead extension INSN.
gcc/testsuite/ChangeLog:
* gcc.target/riscv/xtheadbb-ext-1.c: New test.
* gcc.target/riscv/xtheadbb-extu-1.c: New test.
Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/riscv/riscv.md | 6 | ||||
-rw-r--r-- | gcc/config/riscv/thead.md | 31 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c | 67 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c | 67 |
4 files changed, 168 insertions, 3 deletions
diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md index d63b584..7988026 100644 --- a/gcc/config/riscv/riscv.md +++ b/gcc/config/riscv/riscv.md @@ -1594,7 +1594,7 @@ [(set (match_operand:DI 0 "register_operand" "=r,r") (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" " r,m")))] - "TARGET_64BIT && !TARGET_ZBA + "TARGET_64BIT && !TARGET_ZBA && !TARGET_XTHEADBB && !(register_operand (operands[1], SImode) && reg_or_subregno (operands[1]) == VL_REGNUM)" "@ @@ -1621,7 +1621,7 @@ [(set (match_operand:GPR 0 "register_operand" "=r,r") (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" " r,m")))] - "!TARGET_ZBB" + "!TARGET_ZBB && !TARGET_XTHEADBB" "@ # lhu\t%0,%1" @@ -1677,7 +1677,7 @@ [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") (sign_extend:SUPERQI (match_operand:SHORT 1 "nonimmediate_operand" " r,m")))] - "!TARGET_ZBB" + "!TARGET_ZBB && !TARGET_XTHEADBB" "@ # l<SHORT:size>\t%0,%1" diff --git a/gcc/config/riscv/thead.md b/gcc/config/riscv/thead.md index ea37787..e8d3fcb 100644 --- a/gcc/config/riscv/thead.md +++ b/gcc/config/riscv/thead.md @@ -59,6 +59,17 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "<GPR:MODE>")]) +(define_insn "*extend<SHORT:mode><SUPERQI:mode>2_th_ext" + [(set (match_operand:SUPERQI 0 "register_operand" "=r,r") + (sign_extend:SUPERQI + (match_operand:SHORT 1 "nonimmediate_operand" "r,m")))] + "TARGET_XTHEADBB" + "@ + th.ext\t%0,%1,15,0 + l<SHORT:size>\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "<SUPERQI: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") @@ -72,6 +83,26 @@ [(set_attr "type" "bitmanip") (set_attr "mode" "<GPR:MODE>")]) +(define_insn "*zero_extendsidi2_th_extu" + [(set (match_operand:DI 0 "register_operand" "=r,r") + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m")))] + "TARGET_64BIT && TARGET_XTHEADBB" + "@ + th.extu\t%0,%1,31,0 + lwu\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "SI")]) + +(define_insn "*zero_extendhi<GPR:mode>2_th_extu" + [(set (match_operand:GPR 0 "register_operand" "=r,r") + (zero_extend:GPR (match_operand:HI 1 "nonimmediate_operand" "r,m")))] + "TARGET_XTHEADBB" + "@ + th.extu\t%0,%1,15,0 + lhu\t%0,%1" + [(set_attr "type" "bitmanip,load") + (set_attr "mode" "HI")]) + (define_insn "*th_clz<mode>2" [(set (match_operand:X 0 "register_operand" "=r") (clz:X (match_operand:X 1 "register_operand" "r")))] diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c new file mode 100644 index 0000000..02f6ec1 --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +long sext64_32(int s32) +{ + return s32; +} + +long sext64_16(short s16) +{ + return s16; +} + +long sext64_8(char s8) +{ + return s8; +} + +int sext32_64(long s64) +{ + return s64; +} + +int sext32_16(short s16) +{ + return s16; +} + +int sext32_8(char s8) +{ + return s8; +} + +short sext16_64(long s64) +{ + return s64; +} + +short sext16_32(int s32) +{ + return s32; +} + +short sext16_8(char s8) +{ + return s8; +} + +char sext8_64(long s64) +{ + return s64; +} + +char sext8_32(int s32) +{ + return s32; +} + +char sext8_16(short s16) +{ + return s16; +} + +/* { dg-final { scan-assembler-not "slli" } } */ +/* { dg-final { scan-assembler-not "srli" } } */ diff --git a/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c new file mode 100644 index 0000000..01e3eda --- /dev/null +++ b/gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c @@ -0,0 +1,67 @@ +/* { dg-do compile } */ +/* { dg-options "-march=rv32gc_xtheadbb" { target { rv32 } } } */ +/* { dg-options "-march=rv64gc_xtheadbb" { target { rv64 } } } */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-Os" "-Og" } } */ + +unsigned long zext64_32(unsigned int u32) +{ + return u32; //th.extu a0, a0, 31, 0 +} + +unsigned long zext64_16(unsigned short u16) +{ + return u16; +} + +unsigned long zext64_8(unsigned char u8) +{ + return u8; +} + +unsigned int zext32_64(unsigned long u64) +{ + return u64; +} + +unsigned int zext32_16(unsigned short u16) +{ + return u16; +} + +unsigned int zext32_8(unsigned char u8) +{ + return u8; +} + +unsigned short zext16_64(unsigned long u64) +{ + return u64; +} + +unsigned short zext16_32(unsigned int u32) +{ + return u32; +} + +unsigned short zext16_8(unsigned char u8) +{ + return u8; +} + +unsigned char zext8_64(unsigned long u64) +{ + return u64; +} + +unsigned char zext8_32(unsigned int u32) +{ + return u32; +} + +unsigned char zext8_16(unsigned short u16) +{ + return u16; +} + +/* { dg-final { scan-assembler-not "slli" } } */ +/* { dg-final { scan-assembler-not "srli" } } */ |