From: Sjoerd Meijer Date: Fri, 6 Jul 2018 08:03:12 +0000 (+0000) Subject: [AArch64][ARM] Armv8.4-A: Trace synchronization barrier instruction X-Git-Tag: llvmorg-7.0.0-rc1~2092 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2a57b357a3a0de2202a3fb0272d2648a205bcdfa;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index a21ab50..585acda 100644 --- a/llvm/lib/Target/AArch64/AArch64InstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64InstrInfo.td @@ -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; + +def TSB : CRmSystemI { + let CRm = 0b0010; + let Inst{12} = 0; + let Predicates = [HasV8_4a]; +} } // ARMv8.2 Dot Product diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td index 40ba3fc..d526bf2 100644 --- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -143,6 +143,23 @@ class ISB encoding> : SearchableTable{ def : ISB<"sy", 0xf>; //===----------------------------------------------------------------------===// +// TSB (Trace synchronization barrier) instruction options. +//===----------------------------------------------------------------------===// + +class TSB 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. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 9537204..3e24299 100644 --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -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; diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index 626c580..26e4121 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -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 : ""; diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp index 5f6eaa0..23cc21c 100644 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp @@ -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 diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h index 86bf699..16911ee 100644 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -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; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index da56c6a..d4c342c 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -4819,6 +4819,15 @@ def instsyncb_opt : Operand { let DecoderMethod = "DecodeInstSyncBarrierOption"; } +def TraceSyncBarrierOptOperand : AsmOperandClass { + let Name = "TraceSyncBarrierOpt"; + let ParserMethod = "parseTraceSyncBarrierOptOperand"; +} +def tsb_opt : Operand { + 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 { diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 034cb1d..c7133b6 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -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 opcod, dag oops, dag iops, AddrMode am, int sz, diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 318bfe9..807d625 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -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 + CreateTraceSyncBarrierOpt(ARM_TSB::TraceSyncBOpt Opt, SMLoc S) { + auto Op = make_unique(k_TraceSyncBarrierOpt); + Op->TSBOpt.Val = Opt; + Op->StartLoc = S; + Op->EndLoc = S; + return Op; + } + static std::unique_ptr CreateProcIFlags(ARM_PROC::IFlags IFlags, SMLoc S) { auto Op = make_unique(k_ProcIFlags); @@ -3216,6 +3243,9 @@ void ARMOperand::print(raw_ostream &OS) const { case k_InstSyncBarrierOpt: OS << ""; break; + case k_TraceSyncBarrierOpt: + OS << ""; + break; case k_Memory: OS << "getOperand(OpNum).getImm(); + O << ARM_TSB::TraceSyncBOptToString(val); +} + void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index 7dc3112..afc8515 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h @@ -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, diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h index 5a0d1f9..b918006 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h @@ -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, diff --git a/llvm/test/MC/AArch64/armv8.4a-trace-error.s b/llvm/test/MC/AArch64/armv8.4a-trace-error.s new file mode 100644 index 0000000..99b6128 --- /dev/null +++ b/llvm/test/MC/AArch64/armv8.4a-trace-error.s @@ -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: ^ diff --git a/llvm/test/MC/AArch64/armv8.4a-trace.s b/llvm/test/MC/AArch64/armv8.4a-trace.s index c11b80d..d14b0e0 100644 --- a/llvm/test/MC/AArch64/armv8.4a-trace.s +++ b/llvm/test/MC/AArch64/armv8.4a-trace.s @@ -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 diff --git a/llvm/test/MC/ARM/armv8.4a-trace-error.s b/llvm/test/MC/ARM/armv8.4a-trace-error.s new file mode 100644 index 0000000..7ec8040 --- /dev/null +++ b/llvm/test/MC/ARM/armv8.4a-trace-error.s @@ -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: ^ diff --git a/llvm/test/MC/ARM/armv8.4a-trace.s b/llvm/test/MC/ARM/armv8.4a-trace.s new file mode 100644 index 0000000..254f776 --- /dev/null +++ b/llvm/test/MC/ARM/armv8.4a-trace.s @@ -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: ^ diff --git a/llvm/test/MC/Disassembler/AArch64/armv8.4a-trace.txt b/llvm/test/MC/Disassembler/AArch64/armv8.4a-trace.txt index d51157e0..feb9e8c 100644 --- a/llvm/test/MC/Disassembler/AArch64/armv8.4a-trace.txt +++ b/llvm/test/MC/Disassembler/AArch64/armv8.4a-trace.txt @@ -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 diff --git a/llvm/test/MC/Disassembler/ARM/armv8.4a-trace-a32.txt b/llvm/test/MC/Disassembler/ARM/armv8.4a-trace-a32.txt new file mode 100644 index 0000000..d53cf5e --- /dev/null +++ b/llvm/test/MC/Disassembler/ARM/armv8.4a-trace-a32.txt @@ -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: ^ diff --git a/llvm/test/MC/Disassembler/ARM/armv8.4a-trace-t32.txt b/llvm/test/MC/Disassembler/ARM/armv8.4a-trace-t32.txt new file mode 100644 index 0000000..5b062cc --- /dev/null +++ b/llvm/test/MC/Disassembler/ARM/armv8.4a-trace-t32.txt @@ -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: ^