diff options
author | Sjoerd Meijer <sjoerd.meijer@arm.com> | 2018-07-06 08:03:12 +0000 |
---|---|---|
committer | Sjoerd Meijer <sjoerd.meijer@arm.com> | 2018-07-06 08:03:12 +0000 |
commit | 2a57b357a3a0de2202a3fb0272d2648a205bcdfa (patch) | |
tree | 7a78591803955adc522b572bfac72a8ce8e58e15 /llvm/lib/Target/ARM | |
parent | be4c2933a2c370d292122fc2187d75436aeaea83 (diff) | |
download | bcm5719-llvm-2a57b357a3a0de2202a3fb0272d2648a205bcdfa.tar.gz bcm5719-llvm-2a57b357a3a0de2202a3fb0272d2648a205bcdfa.zip |
[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
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 16 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 6 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 49 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h | 2 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h | 14 |
6 files changed, 98 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index da56c6a36bb..d4c342cee5c 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -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 { diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index 034cb1db758..c7133b6483e 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<bits<4> 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 318bfe90d1d..807d6254733 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<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()) diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 7492a7641d2..75ed40c18fa 100644 --- a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -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) { diff --git a/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h b/llvm/lib/Target/ARM/InstPrinter/ARMInstPrinter.h index 7dc311229cc..afc8515136b 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 5a0d1f9edcc..b918006fe9e 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, |