[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
This commit is contained in:
Craig Topper 2021-01-22 11:58:03 -08:00
parent 83c92fdeda
commit 3c94cee63b
10 changed files with 140 additions and 23 deletions

View File

@ -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",

View File

@ -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 {

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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