mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 13:37:07 +00:00
[AArch64][ARM] Armv8.4-A: Trace synchronization barrier instruction
This adds the Armv8.4-A Trace synchronization barrier (TSB) instruction. Differential Revision: https://reviews.llvm.org/D48918 llvm-svn: 336418
This commit is contained in:
parent
70ff6138f8
commit
c3b59a654a
@ -20,6 +20,8 @@ def HasV8_2a : Predicate<"Subtarget->hasV8_2aOps()">,
|
||||
AssemblerPredicate<"HasV8_2aOps", "armv8.2a">;
|
||||
def HasV8_3a : Predicate<"Subtarget->hasV8_3aOps()">,
|
||||
AssemblerPredicate<"HasV8_3aOps", "armv8.3a">;
|
||||
def HasV8_4a : Predicate<"Subtarget->hasV8_4aOps()">,
|
||||
AssemblerPredicate<"HasV8_4aOps", "armv8.4a">;
|
||||
def HasFPARMv8 : Predicate<"Subtarget->hasFPARMv8()">,
|
||||
AssemblerPredicate<"FeatureFPARMv8", "fp-armv8">;
|
||||
def HasNEON : Predicate<"Subtarget->hasNEON()">,
|
||||
@ -449,6 +451,12 @@ def DSB : CRmSystemI<barrier_op, 0b100, "dsb",
|
||||
|
||||
def ISB : CRmSystemI<barrier_op, 0b110, "isb",
|
||||
[(int_aarch64_isb (i32 imm32_0_15:$CRm))]>;
|
||||
|
||||
def TSB : CRmSystemI<barrier_op, 0b010, "tsb", []> {
|
||||
let CRm = 0b0010;
|
||||
let Inst{12} = 0;
|
||||
let Predicates = [HasV8_4a];
|
||||
}
|
||||
}
|
||||
|
||||
// ARMv8.2 Dot Product
|
||||
|
@ -142,6 +142,23 @@ class ISB<string name, bits<4> encoding> : SearchableTable{
|
||||
|
||||
def : ISB<"sy", 0xf>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TSB (Trace synchronization barrier) instruction options.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class TSB<string name, bits<4> encoding> : SearchableTable{
|
||||
let SearchableFields = ["Name", "Encoding"];
|
||||
let EnumValueField = "Encoding";
|
||||
|
||||
string Name = name;
|
||||
bits<4> Encoding;
|
||||
let Encoding = encoding;
|
||||
|
||||
code Requires = [{ {AArch64::HasV8_4aOps} }];
|
||||
}
|
||||
|
||||
def : TSB<"csync", 0>;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// PRFM (prefetch) instruction options.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -2646,6 +2646,10 @@ static void setRequiredFeatureString(FeatureBitset FBS, std::string &Str) {
|
||||
Str += "ARMv8.1a";
|
||||
else if (FBS[AArch64::HasV8_2aOps])
|
||||
Str += "ARMv8.2a";
|
||||
else if (FBS[AArch64::HasV8_3aOps])
|
||||
Str += "ARMv8.3a";
|
||||
else if (FBS[AArch64::HasV8_4aOps])
|
||||
Str += "ARMv8.4a";
|
||||
else
|
||||
Str += "(unknown)";
|
||||
}
|
||||
@ -2756,9 +2760,11 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
|
||||
if (Mnemonic == "tsb" && Tok.isNot(AsmToken::Identifier)) {
|
||||
TokError("'csync' operand expected");
|
||||
return MatchOperand_ParseFail;
|
||||
// Can be either a #imm style literal or an option name
|
||||
if (parseOptionalToken(AsmToken::Hash) ||
|
||||
Tok.is(AsmToken::Integer)) {
|
||||
} else if (parseOptionalToken(AsmToken::Hash) || Tok.is(AsmToken::Integer)) {
|
||||
// Immediate operand.
|
||||
const MCExpr *ImmVal;
|
||||
SMLoc ExprLoc = getLoc();
|
||||
@ -2784,18 +2790,23 @@ AArch64AsmParser::tryParseBarrierOperand(OperandVector &Operands) {
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
auto TSB = AArch64TSB::lookupTSBByName(Tok.getString());
|
||||
// The only valid named option for ISB is 'sy'
|
||||
auto DB = AArch64DB::lookupDBByName(Tok.getString());
|
||||
if (Mnemonic == "isb" && (!DB || DB->Encoding != AArch64DB::sy)) {
|
||||
TokError("'sy' or #imm operand expected");
|
||||
return MatchOperand_ParseFail;
|
||||
} else if (!DB) {
|
||||
// The only valid named option for TSB is 'csync'
|
||||
} else if (Mnemonic == "tsb" && (!TSB || TSB->Encoding != AArch64TSB::csync)) {
|
||||
TokError("'csync' operand expected");
|
||||
return MatchOperand_ParseFail;
|
||||
} else if (!DB && !TSB) {
|
||||
TokError("invalid barrier option name");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
Operands.push_back(AArch64Operand::CreateBarrier(
|
||||
DB->Encoding, Tok.getString(), getLoc(), getContext()));
|
||||
DB ? DB->Encoding : TSB->Encoding, Tok.getString(), getLoc(), getContext()));
|
||||
Parser.Lex(); // Consume the option
|
||||
|
||||
return MatchOperand_Success;
|
||||
|
@ -282,6 +282,13 @@ void AArch64InstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
return;
|
||||
}
|
||||
|
||||
// Instruction TSB is specified as a one operand instruction, but 'csync' is
|
||||
// not encoded, so for printing it is treated as a special case here:
|
||||
if (Opcode == AArch64::TSB) {
|
||||
O << "\ttsb\tcsync";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!printAliasInstr(MI, STI, O))
|
||||
printInstruction(MI, STI, O);
|
||||
|
||||
@ -1329,6 +1336,9 @@ void AArch64InstPrinter::printBarrierOption(const MCInst *MI, unsigned OpNo,
|
||||
if (Opcode == AArch64::ISB) {
|
||||
auto ISB = AArch64ISB::lookupISBByEncoding(Val);
|
||||
Name = ISB ? ISB->Name : "";
|
||||
} else if (Opcode == AArch64::TSB) {
|
||||
auto TSB = AArch64TSB::lookupTSBByEncoding(Val);
|
||||
Name = TSB ? TSB->Name : "";
|
||||
} else {
|
||||
auto DB = AArch64DB::lookupDBByEncoding(Val);
|
||||
Name = DB ? DB->Name : "";
|
||||
|
@ -53,6 +53,14 @@ namespace llvm {
|
||||
#include "AArch64GenSystemOperands.inc"
|
||||
}
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
namespace AArch64TSB {
|
||||
#define GET_TSB_IMPL
|
||||
#include "AArch64GenSystemOperands.inc"
|
||||
}
|
||||
}
|
||||
|
||||
namespace llvm {
|
||||
namespace AArch64PRFM {
|
||||
#define GET_PRFM_IMPL
|
||||
|
@ -327,6 +327,14 @@ namespace AArch64ISB {
|
||||
#include "AArch64GenSystemOperands.inc"
|
||||
}
|
||||
|
||||
namespace AArch64TSB {
|
||||
struct TSB : SysAlias {
|
||||
using SysAlias::SysAlias;
|
||||
};
|
||||
#define GET_TSB_DECL
|
||||
#include "AArch64GenSystemOperands.inc"
|
||||
}
|
||||
|
||||
namespace AArch64PRFM {
|
||||
struct PRFM : SysAlias {
|
||||
using SysAlias::SysAlias;
|
||||
|
@ -4819,6 +4819,15 @@ def instsyncb_opt : Operand<i32> {
|
||||
let DecoderMethod = "DecodeInstSyncBarrierOption";
|
||||
}
|
||||
|
||||
def TraceSyncBarrierOptOperand : AsmOperandClass {
|
||||
let Name = "TraceSyncBarrierOpt";
|
||||
let ParserMethod = "parseTraceSyncBarrierOptOperand";
|
||||
}
|
||||
def tsb_opt : Operand<i32> {
|
||||
let PrintMethod = "printTraceSyncBOption";
|
||||
let ParserMatchClass = TraceSyncBarrierOptOperand;
|
||||
}
|
||||
|
||||
// Memory barriers protect the atomic sequences
|
||||
let hasSideEffects = 1 in {
|
||||
def DMB : AInoP<(outs), (ins memb_opt:$opt), MiscFrm, NoItinerary,
|
||||
@ -4845,6 +4854,13 @@ def ISB : AInoP<(outs), (ins instsyncb_opt:$opt), MiscFrm, NoItinerary,
|
||||
let Inst{31-4} = 0xf57ff06;
|
||||
let Inst{3-0} = opt;
|
||||
}
|
||||
|
||||
let hasNoSchedulingInfo = 1 in
|
||||
def TSB : AInoP<(outs), (ins tsb_opt:$opt), MiscFrm, NoItinerary,
|
||||
"tsb", "\t$opt", []>, Requires<[IsARM, HasV8_4a]> {
|
||||
let Inst{31-0} = 0xe320f012;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
let usesCustomInserter = 1, Defs = [CPSR] in {
|
||||
|
@ -3215,6 +3215,12 @@ def t2ISB : T2I<(outs), (ins instsyncb_opt:$opt), NoItinerary,
|
||||
let Inst{31-4} = 0xf3bf8f6;
|
||||
let Inst{3-0} = opt;
|
||||
}
|
||||
|
||||
let hasNoSchedulingInfo = 1 in
|
||||
def t2TSB : T2I<(outs), (ins tsb_opt:$opt), NoItinerary,
|
||||
"tsb", "\t$opt", []>, Requires<[IsThumb, HasV8_4a]> {
|
||||
let Inst{31-0} = 0xf3af8012;
|
||||
}
|
||||
}
|
||||
|
||||
class T2I_ldrex<bits<4> opcod, dag oops, dag iops, AddrMode am, int sz,
|
||||
|
@ -527,6 +527,7 @@ class ARMAsmParser : public MCTargetAsmParser {
|
||||
OperandMatchResultTy parseCoprocRegOperand(OperandVector &);
|
||||
OperandMatchResultTy parseCoprocOptionOperand(OperandVector &);
|
||||
OperandMatchResultTy parseMemBarrierOptOperand(OperandVector &);
|
||||
OperandMatchResultTy parseTraceSyncBarrierOptOperand(OperandVector &);
|
||||
OperandMatchResultTy parseInstSyncBarrierOptOperand(OperandVector &);
|
||||
OperandMatchResultTy parseProcIFlagsOperand(OperandVector &);
|
||||
OperandMatchResultTy parseMSRMaskOperand(OperandVector &);
|
||||
@ -646,6 +647,7 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||
k_Immediate,
|
||||
k_MemBarrierOpt,
|
||||
k_InstSyncBarrierOpt,
|
||||
k_TraceSyncBarrierOpt,
|
||||
k_Memory,
|
||||
k_PostIndexRegister,
|
||||
k_MSRMask,
|
||||
@ -696,6 +698,10 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||
ARM_ISB::InstSyncBOpt Val;
|
||||
};
|
||||
|
||||
struct TSBOptOp {
|
||||
ARM_TSB::TraceSyncBOpt Val;
|
||||
};
|
||||
|
||||
struct IFlagsOp {
|
||||
ARM_PROC::IFlags Val;
|
||||
};
|
||||
@ -792,6 +798,7 @@ class ARMOperand : public MCParsedAsmOperand {
|
||||
struct CoprocOptionOp CoprocOption;
|
||||
struct MBOptOp MBOpt;
|
||||
struct ISBOptOp ISBOpt;
|
||||
struct TSBOptOp TSBOpt;
|
||||
struct ITMaskOp ITMask;
|
||||
struct IFlagsOp IFlags;
|
||||
struct MMaskOp MMask;
|
||||
@ -881,6 +888,11 @@ public:
|
||||
return ISBOpt.Val;
|
||||
}
|
||||
|
||||
ARM_TSB::TraceSyncBOpt getTraceSyncBarrierOpt() const {
|
||||
assert(Kind == k_TraceSyncBarrierOpt && "Invalid access!");
|
||||
return TSBOpt.Val;
|
||||
}
|
||||
|
||||
ARM_PROC::IFlags getProcIFlags() const {
|
||||
assert(Kind == k_ProcIFlags && "Invalid access!");
|
||||
return IFlags.Val;
|
||||
@ -1157,6 +1169,7 @@ public:
|
||||
bool isToken() const override { return Kind == k_Token; }
|
||||
bool isMemBarrierOpt() const { return Kind == k_MemBarrierOpt; }
|
||||
bool isInstSyncBarrierOpt() const { return Kind == k_InstSyncBarrierOpt; }
|
||||
bool isTraceSyncBarrierOpt() const { return Kind == k_TraceSyncBarrierOpt; }
|
||||
bool isMem() const override {
|
||||
if (Kind != k_Memory)
|
||||
return false;
|
||||
@ -2292,6 +2305,11 @@ public:
|
||||
Inst.addOperand(MCOperand::createImm(unsigned(getInstSyncBarrierOpt())));
|
||||
}
|
||||
|
||||
void addTraceSyncBarrierOptOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::createImm(unsigned(getTraceSyncBarrierOpt())));
|
||||
}
|
||||
|
||||
void addMemNoOffsetOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(N == 1 && "Invalid number of operands!");
|
||||
Inst.addOperand(MCOperand::createReg(Memory.BaseRegNum));
|
||||
@ -3147,6 +3165,15 @@ public:
|
||||
return Op;
|
||||
}
|
||||
|
||||
static std::unique_ptr<ARMOperand>
|
||||
CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) {
|
||||
auto Op = make_unique<ARMOperand>(k_TraceSyncBarrierOpt);
|
||||
Op->TSBOpt.Val = Opt;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = S;
|
||||
return Op;
|
||||
}
|
||||
|
||||
static std::unique_ptr<ARMOperand> CreateProcIFlags(ARM_PROC::IFlags IFlags,
|
||||
SMLoc S) {
|
||||
auto Op = make_unique<ARMOperand>(k_ProcIFlags);
|
||||
@ -3216,6 +3243,9 @@ void ARMOperand::print(raw_ostream &OS) const {
|
||||
case k_InstSyncBarrierOpt:
|
||||
OS << "<ARM_ISB::" << InstSyncBOptToString(getInstSyncBarrierOpt()) << ">";
|
||||
break;
|
||||
case k_TraceSyncBarrierOpt:
|
||||
OS << "<ARM_TSB::" << TraceSyncBOptToString(getTraceSyncBarrierOpt()) << ">";
|
||||
break;
|
||||
case k_Memory:
|
||||
OS << "<memory "
|
||||
<< " base:" << Memory.BaseRegNum;
|
||||
@ -4205,6 +4235,24 @@ ARMAsmParser::parseMemBarrierOptOperand(OperandVector &Operands) {
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
OperandMatchResultTy
|
||||
ARMAsmParser::parseTraceSyncBarrierOptOperand(OperandVector &Operands) {
|
||||
MCAsmParser &Parser = getParser();
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
const AsmToken &Tok = Parser.getTok();
|
||||
|
||||
if (Tok.isNot(AsmToken::Identifier))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
if (!Tok.getString().equals_lower("csync"))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
Parser.Lex(); // Eat identifier token.
|
||||
|
||||
Operands.push_back(ARMOperand::CreateTraceSyncBarrierOpt(ARM_TSB::CSYNC, S));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
/// parseInstSyncBarrierOptOperand - Try to parse ISB inst sync barrier options.
|
||||
OperandMatchResultTy
|
||||
ARMAsmParser::parseInstSyncBarrierOptOperand(OperandVector &Operands) {
|
||||
@ -5680,6 +5728,7 @@ void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic, StringRef FullInst,
|
||||
Mnemonic != "isb" && Mnemonic != "pld" && Mnemonic != "pli" &&
|
||||
Mnemonic != "pldw" && Mnemonic != "ldc2" && Mnemonic != "ldc2l" &&
|
||||
Mnemonic != "stc2" && Mnemonic != "stc2l" &&
|
||||
Mnemonic != "tsb" &&
|
||||
!Mnemonic.startswith("rfe") && !Mnemonic.startswith("srs");
|
||||
} else if (isThumbOne()) {
|
||||
if (hasV6MOps())
|
||||
|
@ -269,6 +269,10 @@ void ARMInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ARM::TSB:
|
||||
case ARM::t2TSB:
|
||||
O << "\ttsb\tcsync";
|
||||
return;
|
||||
}
|
||||
|
||||
if (!printAliasInstr(MI, STI, O))
|
||||
@ -696,6 +700,13 @@ void ARMInstPrinter::printInstSyncBOption(const MCInst *MI, unsigned OpNum,
|
||||
O << ARM_ISB::InstSyncBOptToString(val);
|
||||
}
|
||||
|
||||
void ARMInstPrinter::printTraceSyncBOption(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
unsigned val = MI->getOperand(OpNum).getImm();
|
||||
O << ARM_TSB::TraceSyncBOptToString(val);
|
||||
}
|
||||
|
||||
void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
|
@ -94,6 +94,8 @@ public:
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printInstSyncBOption(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printTraceSyncBOption(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printShiftImmOperand(const MCInst *MI, unsigned OpNum,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
|
||||
|
@ -98,6 +98,20 @@ namespace ARM_MB {
|
||||
}
|
||||
} // namespace ARM_MB
|
||||
|
||||
namespace ARM_TSB {
|
||||
enum TraceSyncBOpt {
|
||||
CSYNC = 0
|
||||
};
|
||||
|
||||
inline static const char *TraceSyncBOptToString(unsigned val) {
|
||||
switch (val) {
|
||||
default:
|
||||
llvm_unreachable("Unknown trace synchronization barrier operation");
|
||||
case CSYNC: return "csync";
|
||||
}
|
||||
}
|
||||
} // namespace ARM_TSB
|
||||
|
||||
namespace ARM_ISB {
|
||||
enum InstSyncBOpt {
|
||||
RESERVED_0 = 0,
|
||||
|
23
test/MC/AArch64/armv8.4a-trace-error.s
Normal file
23
test/MC/AArch64/armv8.4a-trace-error.s
Normal file
@ -0,0 +1,23 @@
|
||||
// RUN: not llvm-mc -triple aarch64-none-linux-gnu -show-encoding -mattr=+v8.4a < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// ARMV8.4-A Debug, Trace and PMU Extensions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
tsb
|
||||
tsb foo
|
||||
tsb #0
|
||||
tsb 0
|
||||
|
||||
//CHECK-ERROR: error: too few operands for instruction
|
||||
//CHECK-ERROR: tsb
|
||||
//CHECK-ERROR: ^
|
||||
//CHECK-ERROR: error: 'csync' operand expected
|
||||
//CHECK-ERROR: tsb foo
|
||||
//CHECK-ERROR: ^
|
||||
//CHECK-ERROR: error: 'csync' operand expected
|
||||
//CHECK-ERROR: tsb #0
|
||||
//CHECK-ERROR: ^
|
||||
//CHECK-ERROR: error: 'csync' operand expected
|
||||
//CHECK-ERROR: tsb 0
|
||||
//CHECK-ERROR: ^
|
@ -13,6 +13,8 @@ mrs x0, TRFCR_EL1
|
||||
mrs x0, TRFCR_EL2
|
||||
mrs x0, TRFCR_EL12
|
||||
|
||||
tsb csync
|
||||
|
||||
//CHECK: msr TRFCR_EL1, x0 // encoding: [0x20,0x12,0x18,0xd5]
|
||||
//CHECK: msr TRFCR_EL2, x0 // encoding: [0x20,0x12,0x1c,0xd5]
|
||||
//CHECK: msr TRFCR_EL12, x0 // encoding: [0x20,0x12,0x1d,0xd5]
|
||||
@ -21,6 +23,8 @@ mrs x0, TRFCR_EL12
|
||||
//CHECK: mrs x0, TRFCR_EL2 // encoding: [0x20,0x12,0x3c,0xd5]
|
||||
//CHECK: mrs x0, TRFCR_EL12 // encoding: [0x20,0x12,0x3d,0xd5]
|
||||
|
||||
//CHECK: tsb csync // encoding: [0x5f,0x22,0x03,0xd5]
|
||||
|
||||
//CHECK-ERROR: error: expected writable system register or pstate
|
||||
//CHECK-ERROR: msr TRFCR_EL1, x0
|
||||
//CHECK-ERROR: ^
|
||||
@ -40,3 +44,5 @@ mrs x0, TRFCR_EL12
|
||||
//CHECK-ERROR: error: expected readable system register
|
||||
//CHECK-ERROR: mrs x0, TRFCR_EL12
|
||||
//CHECK-ERROR: ^
|
||||
|
||||
//CHECK-ERROR: error: instruction requires: armv8.4a
|
||||
|
20
test/MC/ARM/armv8.4a-trace-error.s
Normal file
20
test/MC/ARM/armv8.4a-trace-error.s
Normal file
@ -0,0 +1,20 @@
|
||||
// RUN: not llvm-mc -triple arm -mattr=+v8.4a -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
|
||||
// RUN: not llvm-mc -triple thumb -mattr=+v8.4a -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-ERROR
|
||||
|
||||
tsb
|
||||
tsb 0
|
||||
tsb #0
|
||||
tsb foo
|
||||
|
||||
//CHECK-ERROR: error: too few operands for instruction
|
||||
//CHECK-ERROR: tsb
|
||||
//CHECK-ERROR: ^
|
||||
//CHECK-ERROR: error: invalid operand for instruction
|
||||
//CHECK-ERROR: tsb 0
|
||||
//CHECK-ERROR: ^
|
||||
//CHECK-ERROR: error: invalid operand for instruction
|
||||
//CHECK-ERROR: tsb #0
|
||||
//CHECK-ERROR: ^
|
||||
//CHECK-ERROR: error: invalid operand for instruction
|
||||
//CHECK-ERROR: tsb foo
|
||||
//CHECK-ERROR: ^
|
12
test/MC/ARM/armv8.4a-trace.s
Normal file
12
test/MC/ARM/armv8.4a-trace.s
Normal file
@ -0,0 +1,12 @@
|
||||
// RUN: llvm-mc -triple arm -mattr=+v8.4a -show-encoding < %s | FileCheck %s --check-prefix=CHECK-A32
|
||||
// RUN: llvm-mc -triple thumb -mattr=+v8.4a -show-encoding < %s | FileCheck %s --check-prefix=CHECK-T32
|
||||
// RUN: not llvm-mc -triple arm -mattr=-v8.4a -show-encoding < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-V84
|
||||
|
||||
tsb csync
|
||||
|
||||
//CHECK-A32: tsb csync @ encoding: [0x12,0xf0,0x20,0xe3]
|
||||
//CHECK-T32: tsb csync @ encoding: [0xaf,0xf3,0x12,0x80]
|
||||
|
||||
//CHECK-NO-V84: error: invalid instruction
|
||||
//CHECK-NO-V84: tsb csync
|
||||
//CHECK-NO-V84: ^
|
@ -7,6 +7,7 @@
|
||||
[0x20,0x12,0x38,0xd5]
|
||||
[0x20,0x12,0x3c,0xd5]
|
||||
[0x20,0x12,0x3d,0xd5]
|
||||
[0x5f,0x22,0x03,0xd5]
|
||||
|
||||
#CHECK: msr TRFCR_EL1, x0
|
||||
#CHECK: msr TRFCR_EL2, x0
|
||||
@ -14,6 +15,7 @@
|
||||
#CHECK: mrs x0, TRFCR_EL1
|
||||
#CHECK: mrs x0, TRFCR_EL2
|
||||
#CHECK: mrs x0, TRFCR_EL12
|
||||
#CHECK: tsb csync
|
||||
|
||||
#CHECK-NO-V84: msr S3_0_C1_C2_1, x0
|
||||
#CHECK-NO-V84: msr S3_4_C1_C2_1, x0
|
||||
@ -21,3 +23,4 @@
|
||||
#CHECK-NO-V84: mrs x0, S3_0_C1_C2_1
|
||||
#CHECK-NO-V84: mrs x0, S3_4_C1_C2_1
|
||||
#CHECK-NO-V84: mrs x0, S3_5_C1_C2_1
|
||||
#CHECK-NO-V84: hint #18
|
||||
|
10
test/MC/Disassembler/ARM/armv8.4a-trace-a32.txt
Normal file
10
test/MC/Disassembler/ARM/armv8.4a-trace-a32.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# RUN: llvm-mc -triple arm-none-linux-gnu -mattr=+v8.4a --disassemble < %s | FileCheck %s
|
||||
# RUN: not llvm-mc -triple arm-none-linux-gnu -mattr=-v8.4a --disassemble < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-V84
|
||||
|
||||
[0x12,0xf0,0x20,0xe3]
|
||||
|
||||
#CHECK: tsb csync
|
||||
|
||||
#CHECK-NO-V84: warning: invalid instruction encoding
|
||||
#CHECK-NO-V84: [0x12,0xf0,0x20,0xe3]
|
||||
#CHECK-NO-V84: ^
|
10
test/MC/Disassembler/ARM/armv8.4a-trace-t32.txt
Normal file
10
test/MC/Disassembler/ARM/armv8.4a-trace-t32.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# RUN: llvm-mc -triple thumb-none-linux-gnu -mattr=+v8.4a --disassemble < %s | FileCheck %s
|
||||
# RUN: not llvm-mc -triple thumb-none-linux-gnu -mattr=-v8.4a --disassemble < %s 2>&1 | FileCheck %s --check-prefix=CHECK-NO-V84
|
||||
|
||||
[0xaf,0xf3,0x12,0x80]
|
||||
|
||||
#CHECK: tsb csync
|
||||
|
||||
#CHECK-NO-V84: warning: invalid instruction encoding
|
||||
#CHECK-NO-V84: [0xaf,0xf3,0x12,0x80]
|
||||
#CHECK-NO-V84: ^
|
Loading…
Reference in New Issue
Block a user