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 @@ -106,6 +106,8 @@ def HasStdExtZbp : Predicate<"Subtarget->hasStdExtZbp()">, AssemblerPredicate<(all_of FeatureExtZbp), "'Zbp' (Permutation 'B' Instructions)">; +def NotHasStdExtZbp : Predicate<"!Subtarget->hasStdExtZbp()">, + AssemblerPredicate<(all_of (not FeatureExtZbp))>; def FeatureExtZbr : SubtargetFeature<"experimental-zbr", "HasStdExtZbr", "true", @@ -133,6 +135,9 @@ def HasStdExtZbbOrZbp : Predicate<"Subtarget->hasStdExtZbb() || Subtarget->hasStdExtZbp()">, AssemblerPredicate<(any_of FeatureExtZbb, FeatureExtZbp)>; +def HasStdExtZbbAndNotZbp + : Predicate<"Subtarget->hasStdExtZbb() && !Subtarget->hasStdExtZbp()">, + AssemblerPredicate<(all_of FeatureExtZbb, (not FeatureExtZbp))>; 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 @@ -461,6 +461,22 @@ let Predicates = [HasStdExtZbf, IsRV64] in def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>; +let Predicates = [HasStdExtZbb, NotHasStdExtZbp, 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 = [HasStdExtZbb, NotHasStdExtZbp, IsRV64] + +let Predicates = [HasStdExtZbb, NotHasStdExtZbp, 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 = [HasStdExtZbb, NotHasStdExtZbp, IsRV64] + //===----------------------------------------------------------------------===// // Future compressed instructions //===----------------------------------------------------------------------===// @@ -869,6 +885,12 @@ def : Pat<(and GPR:$rs, 0x000000000000FFFF), (PACKW GPR:$rs, X0)>; } +let Predicates = [HasStdExtZbb, NotHasStdExtZbp, IsRV32] in +def : Pat<(and GPR:$rs, 0x0000FFFF), (ZEXTH_RV32 GPR:$rs)>; +let Predicates = [HasStdExtZbb, NotHasStdExtZbp, IsRV64] in { +def : Pat<(and GPR:$rs, 0x000000000000FFFF), (ZEXTH_RV64 GPR:$rs)>; +} + let Predicates = [HasStdExtZbp, IsRV32] in { def : Pat<(or (or (and (shl GPR:$rs1, (i32 8)), (i32 0x00FF0000)), (and GPR:$rs1, (i32 0xFF0000FF))), 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 @@ -952,3 +952,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/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 +# CHECK-ASM: encoding: [0xb3,0x42,0x03,0x08] +zext.h t0, t1 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