aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorChristoph Müllner <christoph.muellner@vrull.eu>2023-03-15 10:45:11 +0100
committerKito Cheng <kito.cheng@sifive.com>2023-07-12 16:05:50 +0800
commitd05c8b016fb96cdcc445406469867b757776894e (patch)
tree1aab1ee7a3b34ba3b33e2c75e725815b1f1b8c12 /gcc
parent13c556d6ae84be3ee2bc245a56eafa58221de86a (diff)
downloadgcc-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.md6
-rw-r--r--gcc/config/riscv/thead.md31
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c67
-rw-r--r--gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c67
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" } } */