mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
[AArch64] Add isAuthenticated predicate to MCInstDesc
Add a predicate to MCInstDesc that allows tools to determine whether an instruction authenticates a pointer. This can be used by diagnostic tools to hint at pointer authentication failures. Differential Revision: https://reviews.llvm.org/D70329 rdar://55089604
This commit is contained in:
parent
f40d0a71d9
commit
ac509eb162
@ -176,6 +176,7 @@ enum Flag {
|
||||
Add,
|
||||
Trap,
|
||||
VariadicOpsAreDefs,
|
||||
Authenticated,
|
||||
};
|
||||
}
|
||||
|
||||
@ -416,6 +417,15 @@ public:
|
||||
return Flags & (1ULL << MCID::VariadicOpsAreDefs);
|
||||
}
|
||||
|
||||
/// Return true if this instruction authenticates a pointer (e.g. LDRAx/BRAx
|
||||
/// from ARMv8.3, which perform loads/branches with authentication).
|
||||
///
|
||||
/// An authenticated instruction may fail in an ABI-defined manner when
|
||||
/// operating on an invalid signed pointer.
|
||||
bool isAuthenticated() const {
|
||||
return Flags & (1ULL << MCID::Authenticated);
|
||||
}
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Side Effect Analysis
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -530,6 +530,7 @@ class Instruction : InstructionEncoding {
|
||||
bit hasCtrlDep = 0; // Does this instruction r/w ctrl-flow chains?
|
||||
bit isNotDuplicable = 0; // Is it unsafe to duplicate this instruction?
|
||||
bit isConvergent = 0; // Is this instruction convergent?
|
||||
bit isAuthenticated = 0; // Does this instruction authenticate a pointer?
|
||||
bit isAsCheapAsAMove = 0; // As cheap (or cheaper) than a move instruction.
|
||||
bit hasExtraSrcRegAllocReq = 0; // Sources have special regalloc requirement?
|
||||
bit hasExtraDefRegAllocReq = 0; // Defs have special regalloc requirement?
|
||||
|
@ -1483,6 +1483,7 @@ class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>
|
||||
class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,
|
||||
list<dag> pattern>
|
||||
: I<oops, iops, asm, operands, "", pattern>, Sched<[]> {
|
||||
let isAuthenticated = 1;
|
||||
let Inst{31-25} = 0b1101011;
|
||||
let Inst{20-11} = 0b1111100001;
|
||||
let Inst{10} = M;
|
||||
@ -1522,6 +1523,7 @@ class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,
|
||||
bits<10> offset;
|
||||
bits<5> Rn;
|
||||
bits<5> Rt;
|
||||
let isAuthenticated = 1;
|
||||
let Inst{31-24} = 0b11111000;
|
||||
let Inst{23} = M;
|
||||
let Inst{22} = offset{9};
|
||||
|
@ -819,20 +819,26 @@ let Predicates = [HasComplxNum, HasNEON] in {
|
||||
let Uses = [LR], Defs = [LR] in {
|
||||
def PACIAZ : SystemNoOperands<0b000, "paciaz">;
|
||||
def PACIBZ : SystemNoOperands<0b010, "pacibz">;
|
||||
def AUTIAZ : SystemNoOperands<0b100, "autiaz">;
|
||||
def AUTIBZ : SystemNoOperands<0b110, "autibz">;
|
||||
let isAuthenticated = 1 in {
|
||||
def AUTIAZ : SystemNoOperands<0b100, "autiaz">;
|
||||
def AUTIBZ : SystemNoOperands<0b110, "autibz">;
|
||||
}
|
||||
}
|
||||
let Uses = [LR, SP], Defs = [LR] in {
|
||||
def PACIASP : SystemNoOperands<0b001, "paciasp">;
|
||||
def PACIBSP : SystemNoOperands<0b011, "pacibsp">;
|
||||
def AUTIASP : SystemNoOperands<0b101, "autiasp">;
|
||||
def AUTIBSP : SystemNoOperands<0b111, "autibsp">;
|
||||
let isAuthenticated = 1 in {
|
||||
def AUTIASP : SystemNoOperands<0b101, "autiasp">;
|
||||
def AUTIBSP : SystemNoOperands<0b111, "autibsp">;
|
||||
}
|
||||
}
|
||||
let Uses = [X16, X17], Defs = [X17], CRm = 0b0001 in {
|
||||
def PACIA1716 : SystemNoOperands<0b000, "pacia1716">;
|
||||
def PACIB1716 : SystemNoOperands<0b010, "pacib1716">;
|
||||
def AUTIA1716 : SystemNoOperands<0b100, "autia1716">;
|
||||
def AUTIB1716 : SystemNoOperands<0b110, "autib1716">;
|
||||
let isAuthenticated = 1 in {
|
||||
def AUTIA1716 : SystemNoOperands<0b100, "autia1716">;
|
||||
def AUTIB1716 : SystemNoOperands<0b110, "autib1716">;
|
||||
}
|
||||
}
|
||||
|
||||
let Uses = [LR], Defs = [LR], CRm = 0b0000 in {
|
||||
|
@ -78,6 +78,38 @@ void runChecks(
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
TEST(InstSizes, Authenticated) {
|
||||
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
|
||||
ASSERT_TRUE(TM);
|
||||
std::unique_ptr<AArch64InstrInfo> II = createInstrInfo(TM.get());
|
||||
|
||||
auto isAuthInst = [](AArch64InstrInfo &II, MachineFunction &MF) {
|
||||
auto I = MF.begin()->begin();
|
||||
EXPECT_EQ(4u, II.getInstSizeInBytes(*I));
|
||||
EXPECT_TRUE(I->getDesc().isAuthenticated());
|
||||
};
|
||||
|
||||
runChecks(TM.get(), II.get(), "",
|
||||
" \n"
|
||||
" BLRAA $x10, $x9\n",
|
||||
isAuthInst);
|
||||
|
||||
runChecks(TM.get(), II.get(), "",
|
||||
" \n"
|
||||
" RETAB implicit $lr, implicit $sp, implicit killed $x0\n",
|
||||
isAuthInst);
|
||||
|
||||
runChecks(TM.get(), II.get(), "",
|
||||
" \n"
|
||||
" frame-destroy AUTIASP implicit-def $lr, implicit killed $lr, implicit $sp\n",
|
||||
isAuthInst);
|
||||
|
||||
runChecks(TM.get(), II.get(), "",
|
||||
" \n"
|
||||
" frame-destroy AUTIBSP implicit-def $lr, implicit killed $lr, implicit $sp\n",
|
||||
isAuthInst);
|
||||
}
|
||||
|
||||
TEST(InstSizes, STACKMAP) {
|
||||
std::unique_ptr<LLVMTargetMachine> TM = createTargetMachine();
|
||||
ASSERT_TRUE(TM);
|
||||
|
@ -396,6 +396,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R)
|
||||
hasNoSchedulingInfo = R->getValueAsBit("hasNoSchedulingInfo");
|
||||
FastISelShouldIgnore = R->getValueAsBit("FastISelShouldIgnore");
|
||||
variadicOpsAreDefs = R->getValueAsBit("variadicOpsAreDefs");
|
||||
isAuthenticated = R->getValueAsBit("isAuthenticated");
|
||||
|
||||
bool Unset;
|
||||
mayLoad = R->getValueAsBitOrUnset("mayLoad", Unset);
|
||||
|
@ -278,6 +278,7 @@ template <typename T> class ArrayRef;
|
||||
bool hasChain : 1;
|
||||
bool hasChain_Inferred : 1;
|
||||
bool variadicOpsAreDefs : 1;
|
||||
bool isAuthenticated : 1;
|
||||
|
||||
std::string DeprecatedReason;
|
||||
bool HasComplexDeprecationPredicate;
|
||||
|
@ -138,6 +138,7 @@ void EmitInstrDocs(RecordKeeper &RK, raw_ostream &OS) {
|
||||
FLAG(isConvergent)
|
||||
FLAG(hasNoSchedulingInfo)
|
||||
FLAG(variadicOpsAreDefs)
|
||||
FLAG(isAuthenticated)
|
||||
if (!FlagStrings.empty()) {
|
||||
OS << "Flags: ";
|
||||
bool IsFirst = true;
|
||||
|
@ -708,6 +708,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,
|
||||
if (Inst.isInsertSubreg) OS << "|(1ULL<<MCID::InsertSubreg)";
|
||||
if (Inst.isConvergent) OS << "|(1ULL<<MCID::Convergent)";
|
||||
if (Inst.variadicOpsAreDefs) OS << "|(1ULL<<MCID::VariadicOpsAreDefs)";
|
||||
if (Inst.isAuthenticated) OS << "|(1ULL<<MCID::Authenticated)";
|
||||
|
||||
// Emit all of the target-specific flags...
|
||||
BitsInit *TSF = Inst.TheDef->getValueAsBitsInit("TSFlags");
|
||||
|
Loading…
Reference in New Issue
Block a user