ok
On Fri, Apr 28, 2023 at 2:13 PM Christoph Muellner <christoph.muell...@vrull.eu> wrote: > > From: Christoph Müllner <christoph.muell...@vrull.eu> > > 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.muell...@vrull.eu> > --- > gcc/config/riscv/riscv.md | 6 +- > gcc/config/riscv/thead.md | 31 +++++++++ > .../gcc.target/riscv/xtheadbb-ext-1.c | 67 +++++++++++++++++++ > .../gcc.target/riscv/xtheadbb-extu-1.c | 67 +++++++++++++++++++ > 4 files changed, 168 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-ext-1.c > create mode 100644 gcc/testsuite/gcc.target/riscv/xtheadbb-extu-1.c > > diff --git a/gcc/config/riscv/riscv.md b/gcc/config/riscv/riscv.md > index 1fb29da8a0b..f4cc99187ed 100644 > --- a/gcc/config/riscv/riscv.md > +++ b/gcc/config/riscv/riscv.md > @@ -1368,7 +1368,7 @@ (define_insn_and_split "*zero_extendsidi2_internal" > [(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)" > "@ > @@ -1395,7 +1395,7 @@ (define_insn_and_split "*zero_extendhi<GPR:mode>2" > [(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" > @@ -1451,7 +1451,7 @@ (define_insn_and_split > "*extend<SHORT:mode><SUPERQI:mode>2" > [(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 0623607d3dc..6a06d0dfcf2 100644 > --- a/gcc/config/riscv/thead.md > +++ b/gcc/config/riscv/thead.md > @@ -59,6 +59,17 @@ (define_insn "*th_ext<mode>4" > [(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 @@ (define_insn "*th_extu<mode>4" > [(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 00000000000..02f6ec1417d > --- /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 00000000000..01e3eda7df2 > --- /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" } } */ > -- > 2.40.1 >