[RISCV] Add Zba feature and move add.uw and slli.uw to it.

Still need to add SH*ADD instructions.

Reviewed By: asb, frasercrmck

Differential Revision: https://reviews.llvm.org/D94617
This commit is contained in:
Craig Topper 2021-01-22 10:58:06 -08:00
parent b825278364
commit 4e6ad11bc6
11 changed files with 163 additions and 123 deletions

View File

@ -58,9 +58,9 @@ static StringRef getExtensionType(StringRef Ext) {
// extension that the compiler currently supports.
static Optional<RISCVExtensionVersion>
isExperimentalExtension(StringRef Ext) {
if (Ext == "b" || Ext == "zbb" || Ext == "zbc" || Ext == "zbe" ||
Ext == "zbf" || Ext == "zbm" || Ext == "zbp" || Ext == "zbr" ||
Ext == "zbs" || Ext == "zbt" || Ext == "zbproposedc")
if (Ext == "b" || Ext == "zba" || Ext == "zbb" || Ext == "zbc" ||
Ext == "zbe" || Ext == "zbf" || Ext == "zbm" || Ext == "zbp" ||
Ext == "zbr" || Ext == "zbs" || Ext == "zbt" || Ext == "zbproposedc")
return RISCVExtensionVersion{"0", "92"};
if (Ext == "v")
return RISCVExtensionVersion{"0", "9"};

View File

@ -365,6 +365,10 @@
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBB-ZBP-UNDERSCORE %s
// RV32-EXPERIMENTAL-ZBB-ZBP-UNDERSCORE: error: invalid arch name 'rv32izbb0p92zbp0p92', multi-character extensions must be separated by underscores
// RUN: %clang -target riscv32-unknown-elf -march=rv32izba0p92 -menable-experimental-extensions -### %s \
// RUN: -fsyntax-only 2>&1 | FileCheck -check-prefix=RV32-EXPERIMENTAL-ZBA %s
// RV32-EXPERIMENTAL-ZBA: "-target-feature" "+experimental-zba"
// RUN: %clang -target riscv32-unknown-elf -march=rv32iv -### %s -c 2>&1 | \
// RUN: FileCheck -check-prefix=RV32-EXPERIMENTAL-V-NOFLAG %s
// RV32-EXPERIMENTAL-V-NOFLAG: error: invalid arch name 'rv32iv'

View File

@ -56,6 +56,13 @@ def HasStdExtC : Predicate<"Subtarget->hasStdExtC()">,
AssemblerPredicate<(all_of FeatureStdExtC),
"'C' (Compressed Instructions)">;
def FeatureExtZba
: SubtargetFeature<"experimental-zba", "HasStdExtZba", "true",
"'Zba' (Base 'B' Instructions)">;
def HasStdExtZba : Predicate<"Subtarget->hasStdExtZba()">,
AssemblerPredicate<(all_of FeatureExtZba),
"'Zba' (Address calculation 'B' Instructions)">;
def FeatureExtZbb
: SubtargetFeature<"experimental-zbb", "HasStdExtZbb", "true",
"'Zbb' (Base 'B' Instructions)">;
@ -137,7 +144,8 @@ def HasStdExtZbproposedc : Predicate<"Subtarget->hasStdExtZbproposedc()">,
def FeatureStdExtB
: SubtargetFeature<"experimental-b", "HasStdExtB", "true",
"'B' (Bit Manipulation Instructions)",
[FeatureExtZbb,
[FeatureExtZba,
FeatureExtZbb,
FeatureExtZbc,
FeatureExtZbe,
FeatureExtZbf,

View File

@ -369,7 +369,7 @@ def SHFLI : RVBShfl_ri<0b000010, 0b001, OPC_OP_IMM, "shfli">, Sched<[]>;
def UNSHFLI : RVBShfl_ri<0b000010, 0b101, OPC_OP_IMM, "unshfli">, Sched<[]>;
} // Predicates = [HasStdExtZbp]
let Predicates = [HasStdExtZbb, IsRV64] in {
let Predicates = [HasStdExtZba, IsRV64] in {
def SLLIUW : RVBShift_ri<0b00001, 0b001, OPC_OP_IMM_32, "slli.uw">, Sched<[]>;
def ADDUW : ALUW_rr<0b0000100, 0b000, "add.uw">, Sched<[]>;
} // Predicates = [HasStdExtZbb, IsRV64]
@ -838,13 +838,16 @@ def : Pat<(or (or (and (shl GPR:$rs1, (i64 1)), (i64 0x4444444444444444)),
(SHFLI GPR:$rs1, (i64 1))>;
} // Predicates = [HasStdExtZbp, IsRV64]
let Predicates = [HasStdExtZbb, IsRV64] in {
let Predicates = [HasStdExtZba, IsRV64] in {
def : Pat<(SLLIUWPat GPR:$rs1, uimm5:$shamt),
(SLLIUW GPR:$rs1, uimm5:$shamt)>;
def : Pat<(shl (and GPR:$rs1, 0xFFFFFFFF), uimm5:$shamt),
(SLLIUW GPR:$rs1, uimm5:$shamt)>;
def : Pat<(add GPR:$rs1, (and GPR:$rs2, (i64 0xFFFFFFFF))),
(ADDUW GPR:$rs1, GPR:$rs2)>;
}
let Predicates = [HasStdExtZbb, IsRV64] in {
def : Pat<(not (riscv_sllw (not GPR:$rs1), GPR:$rs2)),
(SLOW GPR:$rs1, GPR:$rs2)>;
def : Pat<(not (riscv_srlw (not GPR:$rs1), GPR:$rs2)),

View File

@ -40,6 +40,7 @@ class RISCVSubtarget : public RISCVGenSubtargetInfo {
bool HasStdExtD = false;
bool HasStdExtC = false;
bool HasStdExtB = false;
bool HasStdExtZba = false;
bool HasStdExtZbb = false;
bool HasStdExtZbc = false;
bool HasStdExtZbe = false;
@ -106,6 +107,7 @@ public:
bool hasStdExtD() const { return HasStdExtD; }
bool hasStdExtC() const { return HasStdExtC; }
bool hasStdExtB() const { return HasStdExtB; }
bool hasStdExtZba() const { return HasStdExtZba; }
bool hasStdExtZbb() const { return HasStdExtZbb; }
bool hasStdExtZbc() const { return HasStdExtZbc; }
bool hasStdExtZbe() const { return HasStdExtZbe; }

View File

@ -0,0 +1,111 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV64I
; RUN: llc -mtriple=riscv64 -mattr=+experimental-b -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV64IB
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zba -verify-machineinstrs < %s \
; RUN: | FileCheck %s -check-prefix=RV64IBA
define i64 @slliuw(i64 %a) nounwind {
; RV64I-LABEL: slliuw:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 1
; RV64I-NEXT: addi a1, zero, 1
; RV64I-NEXT: slli a1, a1, 33
; RV64I-NEXT: addi a1, a1, -2
; RV64I-NEXT: and a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IB-LABEL: slliuw:
; RV64IB: # %bb.0:
; RV64IB-NEXT: slli.uw a0, a0, 1
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: slliuw:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: slli.uw a0, a0, 1
; RV64IBA-NEXT: ret
%conv1 = shl i64 %a, 1
%shl = and i64 %conv1, 8589934590
ret i64 %shl
}
define i128 @slliuw_2(i32 signext %0, i128* %1) {
; RV64I-LABEL: slliuw_2:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: slli a0, a0, 4
; RV64I-NEXT: add a1, a1, a0
; RV64I-NEXT: ld a0, 0(a1)
; RV64I-NEXT: ld a1, 8(a1)
; RV64I-NEXT: ret
;
; RV64IB-LABEL: slliuw_2:
; RV64IB: # %bb.0:
; RV64IB-NEXT: slli.uw a0, a0, 4
; RV64IB-NEXT: add a1, a1, a0
; RV64IB-NEXT: ld a0, 0(a1)
; RV64IB-NEXT: ld a1, 8(a1)
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: slliuw_2:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: slli.uw a0, a0, 4
; RV64IBA-NEXT: add a1, a1, a0
; RV64IBA-NEXT: ld a0, 0(a1)
; RV64IBA-NEXT: ld a1, 8(a1)
; RV64IBA-NEXT: ret
%3 = zext i32 %0 to i64
%4 = getelementptr inbounds i128, i128* %1, i64 %3
%5 = load i128, i128* %4
ret i128 %5
}
define i64 @adduw(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: adduw:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: srli a1, a1, 32
; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: adduw:
; RV64IB: # %bb.0:
; RV64IB-NEXT: add.uw a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: adduw:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: add.uw a0, a0, a1
; RV64IBA-NEXT: ret
%and = and i64 %b, 4294967295
%add = add i64 %and, %a
ret i64 %add
}
define signext i8 @adduw_2(i32 signext %0, i8* %1) {
; RV64I-LABEL: adduw_2:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: lb a0, 0(a0)
; RV64I-NEXT: ret
;
; RV64IB-LABEL: adduw_2:
; RV64IB: # %bb.0:
; RV64IB-NEXT: add.uw a0, a1, a0
; RV64IB-NEXT: lb a0, 0(a0)
; RV64IB-NEXT: ret
;
; RV64IBA-LABEL: adduw_2:
; RV64IBA: # %bb.0:
; RV64IBA-NEXT: add.uw a0, a1, a0
; RV64IBA-NEXT: lb a0, 0(a0)
; RV64IBA-NEXT: ret
%3 = zext i32 %0 to i64
%4 = getelementptr inbounds i8, i8* %1, i64 %3
%5 = load i8, i8* %4
ret i8 %5
}

View File

@ -987,107 +987,3 @@ define i64 @abs_i64(i64 %x) {
%abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
ret i64 %abs
}
define i64 @slliuw(i64 %a) nounwind {
; RV64I-LABEL: slliuw:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 1
; RV64I-NEXT: addi a1, zero, 1
; RV64I-NEXT: slli a1, a1, 33
; RV64I-NEXT: addi a1, a1, -2
; RV64I-NEXT: and a0, a0, a1
; RV64I-NEXT: ret
;
; RV64IB-LABEL: slliuw:
; RV64IB: # %bb.0:
; RV64IB-NEXT: slli.uw a0, a0, 1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: slliuw:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: slli.uw a0, a0, 1
; RV64IBB-NEXT: ret
%conv1 = shl i64 %a, 1
%shl = and i64 %conv1, 8589934590
ret i64 %shl
}
define i128 @slliuw_2(i32 signext %0, i128* %1) {
; RV64I-LABEL: slliuw_2:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: slli a0, a0, 4
; RV64I-NEXT: add a1, a1, a0
; RV64I-NEXT: ld a0, 0(a1)
; RV64I-NEXT: ld a1, 8(a1)
; RV64I-NEXT: ret
;
; RV64IB-LABEL: slliuw_2:
; RV64IB: # %bb.0:
; RV64IB-NEXT: slli.uw a0, a0, 4
; RV64IB-NEXT: add a1, a1, a0
; RV64IB-NEXT: ld a0, 0(a1)
; RV64IB-NEXT: ld a1, 8(a1)
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: slliuw_2:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: slli.uw a0, a0, 4
; RV64IBB-NEXT: add a1, a1, a0
; RV64IBB-NEXT: ld a0, 0(a1)
; RV64IBB-NEXT: ld a1, 8(a1)
; RV64IBB-NEXT: ret
%3 = zext i32 %0 to i64
%4 = getelementptr inbounds i128, i128* %1, i64 %3
%5 = load i128, i128* %4
ret i128 %5
}
define i64 @adduw(i64 %a, i64 %b) nounwind {
; RV64I-LABEL: adduw:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a1, a1, 32
; RV64I-NEXT: srli a1, a1, 32
; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: ret
;
; RV64IB-LABEL: adduw:
; RV64IB: # %bb.0:
; RV64IB-NEXT: add.uw a0, a0, a1
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: adduw:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: add.uw a0, a0, a1
; RV64IBB-NEXT: ret
%and = and i64 %b, 4294967295
%add = add i64 %and, %a
ret i64 %add
}
define signext i8 @adduw_2(i32 signext %0, i8* %1) {
; RV64I-LABEL: adduw_2:
; RV64I: # %bb.0:
; RV64I-NEXT: slli a0, a0, 32
; RV64I-NEXT: srli a0, a0, 32
; RV64I-NEXT: add a0, a1, a0
; RV64I-NEXT: lb a0, 0(a0)
; RV64I-NEXT: ret
;
; RV64IB-LABEL: adduw_2:
; RV64IB: # %bb.0:
; RV64IB-NEXT: add.uw a0, a1, a0
; RV64IB-NEXT: lb a0, 0(a0)
; RV64IB-NEXT: ret
;
; RV64IBB-LABEL: adduw_2:
; RV64IBB: # %bb.0:
; RV64IBB-NEXT: add.uw a0, a1, a0
; RV64IBB-NEXT: lb a0, 0(a0)
; RV64IBB-NEXT: ret
%3 = zext i32 %0 to i64
%4 = getelementptr inbounds i8, i8* %1, i64 %3
%5 = load i8, i8* %4
ret i8 %5
}

View File

@ -0,0 +1,9 @@
# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zba < %s 2>&1 | FileCheck %s
# Too few operands
slli.uw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Immediate operand out of range
slli.uw t0, t1, 64 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 63]
slli.uw t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 63]
# Too few operands
add.uw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction

View File

@ -0,0 +1,20 @@
# With B extension:
# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-b -show-encoding \
# 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
# With Bitmanip base extension:
# RUN: llvm-mc %s -triple=riscv64 -mattr=+experimental-zba -show-encoding \
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+experimental-zba < %s \
# RUN: | llvm-objdump --mattr=+experimental-zba -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# CHECK-ASM-AND-OBJ: slli.uw t0, t1, 0
# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x08]
slli.uw t0, t1, 0
# CHECK-ASM-AND-OBJ: add.uw t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x02,0x73,0x08]
add.uw t0, t1, t2

View File

@ -1,12 +1,5 @@
# RUN: not llvm-mc -triple riscv64 -mattr=+experimental-b,experimental-zbb < %s 2>&1 | FileCheck %s
# Too few operands
slli.uw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Immediate operand out of range
slli.uw t0, t1, 64 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 63]
slli.uw t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 63]
# Too few operands
add.uw t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Too few operands
slow t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction
# Too few operands

View File

@ -12,12 +12,6 @@
# RUN: | llvm-objdump --mattr=+experimental-zbb -d -r - \
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
# CHECK-ASM-AND-OBJ: slli.uw t0, t1, 0
# CHECK-ASM: encoding: [0x9b,0x12,0x03,0x08]
slli.uw t0, t1, 0
# CHECK-ASM-AND-OBJ: add.uw t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x02,0x73,0x08]
add.uw t0, t1, t2
# CHECK-ASM-AND-OBJ: slow t0, t1, t2
# CHECK-ASM: encoding: [0xbb,0x12,0x73,0x20]
slow t0, t1, t2