forked from OSchip/llvm-project
[RISCV] Add support for Zihintpause extention
Add support for the 'pause' hint instruction as an alias for 'fence w, 0'. To do this allow the 'fence' operands pred and succ to be set to 0 (the empty set). This will also allow future hints to be encoded as 'fence 0, <x>' and 'fence <x>, 0'. This patch revised from @mundaym's D93019. Reviewed By: asb Differential Revision: https://reviews.llvm.org/D117789
This commit is contained in:
parent
6f53960d64
commit
005fd8aa70
|
@ -48,6 +48,8 @@ static const RISCVSupportedExtension SupportedExtensions[] = {
|
|||
{"d", RISCVExtensionVersion{2, 0}},
|
||||
{"c", RISCVExtensionVersion{2, 0}},
|
||||
|
||||
{"zihintpause", RISCVExtensionVersion{2, 0}},
|
||||
|
||||
{"zfhmin", RISCVExtensionVersion{1, 0}},
|
||||
{"zfh", RISCVExtensionVersion{1, 0}},
|
||||
|
||||
|
|
|
@ -447,8 +447,16 @@ public:
|
|||
bool isFenceArg() const {
|
||||
if (!isImm())
|
||||
return false;
|
||||
const MCExpr *Val = getImm();
|
||||
auto *SVal = dyn_cast<MCSymbolRefExpr>(Val);
|
||||
|
||||
int64_t Imm;
|
||||
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
|
||||
if (evaluateConstantImm(getImm(), Imm, VK)) {
|
||||
// Only accept 0 as a constant immediate.
|
||||
return VK == RISCVMCExpr::VK_RISCV_None && Imm == 0;
|
||||
}
|
||||
|
||||
auto *SVal = dyn_cast<MCSymbolRefExpr>(getImm());
|
||||
|
||||
if (!SVal || SVal->getKind() != MCSymbolRefExpr::VK_None)
|
||||
return false;
|
||||
|
||||
|
@ -897,6 +905,17 @@ public:
|
|||
|
||||
void addFenceArgOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
|
||||
int64_t Constant = 0;
|
||||
RISCVMCExpr::VariantKind VK = RISCVMCExpr::VK_RISCV_None;
|
||||
if (evaluateConstantImm(getImm(), Constant, VK)) {
|
||||
if (Constant == 0) {
|
||||
Inst.addOperand(MCOperand::createImm(Constant));
|
||||
return;
|
||||
}
|
||||
llvm_unreachable("FenceArg must contain only [iorw] or be 0");
|
||||
}
|
||||
|
||||
// isFenceArg has validated the operand, meaning this cast is safe
|
||||
auto SE = cast<MCSymbolRefExpr>(getImm());
|
||||
|
||||
|
@ -904,7 +923,7 @@ public:
|
|||
for (char c : SE->getSymbol().getName()) {
|
||||
switch (c) {
|
||||
default:
|
||||
llvm_unreachable("FenceArg must contain only [iorw]");
|
||||
llvm_unreachable("FenceArg must contain only [iorw] or be 0");
|
||||
case 'i':
|
||||
Imm |= RISCVFenceField::I;
|
||||
break;
|
||||
|
@ -1208,9 +1227,8 @@ bool RISCVAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
|||
}
|
||||
case Match_InvalidFenceArg: {
|
||||
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
return Error(
|
||||
ErrorLoc,
|
||||
"operand must be formed of letters selected in-order from 'iorw'");
|
||||
return Error(ErrorLoc, "operand must be formed of letters selected "
|
||||
"in-order from 'iorw' or be 0");
|
||||
}
|
||||
case Match_InvalidFRMArg: {
|
||||
SMLoc ErrorLoc = ((RISCVOperand &)*Operands[ErrorInfo]).getStartLoc();
|
||||
|
|
|
@ -146,7 +146,7 @@ void RISCVInstPrinter::printFenceArg(const MCInst *MI, unsigned OpNo,
|
|||
if ((FenceArg & RISCVFenceField::W) != 0)
|
||||
O << 'w';
|
||||
if (FenceArg == 0)
|
||||
O << "unknown";
|
||||
O << "0";
|
||||
}
|
||||
|
||||
void RISCVInstPrinter::printFRMArg(const MCInst *MI, unsigned OpNo,
|
||||
|
|
|
@ -41,6 +41,13 @@ def HasStdExtD : Predicate<"Subtarget->hasStdExtD()">,
|
|||
AssemblerPredicate<(all_of FeatureStdExtD),
|
||||
"'D' (Double-Precision Floating-Point)">;
|
||||
|
||||
def FeatureStdExtZihintpause
|
||||
: SubtargetFeature<"zihintpause", "HasStdExtZihintpause", "true",
|
||||
"'zihintpause' (Pause Hint)">;
|
||||
def HasStdExtZihintpause : Predicate<"Subtarget->hasStdExtZihintpause()">,
|
||||
AssemblerPredicate<(all_of FeatureStdExtZihintpause),
|
||||
"'Zihintpause' (Pause Hint)">;
|
||||
|
||||
def FeatureStdExtZfhmin
|
||||
: SubtargetFeature<"zfhmin", "HasStdExtZfhmin", "true",
|
||||
"'Zfhmin' (Half-Precision Floating-Point Minimal)",
|
||||
|
|
|
@ -799,6 +799,9 @@ def : InstAlias<"jalr $rd, $rs, $offset", (JALR GPR:$rd, GPR:$rs, simm12:$offset
|
|||
|
||||
def : InstAlias<"fence", (FENCE 0xF, 0xF)>; // 0xF == iorw
|
||||
|
||||
let Predicates = [HasStdExtZihintpause] in
|
||||
def : InstAlias<"pause", (FENCE 0x1, 0x0)>; // 0x1 == w
|
||||
|
||||
def : InstAlias<"rdinstret $rd", (CSRRS GPR:$rd, INSTRET.Encoding, X0)>;
|
||||
def : InstAlias<"rdcycle $rd", (CSRRS GPR:$rd, CYCLE.Encoding, X0)>;
|
||||
def : InstAlias<"rdtime $rd", (CSRRS GPR:$rd, TIME.Encoding, X0)>;
|
||||
|
|
|
@ -65,6 +65,7 @@ private:
|
|||
bool HasStdExtF = false;
|
||||
bool HasStdExtD = false;
|
||||
bool HasStdExtC = false;
|
||||
bool HasStdExtZihintpause = false;
|
||||
bool HasStdExtZba = false;
|
||||
bool HasStdExtZbb = false;
|
||||
bool HasStdExtZbc = false;
|
||||
|
@ -157,6 +158,7 @@ public:
|
|||
bool hasStdExtD() const { return HasStdExtD; }
|
||||
bool hasStdExtC() const { return HasStdExtC; }
|
||||
bool hasStdExtV() const { return HasStdExtV; }
|
||||
bool hasStdExtZihintpause() const { return HasStdExtZihintpause; }
|
||||
bool hasStdExtZba() const { return HasStdExtZba; }
|
||||
bool hasStdExtZbb() const { return HasStdExtZbb; }
|
||||
bool hasStdExtZbc() const { return HasStdExtZbc; }
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
; RUN: llc -mtriple=riscv32 -mattr=+f %s -o - | FileCheck --check-prefix=RV32F %s
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+d %s -o - | FileCheck --check-prefix=RV32D %s
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+c %s -o - | FileCheck --check-prefix=RV32C %s
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zihintpause %s -o - | FileCheck --check-prefix=RV32ZIHINTPAUSE %s
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zfhmin %s -o - | FileCheck --check-prefix=RV32ZFHMIN %s
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zfh %s -o - | FileCheck --check-prefix=RV32ZFH %s
|
||||
; RUN: llc -mtriple=riscv32 -mattr=+zba %s -o - | FileCheck --check-prefix=RV32ZBA %s
|
||||
|
@ -37,6 +38,7 @@
|
|||
; RUN: llc -mtriple=riscv64 -mattr=+f %s -o - | FileCheck --check-prefix=RV64F %s
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+d %s -o - | FileCheck --check-prefix=RV64D %s
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+c %s -o - | FileCheck --check-prefix=RV64C %s
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zihintpause %s -o - | FileCheck --check-prefix=RV64ZIHINTPAUSE %s
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zfhmin %s -o - | FileCheck --check-prefix=RV64ZFHMIN %s
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zfh %s -o - | FileCheck --check-prefix=RV64ZFH %s
|
||||
; RUN: llc -mtriple=riscv64 -mattr=+zba %s -o - | FileCheck --check-prefix=RV64ZBA %s
|
||||
|
@ -70,6 +72,7 @@
|
|||
; RV32F: .attribute 5, "rv32i2p0_f2p0"
|
||||
; RV32D: .attribute 5, "rv32i2p0_f2p0_d2p0"
|
||||
; RV32C: .attribute 5, "rv32i2p0_c2p0"
|
||||
; RV32ZIHINTPAUSE: .attribute 5, "rv32i2p0_zihintpause2p0"
|
||||
; RV32ZFHMIN: .attribute 5, "rv32i2p0_f2p0_zfhmin1p0"
|
||||
; RV32ZFH: .attribute 5, "rv32i2p0_f2p0_zfh1p0"
|
||||
; RV32ZBA: .attribute 5, "rv32i2p0_zba1p0"
|
||||
|
@ -103,6 +106,7 @@
|
|||
; RV64F: .attribute 5, "rv64i2p0_f2p0"
|
||||
; RV64D: .attribute 5, "rv64i2p0_f2p0_d2p0"
|
||||
; RV64C: .attribute 5, "rv64i2p0_c2p0"
|
||||
; RV64ZIHINTPAUSE: .attribute 5, "rv64i2p0_zihintpause2p0"
|
||||
; RV64ZFHMIN: .attribute 5, "rv64i2p0_f2p0_zfhmin1p0"
|
||||
; RV64ZFH: .attribute 5, "rv64i2p0_f2p0_zfh1p0"
|
||||
; RV64ZBA: .attribute 5, "rv64i2p0_zba1p0"
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# RUN: llvm-mc -disassemble -triple=riscv32 < %s 2>&1 | FileCheck %s
|
||||
# RUN: llvm-mc -disassemble -triple=riscv64 < %s 2>&1 | FileCheck %s
|
||||
#
|
||||
# Test generated by a LLVM MC Disassembler Protocol Buffer Fuzzer
|
||||
# for the RISC-V assembly language.
|
||||
|
||||
# This decodes as fence , iorw with invalid fence field as 0.
|
||||
[0x0f 0x00 0xf0 0x00]
|
||||
# CHECK: fence unknown, iorw
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
# Out of range immediates
|
||||
## fencearg
|
||||
fence iorw, iore # CHECK: :[[@LINE]]:13: error: operand must be formed of letters selected in-order from 'iorw'
|
||||
fence wr, wr # CHECK: :[[@LINE]]:7: error: operand must be formed of letters selected in-order from 'iorw'
|
||||
fence rw, rr # CHECK: :[[@LINE]]:11: error: operand must be formed of letters selected in-order from 'iorw'
|
||||
fence 1, rw # CHECK: :[[@LINE]]:7: error: operand must be formed of letters selected in-order from 'iorw'
|
||||
fence unknown, unknown # CHECK: :[[@LINE]]:7: error: operand must be formed of letters selected in-order from 'iorw'
|
||||
fence iorw, iore # CHECK: :[[@LINE]]:13: error: operand must be formed of letters selected in-order from 'iorw' or be 0
|
||||
fence wr, wr # CHECK: :[[@LINE]]:7: error: operand must be formed of letters selected in-order from 'iorw' or be 0
|
||||
fence rw, rr # CHECK: :[[@LINE]]:11: error: operand must be formed of letters selected in-order from 'iorw' or be 0
|
||||
fence 1, rw # CHECK: :[[@LINE]]:7: error: operand must be formed of letters selected in-order from 'iorw' or be 0
|
||||
fence unknown, unknown # CHECK: :[[@LINE]]:7: error: operand must be formed of letters selected in-order from 'iorw' or be 0
|
||||
|
||||
## uimm5
|
||||
slli a0, a0, 32 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31]
|
||||
|
@ -177,6 +177,7 @@ sh1add a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the followi
|
|||
clz a0, a1 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbb' (Basic Bit-Manipulation)
|
||||
clmul a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbc' (Carry-Less Multiplication)
|
||||
bset a0, a1, a2 # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zbs' (Single-Bit Instructions)
|
||||
pause # CHECK: :[[@LINE]]:1: error: instruction requires the following: 'Zihintpause' (Pause Hint)
|
||||
|
||||
# Using floating point registers when integer registers are expected
|
||||
addi a2, ft0, 24 # CHECK: :[[@LINE]]:10: error: invalid operand for instruction
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zihintpause -riscv-no-aliases -show-encoding \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zihintpause -riscv-no-aliases -show-encoding \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-ASM,CHECK-ASM-AND-OBJ %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv32 -mattr=+zihintpause < %s \
|
||||
# RUN: | llvm-objdump --mattr=+zihintpause -M no-aliases -d -r - \
|
||||
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
|
||||
# RUN: llvm-mc -filetype=obj -triple=riscv64 -mattr=+zihintpause < %s \
|
||||
# RUN: | llvm-objdump --mattr=+zihintpause -M no-aliases -d -r - \
|
||||
# RUN: | FileCheck --check-prefix=CHECK-ASM-AND-OBJ %s
|
||||
|
||||
# CHECK-ASM-AND-OBJ: fence w, 0
|
||||
# CHECK-ASM: encoding: [0x0f,0x00,0x00,0x01]
|
||||
fence w,0
|
||||
# CHECK-ASM-AND-OBJ: fence 0, w
|
||||
# CHECK-ASM: encoding: [0x0f,0x00,0x10,0x00]
|
||||
fence 0,w
|
||||
# CHECK-ASM-AND-OBJ: fence 0, 0
|
||||
# CHECK-ASM: encoding: [0x0f,0x00,0x00,0x00]
|
||||
fence 0,0
|
|
@ -0,0 +1,24 @@
|
|||
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zihintpause -M no-aliases \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
|
||||
# RUN: llvm-mc %s -triple=riscv32 -mattr=+zihintpause \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zihintpause -M no-aliases \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
|
||||
# RUN: llvm-mc %s -triple=riscv64 -mattr=+zihintpause \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zihintpause < %s \
|
||||
# RUN: | llvm-objdump --mattr=+zihintpause -d -r -M no-aliases - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv32 -mattr=+zihintpause < %s \
|
||||
# RUN: | llvm-objdump --mattr=+zihintpause -d -r - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zihintpause < %s \
|
||||
# RUN: | llvm-objdump --mattr=+zihintpause -d -r -M no-aliases - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ-NOALIAS %s
|
||||
# RUN: llvm-mc -filetype=obj -triple riscv64 -mattr=+zihintpause < %s \
|
||||
# RUN: | llvm-objdump --mattr=+zihintpause -d -r - \
|
||||
# RUN: | FileCheck -check-prefixes=CHECK-S-OBJ %s
|
||||
|
||||
# CHECK-S-OBJ-NOALIAS: fence w, 0
|
||||
# CHECK-S-OBJ: pause
|
||||
pause
|
Loading…
Reference in New Issue