From 3c94cee63b401ca12457395bb1f4d70e161f9ec4 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Fri, 22 Jan 2021 11:58:03 -0800 Subject: [PATCH] [RISCV] Add zext.h instruction to Zbb. zext.h uses the same encoding as pack rd, rs, x0 in rv32 and packw rd, rs, x0 in rv64. Encodings without x0 as the second source are not valid in Zbb. I've added two new instructions with these specific encodings with predicates that enable them when either Zbb or Zbp is enabled. The pack spelling will only be accepted with Zbp. The disassembler will use the zext.h instruction when either feature is enabled. Using the pack spelling will print as pack when llvm-mc is emitting text. We could fix this with some custom code in processInstruction if this is important, but I'm not sure it is. Reviewed By: asb, frasercrmck Differential Revision: https://reviews.llvm.org/D94818 --- llvm/lib/Target/RISCV/RISCV.td | 4 ++- llvm/lib/Target/RISCV/RISCVInstrInfoB.td | 32 ++++++++++++++--------- llvm/test/CodeGen/RISCV/rv32Zbb.ll | 45 ++++++++++++++++++++++++++++++++ llvm/test/CodeGen/RISCV/rv64Zbb.ll | 42 +++++++++++++++++++++++++++++ llvm/test/MC/RISCV/rv32b-aliases-valid.s | 2 +- llvm/test/MC/RISCV/rv32zbb-valid.s | 7 +++-- llvm/test/MC/RISCV/rv32zbp-valid.s | 11 ++++++-- llvm/test/MC/RISCV/rv64b-aliases-valid.s | 2 +- llvm/test/MC/RISCV/rv64zbb-valid.s | 7 +++-- llvm/test/MC/RISCV/rv64zbp-valid.s | 11 ++++++-- 10 files changed, 140 insertions(+), 23 deletions(-) diff --git a/llvm/lib/Target/RISCV/RISCV.td b/llvm/lib/Target/RISCV/RISCV.td index 8f83b16..a17abd0 100644 --- a/llvm/lib/Target/RISCV/RISCV.td +++ b/llvm/lib/Target/RISCV/RISCV.td @@ -131,7 +131,9 @@ def HasStdExtZbt : Predicate<"Subtarget->hasStdExtZbt()">, // 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 index 120a47c..7466097 100644 --- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td @@ -465,6 +465,22 @@ def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>; 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 @@ def C_ZEXTW : RVBInstC<0b10, "c.zext.w">, Sched<[]>; // 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 @@ def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFF00), (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 index 8d03d73..8d773d2 100644 --- a/llvm/test/CodeGen/RISCV/rv32Zbb.ll +++ b/llvm/test/CodeGen/RISCV/rv32Zbb.ll @@ -917,3 +917,48 @@ define i64 @abs_i64(i64 %x) { %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 index 5c34f41..5fd8135 100644 --- a/llvm/test/CodeGen/RISCV/rv64Zbb.ll +++ b/llvm/test/CodeGen/RISCV/rv64Zbb.ll @@ -777,3 +777,45 @@ define i64 @abs_i64(i64 %x) { %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 index 9ff9a5f..a291c38 100644 --- 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 index dd8a4a4..28c3843 100644 --- 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 @@ max t0, t1, t2 # 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 index d791ebe..270c8e2 100644 --- 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 @@ packu t0, t1, t2 # 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 index 4b58c3b..eb9b7b6 100644 --- 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 index 6d43895..c2809ea 100644 --- 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 @@ ctzw t0, t1 # 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 index af0ab74..9a6cca1 100644 --- 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 @@ packw t0, t1, t2 # 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 -- 2.7.4