diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -131,7 +131,9 @@ // subextensions. They should be enabled if either has been specified. def HasStdExtZbbOrZbp : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp()">, - AssemblerPredicate<(any_of FeatureExtZbb, FeatureExtZbp)>; + AssemblerPredicate<(any_of FeatureExtZbb, FeatureExtZbp), + "'Zbb' (Base 'B' Instructions) or " + "'Zbp' (Permutation 'B' Instructions)">; def FeatureExtZbproposedc : SubtargetFeature<"experimental-zbproposedc", "HasStdExtZbproposedc", "true", diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td @@ -465,6 +465,22 @@ let Predicates = [HasStdExtZbf, IsRV64] in def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>; +let Predicates = [HasStdExtZbbOrZbp, IsRV32] in { +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def ZEXTH_RV32 : RVInstR<0b0000100, 0b100, OPC_OP, (outs GPR:$rd), + (ins GPR:$rs1), "zext.h", "$rd, $rs1">, Sched<[]> { + let rs2 = 0b00000; +} +} // Predicates = [HasStdExtZbbOrZbp, IsRV32] + +let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { +let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in +def ZEXTH_RV64 : RVInstR<0b0000100, 0b100, OPC_OP_32, (outs GPR:$rd), + (ins GPR:$rs1), "zext.h", "$rd, $rs1">, Sched<[]> { + let rs2 = 0b00000; +} +} // Predicates = [HasStdExtZbbOrZbp, IsRV64] + //===----------------------------------------------------------------------===// // Future compressed instructions //===----------------------------------------------------------------------===// @@ -500,14 +516,6 @@ // Pseudo Instructions //===----------------------------------------------------------------------===// -let Predicates = [HasStdExtZbp, IsRV32] in { -def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>; -} // Predicates = [HasStdExtZbb, IsRV32] - -let Predicates = [HasStdExtZbp, IsRV64] in { -def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>; -} // Predicates = [HasStdExtZbb, IsRV64] - let Predicates = [HasStdExtZba, IsRV64] in { // NOTE: The 0.93 spec shows zext.w as an alias of pack/packw. It has been // changed to add.uw in a draft after 0.94. @@ -805,10 +813,10 @@ (and GPR:$rs1, 0x00FF)), (PACKH GPR:$rs1, GPR:$rs2)>; -let Predicates = [HasStdExtZbp, IsRV32] in -def : Pat<(and GPR:$rs, 0x0000FFFF), (PACK GPR:$rs, X0)>; -let Predicates = [HasStdExtZbp, IsRV64] in { -def : Pat<(and GPR:$rs, 0x000000000000FFFF), (PACKW GPR:$rs, X0)>; +let Predicates = [HasStdExtZbbOrZbp, IsRV32] in +def : Pat<(and GPR:$rs, 0x0000FFFF), (ZEXTH_RV32 GPR:$rs)>; +let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { +def : Pat<(and GPR:$rs, 0x000000000000FFFF), (ZEXTH_RV64 GPR:$rs)>; } let Predicates = [HasStdExtZbp, IsRV32] in { diff --git a/llvm/test/CodeGen/RISCV/rv32Zbb.ll b/llvm/test/CodeGen/RISCV/rv32Zbb.ll --- a/llvm/test/CodeGen/RISCV/rv32Zbb.ll +++ b/llvm/test/CodeGen/RISCV/rv32Zbb.ll @@ -917,3 +917,48 @@ %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true) ret i64 %abs } + +define i32 @zexth_i32(i32 %a) nounwind { +; RV32I-LABEL: zexth_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 16 +; RV32I-NEXT: addi a1, a1, -1 +; RV32I-NEXT: and a0, a0, a1 +; RV32I-NEXT: ret +; +; RV32IB-LABEL: zexth_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT: zext.h a0, a0 +; RV32IB-NEXT: ret +; +; RV32IBB-LABEL: zexth_i32: +; RV32IBB: # %bb.0: +; RV32IBB-NEXT: zext.h a0, a0 +; RV32IBB-NEXT: ret + %and = and i32 %a, 65535 + ret i32 %and +} + +define i64 @zexth_i64(i64 %a) nounwind { +; RV32I-LABEL: zexth_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 16 +; RV32I-NEXT: addi a1, a1, -1 +; RV32I-NEXT: and a0, a0, a1 +; RV32I-NEXT: mv a1, zero +; RV32I-NEXT: ret +; +; RV32IB-LABEL: zexth_i64: +; RV32IB: # %bb.0: +; RV32IB-NEXT: zext.h a0, a0 +; RV32IB-NEXT: mv a1, zero +; RV32IB-NEXT: ret +; +; RV32IBB-LABEL: zexth_i64: +; RV32IBB: # %bb.0: +; RV32IBB-NEXT: zext.h a0, a0 +; RV32IBB-NEXT: mv a1, zero +; RV32IBB-NEXT: ret + %and = and i64 %a, 65535 + ret i64 %and +} diff --git a/llvm/test/CodeGen/RISCV/rv64Zbb.ll b/llvm/test/CodeGen/RISCV/rv64Zbb.ll --- a/llvm/test/CodeGen/RISCV/rv64Zbb.ll +++ b/llvm/test/CodeGen/RISCV/rv64Zbb.ll @@ -777,3 +777,45 @@ %abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true) ret i64 %abs } + +define i32 @zexth_i32(i32 %a) nounwind { +; RV64I-LABEL: zexth_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a1, 16 +; RV64I-NEXT: addiw a1, a1, -1 +; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: zexth_i32: +; RV64IB: # %bb.0: +; RV64IB-NEXT: zext.h a0, a0 +; RV64IB-NEXT: ret +; +; RV64IBB-LABEL: zexth_i32: +; RV64IBB: # %bb.0: +; RV64IBB-NEXT: zext.h a0, a0 +; RV64IBB-NEXT: ret + %and = and i32 %a, 65535 + ret i32 %and +} + +define i64 @zexth_i64(i64 %a) nounwind { +; RV64I-LABEL: zexth_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a1, 16 +; RV64I-NEXT: addiw a1, a1, -1 +; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: zexth_i64: +; RV64IB: # %bb.0: +; RV64IB-NEXT: zext.h a0, a0 +; RV64IB-NEXT: ret +; +; RV64IBB-LABEL: zexth_i64: +; RV64IBB: # %bb.0: +; RV64IBB-NEXT: zext.h a0, a0 +; RV64IBB-NEXT: ret + %and = and i64 %a, 65535 + ret i64 %and +} diff --git a/llvm/test/MC/RISCV/rv32b-aliases-valid.s b/llvm/test/MC/RISCV/rv32b-aliases-valid.s --- a/llvm/test/MC/RISCV/rv32b-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv32b-aliases-valid.s @@ -19,7 +19,7 @@ # CHECK-S-OBJ: andi t0, t1, 255 zext.b x5, x6 -# CHECK-S-OBJ-NOALIAS: pack t0, t1, zero +# CHECK-S-OBJ-NOALIAS: zext.h t0, t1 # CHECK-S-OBJ: zext.h t0, t1 zext.h x5, x6 diff --git a/llvm/test/MC/RISCV/rv32zbb-valid.s b/llvm/test/MC/RISCV/rv32zbb-valid.s --- a/llvm/test/MC/RISCV/rv32zbb-valid.s +++ b/llvm/test/MC/RISCV/rv32zbb-valid.s @@ -6,10 +6,10 @@ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s # With Bitmanip base extension: -# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbb -show-encoding \ +# RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbb -riscv-no-aliases -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbb < %s \ -# RUN: | llvm-objdump --mattr=+experimental-zbb -d -r - \ +# RUN: | llvm-objdump --mattr=+experimental-zbb -M no-aliases -d -r - \ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s # CHECK-ASM-AND-OBJ: clz t0, t1 @@ -39,3 +39,6 @@ # CHECK-ASM-AND-OBJ: maxu t0, t1, t2 # CHECK-ASM: encoding: [0xb3,0x72,0x73,0x0a] maxu t0, t1, t2 +# CHECK-ASM-AND-OBJ: zext.h t0, t1 +# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08] +zext.h t0, t1 diff --git a/llvm/test/MC/RISCV/rv32zbp-valid.s b/llvm/test/MC/RISCV/rv32zbp-valid.s --- a/llvm/test/MC/RISCV/rv32zbp-valid.s +++ b/llvm/test/MC/RISCV/rv32zbp-valid.s @@ -3,14 +3,14 @@ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-b < %s \ # RUN: | llvm-objdump --mattr=+experimental-b -d -r - \ -# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s # With Bitmanip permutation extension: # RUN: llvm-mc %s -triple=riscv32 -mattr=+experimental-zbp -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+experimental-zbp < %s \ # RUN: | llvm-objdump --mattr=+experimental-zbp -d -r - \ -# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s # CHECK-ASM-AND-OBJ: slo t0, t1, t2 # CHECK-ASM: encoding: [0xb3,0x12,0x73,0x20] @@ -57,3 +57,10 @@ # CHECK-ASM-AND-OBJ: packh t0, t1, t2 # CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08] packh t0, t1, t2 +# CHECK-ASM-AND-OBJ: zext.h t0, t1 +# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08] +zext.h t0, t1 +# CHECK-ASM: pack t0, t1, zero +# CHECK-OBJ: zext.h t0, t1 +# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08] +pack t0, t1, x0 diff --git a/llvm/test/MC/RISCV/rv64b-aliases-valid.s b/llvm/test/MC/RISCV/rv64b-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64b-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64b-aliases-valid.s @@ -19,7 +19,7 @@ # CHECK-S-OBJ: andi t0, t1, 255 zext.b x5, x6 -# CHECK-S-OBJ-NOALIAS: packw t0, t1, zero +# CHECK-S-OBJ-NOALIAS: zext.h t0, t1 # CHECK-S-OBJ: zext.h t0, t1 zext.h x5, x6 diff --git a/llvm/test/MC/RISCV/rv64zbb-valid.s b/llvm/test/MC/RISCV/rv64zbb-valid.s --- a/llvm/test/MC/RISCV/rv64zbb-valid.s +++ b/llvm/test/MC/RISCV/rv64zbb-valid.s @@ -6,10 +6,10 @@ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s # With Bitmanip base extension: -# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbb -show-encoding \ +# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbb -riscv-no-aliases -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbb < %s \ -# RUN: | llvm-objdump --mattr=+experimental-zbb -d -r - \ +# RUN: | llvm-objdump --mattr=+experimental-zbb -M no-aliases -d -r - \ # RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s # CHECK-ASM-AND-OBJ: clzw t0, t1 @@ -21,3 +21,6 @@ # CHECK-ASM-AND-OBJ: cpopw t0, t1 # CHECK-ASM: encoding: [0x9b,0x12,0x23,0x60] cpopw t0, t1 +# CHECK-ASM-AND-OBJ: zext.h t0, t1 +# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08] +zext.h t0, t1 diff --git a/llvm/test/MC/RISCV/rv64zbp-valid.s b/llvm/test/MC/RISCV/rv64zbp-valid.s --- a/llvm/test/MC/RISCV/rv64zbp-valid.s +++ b/llvm/test/MC/RISCV/rv64zbp-valid.s @@ -3,14 +3,14 @@ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-b < %s \ # RUN: | llvm-objdump --mattr=+experimental-b -d -r - \ -# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s # With Bitmanip permutation extension: # RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zbp -show-encoding \ # RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s # RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zbp < %s \ # RUN: | llvm-objdump --mattr=+experimental-zbp -d -r - \ -# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s +# RUN: | FileCheck --check-prefixes=CHECK-OBJ,CHECK-ASM-AND-OBJ %s # CHECK-ASM-AND-OBJ: slow t0, t1, t2 # CHECK-ASM: encoding: [0xbb,0x12,0x73,0x20] @@ -48,3 +48,10 @@ # CHECK-ASM-AND-OBJ: packuw t0, t1, t2 # CHECK-ASM: encoding: [0xbb,0x42,0x73,0x48] packuw t0, t1, t2 +# CHECK-ASM-AND-OBJ: zext.h t0, t1 +# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08] +zext.h t0, t1 +# CHECK-ASM: packw t0, t1, zero +# CHECK-OBJ: zext.h t0, t1 +# CHECK-ASM: encoding: [0xbb,0x42,0x03,0x08] +packw t0, t1, x0