diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64InstrInfo.td | 8 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64SystemOperands.td | 17 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp | 19 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h | 8 | ||||
-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 |
12 files changed, 164 insertions, 4 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64InstrInfo.td b/llvm/lib/Target/AArch64/AArch64InstrInfo.td index a21ab50cd94..585acda13c0 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<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 diff --git a/llvm/lib/Target/AArch64/AArch64SystemOperands.td b/llvm/lib/Target/AArch64/AArch64SystemOperands.td index 40ba3fc5f97..d526bf2576a 100644 --- a/llvm/lib/Target/AArch64/AArch64SystemOperands.td +++ b/llvm/lib/Target/AArch64/AArch64SystemOperands.td @@ -143,6 +143,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. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp index 9537204d592..3e24299ec98 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 626c580663f..26e41215afc 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 5f6eaa0613b..23cc21ce2e7 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 86bf699f0bc..16911eeec99 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 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, |