13dac3a9bSDimitry Andric //===- MIParser.cpp - Machine instructions parser implementation ----------===//
23dac3a9bSDimitry Andric //
33dac3a9bSDimitry Andric // The LLVM Compiler Infrastructure
43dac3a9bSDimitry Andric //
53dac3a9bSDimitry Andric // This file is distributed under the University of Illinois Open Source
63dac3a9bSDimitry Andric // License. See LICENSE.TXT for details.
73dac3a9bSDimitry Andric //
83dac3a9bSDimitry Andric //===----------------------------------------------------------------------===//
93dac3a9bSDimitry Andric //
103dac3a9bSDimitry Andric // This file implements the parsing of machine instructions.
113dac3a9bSDimitry Andric //
123dac3a9bSDimitry Andric //===----------------------------------------------------------------------===//
133dac3a9bSDimitry Andric
14db17bf38SDimitry Andric #include "MIParser.h"
152cab237bSDimitry Andric #include "MILexer.h"
16db17bf38SDimitry Andric #include "llvm/ADT/APInt.h"
17db17bf38SDimitry Andric #include "llvm/ADT/APSInt.h"
18db17bf38SDimitry Andric #include "llvm/ADT/ArrayRef.h"
19db17bf38SDimitry Andric #include "llvm/ADT/DenseMap.h"
20db17bf38SDimitry Andric #include "llvm/ADT/None.h"
21db17bf38SDimitry Andric #include "llvm/ADT/Optional.h"
22db17bf38SDimitry Andric #include "llvm/ADT/SmallVector.h"
233dac3a9bSDimitry Andric #include "llvm/ADT/StringMap.h"
24db17bf38SDimitry Andric #include "llvm/ADT/StringRef.h"
252cab237bSDimitry Andric #include "llvm/ADT/StringSwitch.h"
26db17bf38SDimitry Andric #include "llvm/ADT/Twine.h"
27*b5893f02SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
287d523365SDimitry Andric #include "llvm/AsmParser/Parser.h"
293dac3a9bSDimitry Andric #include "llvm/AsmParser/SlotMapping.h"
300f5676f4SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
313dac3a9bSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
327d523365SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
333ca95b02SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
343dac3a9bSDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
35875ed548SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
367d523365SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
37db17bf38SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
383ca95b02SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
392cab237bSDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
402cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
412cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
42db17bf38SDimitry Andric #include "llvm/IR/BasicBlock.h"
437d523365SDimitry Andric #include "llvm/IR/Constants.h"
44db17bf38SDimitry Andric #include "llvm/IR/DataLayout.h"
452cab237bSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
46db17bf38SDimitry Andric #include "llvm/IR/DebugLoc.h"
47db17bf38SDimitry Andric #include "llvm/IR/Function.h"
48db17bf38SDimitry Andric #include "llvm/IR/InstrTypes.h"
493ca95b02SDimitry Andric #include "llvm/IR/Instructions.h"
50d88c1a5aSDimitry Andric #include "llvm/IR/Intrinsics.h"
51db17bf38SDimitry Andric #include "llvm/IR/Metadata.h"
523dac3a9bSDimitry Andric #include "llvm/IR/Module.h"
537d523365SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
54db17bf38SDimitry Andric #include "llvm/IR/Type.h"
55db17bf38SDimitry Andric #include "llvm/IR/Value.h"
567d523365SDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
57db17bf38SDimitry Andric #include "llvm/MC/LaneBitmask.h"
58*b5893f02SDimitry Andric #include "llvm/MC/MCContext.h"
59db17bf38SDimitry Andric #include "llvm/MC/MCDwarf.h"
60db17bf38SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
61db17bf38SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
62db17bf38SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
63db17bf38SDimitry Andric #include "llvm/Support/BranchProbability.h"
64db17bf38SDimitry Andric #include "llvm/Support/Casting.h"
65db17bf38SDimitry Andric #include "llvm/Support/ErrorHandling.h"
66db17bf38SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h"
67db17bf38SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
68db17bf38SDimitry Andric #include "llvm/Support/SMLoc.h"
693dac3a9bSDimitry Andric #include "llvm/Support/SourceMgr.h"
703ca95b02SDimitry Andric #include "llvm/Support/raw_ostream.h"
71d88c1a5aSDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
72db17bf38SDimitry Andric #include "llvm/Target/TargetMachine.h"
73db17bf38SDimitry Andric #include <algorithm>
74db17bf38SDimitry Andric #include <cassert>
75d88c1a5aSDimitry Andric #include <cctype>
76db17bf38SDimitry Andric #include <cstddef>
77db17bf38SDimitry Andric #include <cstdint>
78db17bf38SDimitry Andric #include <limits>
79db17bf38SDimitry Andric #include <string>
80db17bf38SDimitry Andric #include <utility>
813dac3a9bSDimitry Andric
823dac3a9bSDimitry Andric using namespace llvm;
833dac3a9bSDimitry Andric
PerFunctionMIParsingState(MachineFunction & MF,SourceMgr & SM,const SlotMapping & IRSlots,const Name2RegClassMap & Names2RegClasses,const Name2RegBankMap & Names2RegBanks)843ca95b02SDimitry Andric PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF,
857a7e6055SDimitry Andric SourceMgr &SM, const SlotMapping &IRSlots,
867a7e6055SDimitry Andric const Name2RegClassMap &Names2RegClasses,
877a7e6055SDimitry Andric const Name2RegBankMap &Names2RegBanks)
887a7e6055SDimitry Andric : MF(MF), SM(&SM), IRSlots(IRSlots), Names2RegClasses(Names2RegClasses),
897a7e6055SDimitry Andric Names2RegBanks(Names2RegBanks) {
903ca95b02SDimitry Andric }
913ca95b02SDimitry Andric
getVRegInfo(unsigned Num)92d88c1a5aSDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) {
93d88c1a5aSDimitry Andric auto I = VRegInfos.insert(std::make_pair(Num, nullptr));
94d88c1a5aSDimitry Andric if (I.second) {
95d88c1a5aSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
96d88c1a5aSDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo;
97d88c1a5aSDimitry Andric Info->VReg = MRI.createIncompleteVirtualRegister();
98d88c1a5aSDimitry Andric I.first->second = Info;
99d88c1a5aSDimitry Andric }
100d88c1a5aSDimitry Andric return *I.first->second;
101d88c1a5aSDimitry Andric }
102d88c1a5aSDimitry Andric
getVRegInfoNamed(StringRef RegName)1034ba319b5SDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) {
1044ba319b5SDimitry Andric assert(RegName != "" && "Expected named reg.");
1054ba319b5SDimitry Andric
1064ba319b5SDimitry Andric auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr));
1074ba319b5SDimitry Andric if (I.second) {
1084ba319b5SDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo;
1094ba319b5SDimitry Andric Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName);
1104ba319b5SDimitry Andric I.first->second = Info;
1114ba319b5SDimitry Andric }
1124ba319b5SDimitry Andric return *I.first->second;
1134ba319b5SDimitry Andric }
1144ba319b5SDimitry Andric
1153dac3a9bSDimitry Andric namespace {
1163dac3a9bSDimitry Andric
117875ed548SDimitry Andric /// A wrapper struct around the 'MachineOperand' struct that includes a source
1187d523365SDimitry Andric /// range and other attributes.
1197d523365SDimitry Andric struct ParsedMachineOperand {
120875ed548SDimitry Andric MachineOperand Operand;
121875ed548SDimitry Andric StringRef::iterator Begin;
122875ed548SDimitry Andric StringRef::iterator End;
1237d523365SDimitry Andric Optional<unsigned> TiedDefIdx;
124875ed548SDimitry Andric
ParsedMachineOperand__anon7ed225c00111::ParsedMachineOperand1257d523365SDimitry Andric ParsedMachineOperand(const MachineOperand &Operand, StringRef::iterator Begin,
1267d523365SDimitry Andric StringRef::iterator End, Optional<unsigned> &TiedDefIdx)
1277d523365SDimitry Andric : Operand(Operand), Begin(Begin), End(End), TiedDefIdx(TiedDefIdx) {
1287d523365SDimitry Andric if (TiedDefIdx)
1297d523365SDimitry Andric assert(Operand.isReg() && Operand.isUse() &&
1307d523365SDimitry Andric "Only used register operands can be tied");
1317d523365SDimitry Andric }
132875ed548SDimitry Andric };
133875ed548SDimitry Andric
1343dac3a9bSDimitry Andric class MIParser {
1353dac3a9bSDimitry Andric MachineFunction &MF;
1363dac3a9bSDimitry Andric SMDiagnostic &Error;
1373dac3a9bSDimitry Andric StringRef Source, CurrentSource;
1383dac3a9bSDimitry Andric MIToken Token;
139d88c1a5aSDimitry Andric PerFunctionMIParsingState &PFS;
1403dac3a9bSDimitry Andric /// Maps from instruction names to op codes.
1413dac3a9bSDimitry Andric StringMap<unsigned> Names2InstrOpCodes;
1423dac3a9bSDimitry Andric /// Maps from register names to registers.
1433dac3a9bSDimitry Andric StringMap<unsigned> Names2Regs;
1443dac3a9bSDimitry Andric /// Maps from register mask names to register masks.
1453dac3a9bSDimitry Andric StringMap<const uint32_t *> Names2RegMasks;
146875ed548SDimitry Andric /// Maps from subregister names to subregister indices.
147875ed548SDimitry Andric StringMap<unsigned> Names2SubRegIndices;
1487d523365SDimitry Andric /// Maps from slot numbers to function's unnamed basic blocks.
1497d523365SDimitry Andric DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
1507d523365SDimitry Andric /// Maps from slot numbers to function's unnamed values.
1517d523365SDimitry Andric DenseMap<unsigned, const Value *> Slots2Values;
1527d523365SDimitry Andric /// Maps from target index names to target indices.
1537d523365SDimitry Andric StringMap<int> Names2TargetIndices;
1547d523365SDimitry Andric /// Maps from direct target flag names to the direct target flag values.
1557d523365SDimitry Andric StringMap<unsigned> Names2DirectTargetFlags;
1567d523365SDimitry Andric /// Maps from direct target flag names to the bitmask target flag values.
1577d523365SDimitry Andric StringMap<unsigned> Names2BitmaskTargetFlags;
158c4394386SDimitry Andric /// Maps from MMO target flag names to MMO target flag values.
159c4394386SDimitry Andric StringMap<MachineMemOperand::Flags> Names2MMOTargetFlags;
1603dac3a9bSDimitry Andric
1613dac3a9bSDimitry Andric public:
162d88c1a5aSDimitry Andric MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
1633ca95b02SDimitry Andric StringRef Source);
1643dac3a9bSDimitry Andric
1653ca95b02SDimitry Andric /// \p SkipChar gives the number of characters to skip before looking
1663ca95b02SDimitry Andric /// for the next token.
1673ca95b02SDimitry Andric void lex(unsigned SkipChar = 0);
1683dac3a9bSDimitry Andric
1693dac3a9bSDimitry Andric /// Report an error at the current location with the given message.
1703dac3a9bSDimitry Andric ///
1713dac3a9bSDimitry Andric /// This function always return true.
1723dac3a9bSDimitry Andric bool error(const Twine &Msg);
1733dac3a9bSDimitry Andric
1743dac3a9bSDimitry Andric /// Report an error at the given location with the given message.
1753dac3a9bSDimitry Andric ///
1763dac3a9bSDimitry Andric /// This function always return true.
1773dac3a9bSDimitry Andric bool error(StringRef::iterator Loc, const Twine &Msg);
1783dac3a9bSDimitry Andric
1797d523365SDimitry Andric bool
1807d523365SDimitry Andric parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
1817d523365SDimitry Andric bool parseBasicBlocks();
1823dac3a9bSDimitry Andric bool parse(MachineInstr *&MI);
1837d523365SDimitry Andric bool parseStandaloneMBB(MachineBasicBlock *&MBB);
1847d523365SDimitry Andric bool parseStandaloneNamedRegister(unsigned &Reg);
185d88c1a5aSDimitry Andric bool parseStandaloneVirtualRegister(VRegInfo *&Info);
186d88c1a5aSDimitry Andric bool parseStandaloneRegister(unsigned &Reg);
1877d523365SDimitry Andric bool parseStandaloneStackObject(int &FI);
1887d523365SDimitry Andric bool parseStandaloneMDNode(MDNode *&Node);
1897d523365SDimitry Andric
1907d523365SDimitry Andric bool
1917d523365SDimitry Andric parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
1920f5676f4SDimitry Andric bool parseBasicBlock(MachineBasicBlock &MBB,
1930f5676f4SDimitry Andric MachineBasicBlock *&AddFalthroughFrom);
1947d523365SDimitry Andric bool parseBasicBlockLiveins(MachineBasicBlock &MBB);
1957d523365SDimitry Andric bool parseBasicBlockSuccessors(MachineBasicBlock &MBB);
1963dac3a9bSDimitry Andric
197d88c1a5aSDimitry Andric bool parseNamedRegister(unsigned &Reg);
198d88c1a5aSDimitry Andric bool parseVirtualRegister(VRegInfo *&Info);
1994ba319b5SDimitry Andric bool parseNamedVirtualRegister(VRegInfo *&Info);
200d88c1a5aSDimitry Andric bool parseRegister(unsigned &Reg, VRegInfo *&VRegInfo);
201875ed548SDimitry Andric bool parseRegisterFlag(unsigned &Flags);
2027a7e6055SDimitry Andric bool parseRegisterClassOrBank(VRegInfo &RegInfo);
203875ed548SDimitry Andric bool parseSubRegisterIndex(unsigned &SubReg);
2047d523365SDimitry Andric bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx);
2057d523365SDimitry Andric bool parseRegisterOperand(MachineOperand &Dest,
2067d523365SDimitry Andric Optional<unsigned> &TiedDefIdx, bool IsDef = false);
2073dac3a9bSDimitry Andric bool parseImmediateOperand(MachineOperand &Dest);
2084ba319b5SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
2097d523365SDimitry Andric const Constant *&C);
2107d523365SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
211d88c1a5aSDimitry Andric bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty);
2127d523365SDimitry Andric bool parseTypedImmediateOperand(MachineOperand &Dest);
2137d523365SDimitry Andric bool parseFPImmediateOperand(MachineOperand &Dest);
2143dac3a9bSDimitry Andric bool parseMBBReference(MachineBasicBlock *&MBB);
2153dac3a9bSDimitry Andric bool parseMBBOperand(MachineOperand &Dest);
2167d523365SDimitry Andric bool parseStackFrameIndex(int &FI);
2177d523365SDimitry Andric bool parseStackObjectOperand(MachineOperand &Dest);
2187d523365SDimitry Andric bool parseFixedStackFrameIndex(int &FI);
2197d523365SDimitry Andric bool parseFixedStackObjectOperand(MachineOperand &Dest);
2207d523365SDimitry Andric bool parseGlobalValue(GlobalValue *&GV);
2213dac3a9bSDimitry Andric bool parseGlobalAddressOperand(MachineOperand &Dest);
2227d523365SDimitry Andric bool parseConstantPoolIndexOperand(MachineOperand &Dest);
2233ca95b02SDimitry Andric bool parseSubRegisterIndexOperand(MachineOperand &Dest);
2247d523365SDimitry Andric bool parseJumpTableIndexOperand(MachineOperand &Dest);
2257d523365SDimitry Andric bool parseExternalSymbolOperand(MachineOperand &Dest);
226*b5893f02SDimitry Andric bool parseMCSymbolOperand(MachineOperand &Dest);
2277d523365SDimitry Andric bool parseMDNode(MDNode *&Node);
2284ba319b5SDimitry Andric bool parseDIExpression(MDNode *&Expr);
229*b5893f02SDimitry Andric bool parseDILocation(MDNode *&Expr);
2307d523365SDimitry Andric bool parseMetadataOperand(MachineOperand &Dest);
2317d523365SDimitry Andric bool parseCFIOffset(int &Offset);
2327d523365SDimitry Andric bool parseCFIRegister(unsigned &Reg);
2332cab237bSDimitry Andric bool parseCFIEscapeValues(std::string& Values);
2347d523365SDimitry Andric bool parseCFIOperand(MachineOperand &Dest);
2357d523365SDimitry Andric bool parseIRBlock(BasicBlock *&BB, const Function &F);
2367d523365SDimitry Andric bool parseBlockAddressOperand(MachineOperand &Dest);
237d88c1a5aSDimitry Andric bool parseIntrinsicOperand(MachineOperand &Dest);
238d88c1a5aSDimitry Andric bool parsePredicateOperand(MachineOperand &Dest);
2397d523365SDimitry Andric bool parseTargetIndexOperand(MachineOperand &Dest);
2407a7e6055SDimitry Andric bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
2417d523365SDimitry Andric bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
2427d523365SDimitry Andric bool parseMachineOperand(MachineOperand &Dest,
2437d523365SDimitry Andric Optional<unsigned> &TiedDefIdx);
2447d523365SDimitry Andric bool parseMachineOperandAndTargetFlags(MachineOperand &Dest,
2457d523365SDimitry Andric Optional<unsigned> &TiedDefIdx);
2467d523365SDimitry Andric bool parseOffset(int64_t &Offset);
2477d523365SDimitry Andric bool parseAlignment(unsigned &Alignment);
2484ba319b5SDimitry Andric bool parseAddrspace(unsigned &Addrspace);
2497d523365SDimitry Andric bool parseOperandsOffset(MachineOperand &Op);
2507d523365SDimitry Andric bool parseIRValue(const Value *&V);
2513ca95b02SDimitry Andric bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
2527d523365SDimitry Andric bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV);
2537d523365SDimitry Andric bool parseMachinePointerInfo(MachinePointerInfo &Dest);
254c4394386SDimitry Andric bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID);
2557a7e6055SDimitry Andric bool parseOptionalAtomicOrdering(AtomicOrdering &Order);
2567d523365SDimitry Andric bool parseMachineMemoryOperand(MachineMemOperand *&Dest);
257*b5893f02SDimitry Andric bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol);
2583dac3a9bSDimitry Andric
2593dac3a9bSDimitry Andric private:
2603dac3a9bSDimitry Andric /// Convert the integer literal in the current token into an unsigned integer.
2613dac3a9bSDimitry Andric ///
2623dac3a9bSDimitry Andric /// Return true if an error occurred.
2633dac3a9bSDimitry Andric bool getUnsigned(unsigned &Result);
2643dac3a9bSDimitry Andric
2657d523365SDimitry Andric /// Convert the integer literal in the current token into an uint64.
2667d523365SDimitry Andric ///
2677d523365SDimitry Andric /// Return true if an error occurred.
2687d523365SDimitry Andric bool getUint64(uint64_t &Result);
2697d523365SDimitry Andric
270d88c1a5aSDimitry Andric /// Convert the hexadecimal literal in the current token into an unsigned
271d88c1a5aSDimitry Andric /// APInt with a minimum bitwidth required to represent the value.
272d88c1a5aSDimitry Andric ///
273d88c1a5aSDimitry Andric /// Return true if the literal does not represent an integer value.
274d88c1a5aSDimitry Andric bool getHexUint(APInt &Result);
275d88c1a5aSDimitry Andric
2767d523365SDimitry Andric /// If the current token is of the given kind, consume it and return false.
2777d523365SDimitry Andric /// Otherwise report an error and return true.
2787d523365SDimitry Andric bool expectAndConsume(MIToken::TokenKind TokenKind);
2797d523365SDimitry Andric
2807d523365SDimitry Andric /// If the current token is of the given kind, consume it and return true.
2817d523365SDimitry Andric /// Otherwise return false.
2827d523365SDimitry Andric bool consumeIfPresent(MIToken::TokenKind TokenKind);
2837d523365SDimitry Andric
2843dac3a9bSDimitry Andric void initNames2InstrOpCodes();
2853dac3a9bSDimitry Andric
2863dac3a9bSDimitry Andric /// Try to convert an instruction name to an opcode. Return true if the
2873dac3a9bSDimitry Andric /// instruction name is invalid.
2883dac3a9bSDimitry Andric bool parseInstrName(StringRef InstrName, unsigned &OpCode);
2893dac3a9bSDimitry Andric
2907d523365SDimitry Andric bool parseInstruction(unsigned &OpCode, unsigned &Flags);
2913dac3a9bSDimitry Andric
2927d523365SDimitry Andric bool assignRegisterTies(MachineInstr &MI,
2937d523365SDimitry Andric ArrayRef<ParsedMachineOperand> Operands);
2947d523365SDimitry Andric
2957d523365SDimitry Andric bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
296875ed548SDimitry Andric const MCInstrDesc &MCID);
297875ed548SDimitry Andric
2983dac3a9bSDimitry Andric void initNames2Regs();
2993dac3a9bSDimitry Andric
3003dac3a9bSDimitry Andric /// Try to convert a register name to a register number. Return true if the
3013dac3a9bSDimitry Andric /// register name is invalid.
3023dac3a9bSDimitry Andric bool getRegisterByName(StringRef RegName, unsigned &Reg);
3033dac3a9bSDimitry Andric
3043dac3a9bSDimitry Andric void initNames2RegMasks();
3053dac3a9bSDimitry Andric
3063dac3a9bSDimitry Andric /// Check if the given identifier is a name of a register mask.
3073dac3a9bSDimitry Andric ///
3083dac3a9bSDimitry Andric /// Return null if the identifier isn't a register mask.
3093dac3a9bSDimitry Andric const uint32_t *getRegMask(StringRef Identifier);
310875ed548SDimitry Andric
311875ed548SDimitry Andric void initNames2SubRegIndices();
312875ed548SDimitry Andric
313875ed548SDimitry Andric /// Check if the given identifier is a name of a subregister index.
314875ed548SDimitry Andric ///
315875ed548SDimitry Andric /// Return 0 if the name isn't a subregister index class.
316875ed548SDimitry Andric unsigned getSubRegIndex(StringRef Name);
3177d523365SDimitry Andric
3187d523365SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot);
3197d523365SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot, const Function &F);
3207d523365SDimitry Andric
3217d523365SDimitry Andric const Value *getIRValue(unsigned Slot);
3227d523365SDimitry Andric
3237d523365SDimitry Andric void initNames2TargetIndices();
3247d523365SDimitry Andric
3257d523365SDimitry Andric /// Try to convert a name of target index to the corresponding target index.
3267d523365SDimitry Andric ///
3277d523365SDimitry Andric /// Return true if the name isn't a name of a target index.
3287d523365SDimitry Andric bool getTargetIndex(StringRef Name, int &Index);
3297d523365SDimitry Andric
3307d523365SDimitry Andric void initNames2DirectTargetFlags();
3317d523365SDimitry Andric
3327d523365SDimitry Andric /// Try to convert a name of a direct target flag to the corresponding
3337d523365SDimitry Andric /// target flag.
3347d523365SDimitry Andric ///
3357d523365SDimitry Andric /// Return true if the name isn't a name of a direct flag.
3367d523365SDimitry Andric bool getDirectTargetFlag(StringRef Name, unsigned &Flag);
3377d523365SDimitry Andric
3387d523365SDimitry Andric void initNames2BitmaskTargetFlags();
3397d523365SDimitry Andric
3407d523365SDimitry Andric /// Try to convert a name of a bitmask target flag to the corresponding
3417d523365SDimitry Andric /// target flag.
3427d523365SDimitry Andric ///
3437d523365SDimitry Andric /// Return true if the name isn't a name of a bitmask target flag.
3447d523365SDimitry Andric bool getBitmaskTargetFlag(StringRef Name, unsigned &Flag);
345c4394386SDimitry Andric
346c4394386SDimitry Andric void initNames2MMOTargetFlags();
347c4394386SDimitry Andric
348c4394386SDimitry Andric /// Try to convert a name of a MachineMemOperand target flag to the
349c4394386SDimitry Andric /// corresponding target flag.
350c4394386SDimitry Andric ///
351c4394386SDimitry Andric /// Return true if the name isn't a name of a target MMO flag.
352c4394386SDimitry Andric bool getMMOTargetFlag(StringRef Name, MachineMemOperand::Flags &Flag);
353c4394386SDimitry Andric
354*b5893f02SDimitry Andric /// Get or create an MCSymbol for a given name.
355*b5893f02SDimitry Andric MCSymbol *getOrCreateMCSymbol(StringRef Name);
356*b5893f02SDimitry Andric
357c4394386SDimitry Andric /// parseStringConstant
358c4394386SDimitry Andric /// ::= StringConstant
359c4394386SDimitry Andric bool parseStringConstant(std::string &Result);
3603dac3a9bSDimitry Andric };
3613dac3a9bSDimitry Andric
3623dac3a9bSDimitry Andric } // end anonymous namespace
3633dac3a9bSDimitry Andric
MIParser(PerFunctionMIParsingState & PFS,SMDiagnostic & Error,StringRef Source)364d88c1a5aSDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
3653ca95b02SDimitry Andric StringRef Source)
3663ca95b02SDimitry Andric : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS)
3673ca95b02SDimitry Andric {}
3683dac3a9bSDimitry Andric
lex(unsigned SkipChar)3693ca95b02SDimitry Andric void MIParser::lex(unsigned SkipChar) {
3703dac3a9bSDimitry Andric CurrentSource = lexMIToken(
3713ca95b02SDimitry Andric CurrentSource.data() + SkipChar, Token,
3723dac3a9bSDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); });
3733dac3a9bSDimitry Andric }
3743dac3a9bSDimitry Andric
error(const Twine & Msg)3753dac3a9bSDimitry Andric bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); }
3763dac3a9bSDimitry Andric
error(StringRef::iterator Loc,const Twine & Msg)3773dac3a9bSDimitry Andric bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
3783ca95b02SDimitry Andric const SourceMgr &SM = *PFS.SM;
3793dac3a9bSDimitry Andric assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
3807d523365SDimitry Andric const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID());
3817d523365SDimitry Andric if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) {
3827d523365SDimitry Andric // Create an ordinary diagnostic when the source manager's buffer is the
3837d523365SDimitry Andric // source string.
3847d523365SDimitry Andric Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
3853dac3a9bSDimitry Andric return true;
3863dac3a9bSDimitry Andric }
3877d523365SDimitry Andric // Create a diagnostic for a YAML string literal.
3887d523365SDimitry Andric Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1,
3897d523365SDimitry Andric Loc - Source.data(), SourceMgr::DK_Error, Msg.str(),
3907d523365SDimitry Andric Source, None, None);
3917d523365SDimitry Andric return true;
3927d523365SDimitry Andric }
3937d523365SDimitry Andric
toString(MIToken::TokenKind TokenKind)3947d523365SDimitry Andric static const char *toString(MIToken::TokenKind TokenKind) {
3957d523365SDimitry Andric switch (TokenKind) {
3967d523365SDimitry Andric case MIToken::comma:
3977d523365SDimitry Andric return "','";
3987d523365SDimitry Andric case MIToken::equal:
3997d523365SDimitry Andric return "'='";
4007d523365SDimitry Andric case MIToken::colon:
4017d523365SDimitry Andric return "':'";
4027d523365SDimitry Andric case MIToken::lparen:
4037d523365SDimitry Andric return "'('";
4047d523365SDimitry Andric case MIToken::rparen:
4057d523365SDimitry Andric return "')'";
4067d523365SDimitry Andric default:
4077d523365SDimitry Andric return "<unknown token>";
4087d523365SDimitry Andric }
4097d523365SDimitry Andric }
4107d523365SDimitry Andric
expectAndConsume(MIToken::TokenKind TokenKind)4117d523365SDimitry Andric bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) {
4127d523365SDimitry Andric if (Token.isNot(TokenKind))
4137d523365SDimitry Andric return error(Twine("expected ") + toString(TokenKind));
4147d523365SDimitry Andric lex();
4157d523365SDimitry Andric return false;
4167d523365SDimitry Andric }
4177d523365SDimitry Andric
consumeIfPresent(MIToken::TokenKind TokenKind)4187d523365SDimitry Andric bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) {
4197d523365SDimitry Andric if (Token.isNot(TokenKind))
4207d523365SDimitry Andric return false;
4217d523365SDimitry Andric lex();
4227d523365SDimitry Andric return true;
4237d523365SDimitry Andric }
4247d523365SDimitry Andric
parseBasicBlockDefinition(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)4257d523365SDimitry Andric bool MIParser::parseBasicBlockDefinition(
4267d523365SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
4277d523365SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
4287d523365SDimitry Andric unsigned ID = 0;
4297d523365SDimitry Andric if (getUnsigned(ID))
4307d523365SDimitry Andric return true;
4317d523365SDimitry Andric auto Loc = Token.location();
4327d523365SDimitry Andric auto Name = Token.stringValue();
4337d523365SDimitry Andric lex();
4347d523365SDimitry Andric bool HasAddressTaken = false;
4357d523365SDimitry Andric bool IsLandingPad = false;
4367d523365SDimitry Andric unsigned Alignment = 0;
4377d523365SDimitry Andric BasicBlock *BB = nullptr;
4387d523365SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
4397d523365SDimitry Andric do {
4407d523365SDimitry Andric // TODO: Report an error when multiple same attributes are specified.
4417d523365SDimitry Andric switch (Token.kind()) {
4427d523365SDimitry Andric case MIToken::kw_address_taken:
4437d523365SDimitry Andric HasAddressTaken = true;
4447d523365SDimitry Andric lex();
4457d523365SDimitry Andric break;
4467d523365SDimitry Andric case MIToken::kw_landing_pad:
4477d523365SDimitry Andric IsLandingPad = true;
4487d523365SDimitry Andric lex();
4497d523365SDimitry Andric break;
4507d523365SDimitry Andric case MIToken::kw_align:
4517d523365SDimitry Andric if (parseAlignment(Alignment))
4527d523365SDimitry Andric return true;
4537d523365SDimitry Andric break;
4547d523365SDimitry Andric case MIToken::IRBlock:
4557d523365SDimitry Andric // TODO: Report an error when both name and ir block are specified.
4562cab237bSDimitry Andric if (parseIRBlock(BB, MF.getFunction()))
4577d523365SDimitry Andric return true;
4587d523365SDimitry Andric lex();
4597d523365SDimitry Andric break;
4607d523365SDimitry Andric default:
4617d523365SDimitry Andric break;
4627d523365SDimitry Andric }
4637d523365SDimitry Andric } while (consumeIfPresent(MIToken::comma));
4647d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
4657d523365SDimitry Andric return true;
4667d523365SDimitry Andric }
4677d523365SDimitry Andric if (expectAndConsume(MIToken::colon))
4687d523365SDimitry Andric return true;
4697d523365SDimitry Andric
4707d523365SDimitry Andric if (!Name.empty()) {
4717d523365SDimitry Andric BB = dyn_cast_or_null<BasicBlock>(
4722cab237bSDimitry Andric MF.getFunction().getValueSymbolTable()->lookup(Name));
4737d523365SDimitry Andric if (!BB)
4747d523365SDimitry Andric return error(Loc, Twine("basic block '") + Name +
4757d523365SDimitry Andric "' is not defined in the function '" +
4767d523365SDimitry Andric MF.getName() + "'");
4777d523365SDimitry Andric }
4787d523365SDimitry Andric auto *MBB = MF.CreateMachineBasicBlock(BB);
4797d523365SDimitry Andric MF.insert(MF.end(), MBB);
4807d523365SDimitry Andric bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second;
4817d523365SDimitry Andric if (!WasInserted)
4827d523365SDimitry Andric return error(Loc, Twine("redefinition of machine basic block with id #") +
4837d523365SDimitry Andric Twine(ID));
4847d523365SDimitry Andric if (Alignment)
4857d523365SDimitry Andric MBB->setAlignment(Alignment);
4867d523365SDimitry Andric if (HasAddressTaken)
4877d523365SDimitry Andric MBB->setHasAddressTaken();
4887d523365SDimitry Andric MBB->setIsEHPad(IsLandingPad);
4897d523365SDimitry Andric return false;
4907d523365SDimitry Andric }
4917d523365SDimitry Andric
parseBasicBlockDefinitions(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)4927d523365SDimitry Andric bool MIParser::parseBasicBlockDefinitions(
4937d523365SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
4947d523365SDimitry Andric lex();
4957d523365SDimitry Andric // Skip until the first machine basic block.
4967d523365SDimitry Andric while (Token.is(MIToken::Newline))
4977d523365SDimitry Andric lex();
4987d523365SDimitry Andric if (Token.isErrorOrEOF())
4997d523365SDimitry Andric return Token.isError();
5007d523365SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlockLabel))
5017d523365SDimitry Andric return error("expected a basic block definition before instructions");
5027d523365SDimitry Andric unsigned BraceDepth = 0;
5037d523365SDimitry Andric do {
5047d523365SDimitry Andric if (parseBasicBlockDefinition(MBBSlots))
5057d523365SDimitry Andric return true;
5067d523365SDimitry Andric bool IsAfterNewline = false;
5077d523365SDimitry Andric // Skip until the next machine basic block.
5087d523365SDimitry Andric while (true) {
5097d523365SDimitry Andric if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) ||
5107d523365SDimitry Andric Token.isErrorOrEOF())
5117d523365SDimitry Andric break;
5127d523365SDimitry Andric else if (Token.is(MIToken::MachineBasicBlockLabel))
5137d523365SDimitry Andric return error("basic block definition should be located at the start of "
5147d523365SDimitry Andric "the line");
5157d523365SDimitry Andric else if (consumeIfPresent(MIToken::Newline)) {
5167d523365SDimitry Andric IsAfterNewline = true;
5177d523365SDimitry Andric continue;
5187d523365SDimitry Andric }
5197d523365SDimitry Andric IsAfterNewline = false;
5207d523365SDimitry Andric if (Token.is(MIToken::lbrace))
5217d523365SDimitry Andric ++BraceDepth;
5227d523365SDimitry Andric if (Token.is(MIToken::rbrace)) {
5237d523365SDimitry Andric if (!BraceDepth)
5247d523365SDimitry Andric return error("extraneous closing brace ('}')");
5257d523365SDimitry Andric --BraceDepth;
5267d523365SDimitry Andric }
5277d523365SDimitry Andric lex();
5287d523365SDimitry Andric }
5297d523365SDimitry Andric // Verify that we closed all of the '{' at the end of a file or a block.
5307d523365SDimitry Andric if (!Token.isError() && BraceDepth)
5317d523365SDimitry Andric return error("expected '}'"); // FIXME: Report a note that shows '{'.
5327d523365SDimitry Andric } while (!Token.isErrorOrEOF());
5337d523365SDimitry Andric return Token.isError();
5347d523365SDimitry Andric }
5357d523365SDimitry Andric
parseBasicBlockLiveins(MachineBasicBlock & MBB)5367d523365SDimitry Andric bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) {
5377d523365SDimitry Andric assert(Token.is(MIToken::kw_liveins));
5387d523365SDimitry Andric lex();
5397d523365SDimitry Andric if (expectAndConsume(MIToken::colon))
5407d523365SDimitry Andric return true;
5417d523365SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of liveins.
5427d523365SDimitry Andric return false;
5437d523365SDimitry Andric do {
5447d523365SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
5457d523365SDimitry Andric return error("expected a named register");
5467d523365SDimitry Andric unsigned Reg = 0;
547d88c1a5aSDimitry Andric if (parseNamedRegister(Reg))
5487d523365SDimitry Andric return true;
5497d523365SDimitry Andric lex();
550d88c1a5aSDimitry Andric LaneBitmask Mask = LaneBitmask::getAll();
551d88c1a5aSDimitry Andric if (consumeIfPresent(MIToken::colon)) {
552d88c1a5aSDimitry Andric // Parse lane mask.
553d88c1a5aSDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
554d88c1a5aSDimitry Andric Token.isNot(MIToken::HexLiteral))
555d88c1a5aSDimitry Andric return error("expected a lane mask");
556d88c1a5aSDimitry Andric static_assert(sizeof(LaneBitmask::Type) == sizeof(unsigned),
557d88c1a5aSDimitry Andric "Use correct get-function for lane mask");
558d88c1a5aSDimitry Andric LaneBitmask::Type V;
559d88c1a5aSDimitry Andric if (getUnsigned(V))
560d88c1a5aSDimitry Andric return error("invalid lane mask value");
561d88c1a5aSDimitry Andric Mask = LaneBitmask(V);
562d88c1a5aSDimitry Andric lex();
563d88c1a5aSDimitry Andric }
564d88c1a5aSDimitry Andric MBB.addLiveIn(Reg, Mask);
5657d523365SDimitry Andric } while (consumeIfPresent(MIToken::comma));
5667d523365SDimitry Andric return false;
5677d523365SDimitry Andric }
5687d523365SDimitry Andric
parseBasicBlockSuccessors(MachineBasicBlock & MBB)5697d523365SDimitry Andric bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) {
5707d523365SDimitry Andric assert(Token.is(MIToken::kw_successors));
5717d523365SDimitry Andric lex();
5727d523365SDimitry Andric if (expectAndConsume(MIToken::colon))
5737d523365SDimitry Andric return true;
5747d523365SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of successors.
5757d523365SDimitry Andric return false;
5767d523365SDimitry Andric do {
5777d523365SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock))
5787d523365SDimitry Andric return error("expected a machine basic block reference");
5797d523365SDimitry Andric MachineBasicBlock *SuccMBB = nullptr;
5807d523365SDimitry Andric if (parseMBBReference(SuccMBB))
5817d523365SDimitry Andric return true;
5827d523365SDimitry Andric lex();
5837d523365SDimitry Andric unsigned Weight = 0;
5847d523365SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
585d88c1a5aSDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
586d88c1a5aSDimitry Andric Token.isNot(MIToken::HexLiteral))
5877d523365SDimitry Andric return error("expected an integer literal after '('");
5887d523365SDimitry Andric if (getUnsigned(Weight))
5897d523365SDimitry Andric return true;
5907d523365SDimitry Andric lex();
5917d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
5927d523365SDimitry Andric return true;
5937d523365SDimitry Andric }
5947d523365SDimitry Andric MBB.addSuccessor(SuccMBB, BranchProbability::getRaw(Weight));
5957d523365SDimitry Andric } while (consumeIfPresent(MIToken::comma));
5967d523365SDimitry Andric MBB.normalizeSuccProbs();
5977d523365SDimitry Andric return false;
5987d523365SDimitry Andric }
5997d523365SDimitry Andric
parseBasicBlock(MachineBasicBlock & MBB,MachineBasicBlock * & AddFalthroughFrom)6000f5676f4SDimitry Andric bool MIParser::parseBasicBlock(MachineBasicBlock &MBB,
6010f5676f4SDimitry Andric MachineBasicBlock *&AddFalthroughFrom) {
6027d523365SDimitry Andric // Skip the definition.
6037d523365SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
6047d523365SDimitry Andric lex();
6057d523365SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
6067d523365SDimitry Andric while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF())
6077d523365SDimitry Andric lex();
6087d523365SDimitry Andric consumeIfPresent(MIToken::rparen);
6097d523365SDimitry Andric }
6107d523365SDimitry Andric consumeIfPresent(MIToken::colon);
6117d523365SDimitry Andric
6127d523365SDimitry Andric // Parse the liveins and successors.
6137d523365SDimitry Andric // N.B: Multiple lists of successors and liveins are allowed and they're
6147d523365SDimitry Andric // merged into one.
6157d523365SDimitry Andric // Example:
6167d523365SDimitry Andric // liveins: %edi
6177d523365SDimitry Andric // liveins: %esi
6187d523365SDimitry Andric //
6197d523365SDimitry Andric // is equivalent to
6207d523365SDimitry Andric // liveins: %edi, %esi
621a580b014SDimitry Andric bool ExplicitSuccessors = false;
6227d523365SDimitry Andric while (true) {
6237d523365SDimitry Andric if (Token.is(MIToken::kw_successors)) {
6247d523365SDimitry Andric if (parseBasicBlockSuccessors(MBB))
6257d523365SDimitry Andric return true;
626a580b014SDimitry Andric ExplicitSuccessors = true;
6277d523365SDimitry Andric } else if (Token.is(MIToken::kw_liveins)) {
6287d523365SDimitry Andric if (parseBasicBlockLiveins(MBB))
6297d523365SDimitry Andric return true;
6307d523365SDimitry Andric } else if (consumeIfPresent(MIToken::Newline)) {
6317d523365SDimitry Andric continue;
6327d523365SDimitry Andric } else
6337d523365SDimitry Andric break;
6347d523365SDimitry Andric if (!Token.isNewlineOrEOF())
6357d523365SDimitry Andric return error("expected line break at the end of a list");
6367d523365SDimitry Andric lex();
6377d523365SDimitry Andric }
6387d523365SDimitry Andric
6397d523365SDimitry Andric // Parse the instructions.
6407d523365SDimitry Andric bool IsInBundle = false;
6417d523365SDimitry Andric MachineInstr *PrevMI = nullptr;
6420f5676f4SDimitry Andric while (!Token.is(MIToken::MachineBasicBlockLabel) &&
6430f5676f4SDimitry Andric !Token.is(MIToken::Eof)) {
6440f5676f4SDimitry Andric if (consumeIfPresent(MIToken::Newline))
6457d523365SDimitry Andric continue;
6467d523365SDimitry Andric if (consumeIfPresent(MIToken::rbrace)) {
6477d523365SDimitry Andric // The first parsing pass should verify that all closing '}' have an
6487d523365SDimitry Andric // opening '{'.
6497d523365SDimitry Andric assert(IsInBundle);
6507d523365SDimitry Andric IsInBundle = false;
6517d523365SDimitry Andric continue;
6527d523365SDimitry Andric }
6537d523365SDimitry Andric MachineInstr *MI = nullptr;
6547d523365SDimitry Andric if (parse(MI))
6557d523365SDimitry Andric return true;
6567d523365SDimitry Andric MBB.insert(MBB.end(), MI);
6577d523365SDimitry Andric if (IsInBundle) {
6587d523365SDimitry Andric PrevMI->setFlag(MachineInstr::BundledSucc);
6597d523365SDimitry Andric MI->setFlag(MachineInstr::BundledPred);
6607d523365SDimitry Andric }
6617d523365SDimitry Andric PrevMI = MI;
6627d523365SDimitry Andric if (Token.is(MIToken::lbrace)) {
6637d523365SDimitry Andric if (IsInBundle)
6647d523365SDimitry Andric return error("nested instruction bundles are not allowed");
6657d523365SDimitry Andric lex();
6667d523365SDimitry Andric // This instruction is the start of the bundle.
6677d523365SDimitry Andric MI->setFlag(MachineInstr::BundledSucc);
6687d523365SDimitry Andric IsInBundle = true;
6697d523365SDimitry Andric if (!Token.is(MIToken::Newline))
6707d523365SDimitry Andric // The next instruction can be on the same line.
6717d523365SDimitry Andric continue;
6727d523365SDimitry Andric }
6737d523365SDimitry Andric assert(Token.isNewlineOrEOF() && "MI is not fully parsed");
6747d523365SDimitry Andric lex();
6757d523365SDimitry Andric }
6760f5676f4SDimitry Andric
6770f5676f4SDimitry Andric // Construct successor list by searching for basic block machine operands.
678a580b014SDimitry Andric if (!ExplicitSuccessors) {
6790f5676f4SDimitry Andric SmallVector<MachineBasicBlock*,4> Successors;
6800f5676f4SDimitry Andric bool IsFallthrough;
6810f5676f4SDimitry Andric guessSuccessors(MBB, Successors, IsFallthrough);
6820f5676f4SDimitry Andric for (MachineBasicBlock *Succ : Successors)
6830f5676f4SDimitry Andric MBB.addSuccessor(Succ);
6840f5676f4SDimitry Andric
6850f5676f4SDimitry Andric if (IsFallthrough) {
6860f5676f4SDimitry Andric AddFalthroughFrom = &MBB;
6870f5676f4SDimitry Andric } else {
6880f5676f4SDimitry Andric MBB.normalizeSuccProbs();
6890f5676f4SDimitry Andric }
6900f5676f4SDimitry Andric }
6910f5676f4SDimitry Andric
6927d523365SDimitry Andric return false;
6937d523365SDimitry Andric }
6947d523365SDimitry Andric
parseBasicBlocks()6957d523365SDimitry Andric bool MIParser::parseBasicBlocks() {
6967d523365SDimitry Andric lex();
6977d523365SDimitry Andric // Skip until the first machine basic block.
6987d523365SDimitry Andric while (Token.is(MIToken::Newline))
6997d523365SDimitry Andric lex();
7007d523365SDimitry Andric if (Token.isErrorOrEOF())
7017d523365SDimitry Andric return Token.isError();
7027d523365SDimitry Andric // The first parsing pass should have verified that this token is a MBB label
7037d523365SDimitry Andric // in the 'parseBasicBlockDefinitions' method.
7047d523365SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
7050f5676f4SDimitry Andric MachineBasicBlock *AddFalthroughFrom = nullptr;
7067d523365SDimitry Andric do {
7077d523365SDimitry Andric MachineBasicBlock *MBB = nullptr;
7087d523365SDimitry Andric if (parseMBBReference(MBB))
7097d523365SDimitry Andric return true;
7100f5676f4SDimitry Andric if (AddFalthroughFrom) {
7110f5676f4SDimitry Andric if (!AddFalthroughFrom->isSuccessor(MBB))
7120f5676f4SDimitry Andric AddFalthroughFrom->addSuccessor(MBB);
7130f5676f4SDimitry Andric AddFalthroughFrom->normalizeSuccProbs();
7140f5676f4SDimitry Andric AddFalthroughFrom = nullptr;
7150f5676f4SDimitry Andric }
7160f5676f4SDimitry Andric if (parseBasicBlock(*MBB, AddFalthroughFrom))
7177d523365SDimitry Andric return true;
7187d523365SDimitry Andric // The method 'parseBasicBlock' should parse the whole block until the next
7197d523365SDimitry Andric // block or the end of file.
7207d523365SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof));
7217d523365SDimitry Andric } while (Token.isNot(MIToken::Eof));
7227d523365SDimitry Andric return false;
7237d523365SDimitry Andric }
7243dac3a9bSDimitry Andric
parse(MachineInstr * & MI)7253dac3a9bSDimitry Andric bool MIParser::parse(MachineInstr *&MI) {
7263dac3a9bSDimitry Andric // Parse any register operands before '='
7273dac3a9bSDimitry Andric MachineOperand MO = MachineOperand::CreateImm(0);
7287d523365SDimitry Andric SmallVector<ParsedMachineOperand, 8> Operands;
7297d523365SDimitry Andric while (Token.isRegister() || Token.isRegisterFlag()) {
730875ed548SDimitry Andric auto Loc = Token.location();
7317d523365SDimitry Andric Optional<unsigned> TiedDefIdx;
7327d523365SDimitry Andric if (parseRegisterOperand(MO, TiedDefIdx, /*IsDef=*/true))
7333dac3a9bSDimitry Andric return true;
7347d523365SDimitry Andric Operands.push_back(
7357d523365SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
7367d523365SDimitry Andric if (Token.isNot(MIToken::comma))
7377d523365SDimitry Andric break;
7383dac3a9bSDimitry Andric lex();
7393dac3a9bSDimitry Andric }
7407d523365SDimitry Andric if (!Operands.empty() && expectAndConsume(MIToken::equal))
7413dac3a9bSDimitry Andric return true;
7423dac3a9bSDimitry Andric
7437d523365SDimitry Andric unsigned OpCode, Flags = 0;
7447d523365SDimitry Andric if (Token.isError() || parseInstruction(OpCode, Flags))
7457d523365SDimitry Andric return true;
7463dac3a9bSDimitry Andric
7473dac3a9bSDimitry Andric // Parse the remaining machine operands.
748*b5893f02SDimitry Andric while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) &&
749*b5893f02SDimitry Andric Token.isNot(MIToken::kw_post_instr_symbol) &&
750*b5893f02SDimitry Andric Token.isNot(MIToken::kw_debug_location) &&
7517d523365SDimitry Andric Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
752875ed548SDimitry Andric auto Loc = Token.location();
7537d523365SDimitry Andric Optional<unsigned> TiedDefIdx;
7547d523365SDimitry Andric if (parseMachineOperandAndTargetFlags(MO, TiedDefIdx))
7553dac3a9bSDimitry Andric return true;
756*b5893f02SDimitry Andric if (OpCode == TargetOpcode::DBG_VALUE && MO.isReg())
757*b5893f02SDimitry Andric MO.setIsDebug();
7587d523365SDimitry Andric Operands.push_back(
7597d523365SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
7607d523365SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
7617d523365SDimitry Andric Token.is(MIToken::lbrace))
7623dac3a9bSDimitry Andric break;
7633dac3a9bSDimitry Andric if (Token.isNot(MIToken::comma))
7643dac3a9bSDimitry Andric return error("expected ',' before the next machine operand");
7653dac3a9bSDimitry Andric lex();
7663dac3a9bSDimitry Andric }
7673dac3a9bSDimitry Andric
768*b5893f02SDimitry Andric MCSymbol *PreInstrSymbol = nullptr;
769*b5893f02SDimitry Andric if (Token.is(MIToken::kw_pre_instr_symbol))
770*b5893f02SDimitry Andric if (parsePreOrPostInstrSymbol(PreInstrSymbol))
771*b5893f02SDimitry Andric return true;
772*b5893f02SDimitry Andric MCSymbol *PostInstrSymbol = nullptr;
773*b5893f02SDimitry Andric if (Token.is(MIToken::kw_post_instr_symbol))
774*b5893f02SDimitry Andric if (parsePreOrPostInstrSymbol(PostInstrSymbol))
775*b5893f02SDimitry Andric return true;
776*b5893f02SDimitry Andric
7777d523365SDimitry Andric DebugLoc DebugLocation;
7787d523365SDimitry Andric if (Token.is(MIToken::kw_debug_location)) {
7797d523365SDimitry Andric lex();
7807d523365SDimitry Andric MDNode *Node = nullptr;
781*b5893f02SDimitry Andric if (Token.is(MIToken::exclaim)) {
7827d523365SDimitry Andric if (parseMDNode(Node))
7837d523365SDimitry Andric return true;
784*b5893f02SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
785*b5893f02SDimitry Andric if (parseDILocation(Node))
786*b5893f02SDimitry Andric return true;
787*b5893f02SDimitry Andric } else
788*b5893f02SDimitry Andric return error("expected a metadata node after 'debug-location'");
789*b5893f02SDimitry Andric if (!isa<DILocation>(Node))
790*b5893f02SDimitry Andric return error("referenced metadata is not a DILocation");
7917d523365SDimitry Andric DebugLocation = DebugLoc(Node);
7927d523365SDimitry Andric }
7937d523365SDimitry Andric
7947d523365SDimitry Andric // Parse the machine memory operands.
7957d523365SDimitry Andric SmallVector<MachineMemOperand *, 2> MemOperands;
7967d523365SDimitry Andric if (Token.is(MIToken::coloncolon)) {
7977d523365SDimitry Andric lex();
7987d523365SDimitry Andric while (!Token.isNewlineOrEOF()) {
7997d523365SDimitry Andric MachineMemOperand *MemOp = nullptr;
8007d523365SDimitry Andric if (parseMachineMemoryOperand(MemOp))
8017d523365SDimitry Andric return true;
8027d523365SDimitry Andric MemOperands.push_back(MemOp);
8037d523365SDimitry Andric if (Token.isNewlineOrEOF())
8047d523365SDimitry Andric break;
8057d523365SDimitry Andric if (Token.isNot(MIToken::comma))
8067d523365SDimitry Andric return error("expected ',' before the next machine memory operand");
8077d523365SDimitry Andric lex();
8087d523365SDimitry Andric }
8097d523365SDimitry Andric }
8107d523365SDimitry Andric
8113dac3a9bSDimitry Andric const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode);
8123dac3a9bSDimitry Andric if (!MCID.isVariadic()) {
813875ed548SDimitry Andric // FIXME: Move the implicit operand verification to the machine verifier.
814875ed548SDimitry Andric if (verifyImplicitOperands(Operands, MCID))
815875ed548SDimitry Andric return true;
8163dac3a9bSDimitry Andric }
8173dac3a9bSDimitry Andric
818875ed548SDimitry Andric // TODO: Check for extraneous machine operands.
8197d523365SDimitry Andric MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
8207d523365SDimitry Andric MI->setFlags(Flags);
8213dac3a9bSDimitry Andric for (const auto &Operand : Operands)
822875ed548SDimitry Andric MI->addOperand(MF, Operand.Operand);
8237d523365SDimitry Andric if (assignRegisterTies(*MI, Operands))
8247d523365SDimitry Andric return true;
825*b5893f02SDimitry Andric if (PreInstrSymbol)
826*b5893f02SDimitry Andric MI->setPreInstrSymbol(MF, PreInstrSymbol);
827*b5893f02SDimitry Andric if (PostInstrSymbol)
828*b5893f02SDimitry Andric MI->setPostInstrSymbol(MF, PostInstrSymbol);
829*b5893f02SDimitry Andric if (!MemOperands.empty())
830*b5893f02SDimitry Andric MI->setMemRefs(MF, MemOperands);
8313dac3a9bSDimitry Andric return false;
8323dac3a9bSDimitry Andric }
8333dac3a9bSDimitry Andric
parseStandaloneMBB(MachineBasicBlock * & MBB)8347d523365SDimitry Andric bool MIParser::parseStandaloneMBB(MachineBasicBlock *&MBB) {
8353dac3a9bSDimitry Andric lex();
8363dac3a9bSDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock))
8373dac3a9bSDimitry Andric return error("expected a machine basic block reference");
8383dac3a9bSDimitry Andric if (parseMBBReference(MBB))
8393dac3a9bSDimitry Andric return true;
8403dac3a9bSDimitry Andric lex();
8413dac3a9bSDimitry Andric if (Token.isNot(MIToken::Eof))
8423dac3a9bSDimitry Andric return error(
8433dac3a9bSDimitry Andric "expected end of string after the machine basic block reference");
8443dac3a9bSDimitry Andric return false;
8453dac3a9bSDimitry Andric }
8463dac3a9bSDimitry Andric
parseStandaloneNamedRegister(unsigned & Reg)8477d523365SDimitry Andric bool MIParser::parseStandaloneNamedRegister(unsigned &Reg) {
848875ed548SDimitry Andric lex();
849875ed548SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
850875ed548SDimitry Andric return error("expected a named register");
851d88c1a5aSDimitry Andric if (parseNamedRegister(Reg))
8527d523365SDimitry Andric return true;
853875ed548SDimitry Andric lex();
854875ed548SDimitry Andric if (Token.isNot(MIToken::Eof))
855875ed548SDimitry Andric return error("expected end of string after the register reference");
856875ed548SDimitry Andric return false;
857875ed548SDimitry Andric }
858875ed548SDimitry Andric
parseStandaloneVirtualRegister(VRegInfo * & Info)859d88c1a5aSDimitry Andric bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) {
8607d523365SDimitry Andric lex();
8617d523365SDimitry Andric if (Token.isNot(MIToken::VirtualRegister))
8627d523365SDimitry Andric return error("expected a virtual register");
863d88c1a5aSDimitry Andric if (parseVirtualRegister(Info))
8647d523365SDimitry Andric return true;
8657d523365SDimitry Andric lex();
8667d523365SDimitry Andric if (Token.isNot(MIToken::Eof))
8677d523365SDimitry Andric return error("expected end of string after the register reference");
8687d523365SDimitry Andric return false;
8697d523365SDimitry Andric }
8707d523365SDimitry Andric
parseStandaloneRegister(unsigned & Reg)871d88c1a5aSDimitry Andric bool MIParser::parseStandaloneRegister(unsigned &Reg) {
872d88c1a5aSDimitry Andric lex();
873d88c1a5aSDimitry Andric if (Token.isNot(MIToken::NamedRegister) &&
874d88c1a5aSDimitry Andric Token.isNot(MIToken::VirtualRegister))
875d88c1a5aSDimitry Andric return error("expected either a named or virtual register");
876d88c1a5aSDimitry Andric
877d88c1a5aSDimitry Andric VRegInfo *Info;
878d88c1a5aSDimitry Andric if (parseRegister(Reg, Info))
879d88c1a5aSDimitry Andric return true;
880d88c1a5aSDimitry Andric
881d88c1a5aSDimitry Andric lex();
882d88c1a5aSDimitry Andric if (Token.isNot(MIToken::Eof))
883d88c1a5aSDimitry Andric return error("expected end of string after the register reference");
884d88c1a5aSDimitry Andric return false;
885d88c1a5aSDimitry Andric }
886d88c1a5aSDimitry Andric
parseStandaloneStackObject(int & FI)8877d523365SDimitry Andric bool MIParser::parseStandaloneStackObject(int &FI) {
8887d523365SDimitry Andric lex();
8897d523365SDimitry Andric if (Token.isNot(MIToken::StackObject))
8907d523365SDimitry Andric return error("expected a stack object");
8917d523365SDimitry Andric if (parseStackFrameIndex(FI))
8927d523365SDimitry Andric return true;
8937d523365SDimitry Andric if (Token.isNot(MIToken::Eof))
8947d523365SDimitry Andric return error("expected end of string after the stack object reference");
8957d523365SDimitry Andric return false;
8967d523365SDimitry Andric }
8977d523365SDimitry Andric
parseStandaloneMDNode(MDNode * & Node)8987d523365SDimitry Andric bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
8997d523365SDimitry Andric lex();
9002cab237bSDimitry Andric if (Token.is(MIToken::exclaim)) {
9017d523365SDimitry Andric if (parseMDNode(Node))
9027d523365SDimitry Andric return true;
9032cab237bSDimitry Andric } else if (Token.is(MIToken::md_diexpr)) {
9042cab237bSDimitry Andric if (parseDIExpression(Node))
9052cab237bSDimitry Andric return true;
906*b5893f02SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
907*b5893f02SDimitry Andric if (parseDILocation(Node))
908*b5893f02SDimitry Andric return true;
9092cab237bSDimitry Andric } else
9102cab237bSDimitry Andric return error("expected a metadata node");
9117d523365SDimitry Andric if (Token.isNot(MIToken::Eof))
9127d523365SDimitry Andric return error("expected end of string after the metadata node");
9137d523365SDimitry Andric return false;
9147d523365SDimitry Andric }
9157d523365SDimitry Andric
printImplicitRegisterFlag(const MachineOperand & MO)916875ed548SDimitry Andric static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
917875ed548SDimitry Andric assert(MO.isImplicit());
918875ed548SDimitry Andric return MO.isDef() ? "implicit-def" : "implicit";
919875ed548SDimitry Andric }
920875ed548SDimitry Andric
getRegisterName(const TargetRegisterInfo * TRI,unsigned Reg)921875ed548SDimitry Andric static std::string getRegisterName(const TargetRegisterInfo *TRI,
922875ed548SDimitry Andric unsigned Reg) {
923875ed548SDimitry Andric assert(TargetRegisterInfo::isPhysicalRegister(Reg) && "expected phys reg");
924875ed548SDimitry Andric return StringRef(TRI->getName(Reg)).lower();
925875ed548SDimitry Andric }
926875ed548SDimitry Andric
9277d523365SDimitry Andric /// Return true if the parsed machine operands contain a given machine operand.
isImplicitOperandIn(const MachineOperand & ImplicitOperand,ArrayRef<ParsedMachineOperand> Operands)9287d523365SDimitry Andric static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand,
9297d523365SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) {
9307d523365SDimitry Andric for (const auto &I : Operands) {
9317d523365SDimitry Andric if (ImplicitOperand.isIdenticalTo(I.Operand))
9327d523365SDimitry Andric return true;
9337d523365SDimitry Andric }
9347d523365SDimitry Andric return false;
9357d523365SDimitry Andric }
9367d523365SDimitry Andric
verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,const MCInstrDesc & MCID)9377d523365SDimitry Andric bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
9387d523365SDimitry Andric const MCInstrDesc &MCID) {
939875ed548SDimitry Andric if (MCID.isCall())
940875ed548SDimitry Andric // We can't verify call instructions as they can contain arbitrary implicit
941875ed548SDimitry Andric // register and register mask operands.
942875ed548SDimitry Andric return false;
943875ed548SDimitry Andric
944875ed548SDimitry Andric // Gather all the expected implicit operands.
945875ed548SDimitry Andric SmallVector<MachineOperand, 4> ImplicitOperands;
946875ed548SDimitry Andric if (MCID.ImplicitDefs)
9477d523365SDimitry Andric for (const MCPhysReg *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs)
948875ed548SDimitry Andric ImplicitOperands.push_back(
949875ed548SDimitry Andric MachineOperand::CreateReg(*ImpDefs, true, true));
950875ed548SDimitry Andric if (MCID.ImplicitUses)
9517d523365SDimitry Andric for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses)
952875ed548SDimitry Andric ImplicitOperands.push_back(
953875ed548SDimitry Andric MachineOperand::CreateReg(*ImpUses, false, true));
954875ed548SDimitry Andric
955875ed548SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
956875ed548SDimitry Andric assert(TRI && "Expected target register info");
9577d523365SDimitry Andric for (const auto &I : ImplicitOperands) {
9587d523365SDimitry Andric if (isImplicitOperandIn(I, Operands))
959875ed548SDimitry Andric continue;
9607d523365SDimitry Andric return error(Operands.empty() ? Token.location() : Operands.back().End,
961875ed548SDimitry Andric Twine("missing implicit register operand '") +
9624ba319b5SDimitry Andric printImplicitRegisterFlag(I) + " $" +
9637d523365SDimitry Andric getRegisterName(TRI, I.getReg()) + "'");
964875ed548SDimitry Andric }
965875ed548SDimitry Andric return false;
966875ed548SDimitry Andric }
967875ed548SDimitry Andric
parseInstruction(unsigned & OpCode,unsigned & Flags)9687d523365SDimitry Andric bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
9694ba319b5SDimitry Andric // Allow frame and fast math flags for OPCODE
9704ba319b5SDimitry Andric while (Token.is(MIToken::kw_frame_setup) ||
9714ba319b5SDimitry Andric Token.is(MIToken::kw_frame_destroy) ||
9724ba319b5SDimitry Andric Token.is(MIToken::kw_nnan) ||
9734ba319b5SDimitry Andric Token.is(MIToken::kw_ninf) ||
9744ba319b5SDimitry Andric Token.is(MIToken::kw_nsz) ||
9754ba319b5SDimitry Andric Token.is(MIToken::kw_arcp) ||
9764ba319b5SDimitry Andric Token.is(MIToken::kw_contract) ||
9774ba319b5SDimitry Andric Token.is(MIToken::kw_afn) ||
978*b5893f02SDimitry Andric Token.is(MIToken::kw_reassoc) ||
979*b5893f02SDimitry Andric Token.is(MIToken::kw_nuw) ||
980*b5893f02SDimitry Andric Token.is(MIToken::kw_nsw) ||
981*b5893f02SDimitry Andric Token.is(MIToken::kw_exact)) {
9824ba319b5SDimitry Andric // Mine frame and fast math flags
9834ba319b5SDimitry Andric if (Token.is(MIToken::kw_frame_setup))
9847d523365SDimitry Andric Flags |= MachineInstr::FrameSetup;
9854ba319b5SDimitry Andric if (Token.is(MIToken::kw_frame_destroy))
9864ba319b5SDimitry Andric Flags |= MachineInstr::FrameDestroy;
9874ba319b5SDimitry Andric if (Token.is(MIToken::kw_nnan))
9884ba319b5SDimitry Andric Flags |= MachineInstr::FmNoNans;
9894ba319b5SDimitry Andric if (Token.is(MIToken::kw_ninf))
9904ba319b5SDimitry Andric Flags |= MachineInstr::FmNoInfs;
9914ba319b5SDimitry Andric if (Token.is(MIToken::kw_nsz))
9924ba319b5SDimitry Andric Flags |= MachineInstr::FmNsz;
9934ba319b5SDimitry Andric if (Token.is(MIToken::kw_arcp))
9944ba319b5SDimitry Andric Flags |= MachineInstr::FmArcp;
9954ba319b5SDimitry Andric if (Token.is(MIToken::kw_contract))
9964ba319b5SDimitry Andric Flags |= MachineInstr::FmContract;
9974ba319b5SDimitry Andric if (Token.is(MIToken::kw_afn))
9984ba319b5SDimitry Andric Flags |= MachineInstr::FmAfn;
9994ba319b5SDimitry Andric if (Token.is(MIToken::kw_reassoc))
10004ba319b5SDimitry Andric Flags |= MachineInstr::FmReassoc;
1001*b5893f02SDimitry Andric if (Token.is(MIToken::kw_nuw))
1002*b5893f02SDimitry Andric Flags |= MachineInstr::NoUWrap;
1003*b5893f02SDimitry Andric if (Token.is(MIToken::kw_nsw))
1004*b5893f02SDimitry Andric Flags |= MachineInstr::NoSWrap;
1005*b5893f02SDimitry Andric if (Token.is(MIToken::kw_exact))
1006*b5893f02SDimitry Andric Flags |= MachineInstr::IsExact;
10074ba319b5SDimitry Andric
10087d523365SDimitry Andric lex();
10097d523365SDimitry Andric }
10103dac3a9bSDimitry Andric if (Token.isNot(MIToken::Identifier))
10113dac3a9bSDimitry Andric return error("expected a machine instruction");
10123dac3a9bSDimitry Andric StringRef InstrName = Token.stringValue();
10133dac3a9bSDimitry Andric if (parseInstrName(InstrName, OpCode))
10143dac3a9bSDimitry Andric return error(Twine("unknown machine instruction name '") + InstrName + "'");
10153dac3a9bSDimitry Andric lex();
10163dac3a9bSDimitry Andric return false;
10173dac3a9bSDimitry Andric }
10183dac3a9bSDimitry Andric
parseNamedRegister(unsigned & Reg)1019d88c1a5aSDimitry Andric bool MIParser::parseNamedRegister(unsigned &Reg) {
1020d88c1a5aSDimitry Andric assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token");
10213dac3a9bSDimitry Andric StringRef Name = Token.stringValue();
10223dac3a9bSDimitry Andric if (getRegisterByName(Name, Reg))
10233dac3a9bSDimitry Andric return error(Twine("unknown register name '") + Name + "'");
1024d88c1a5aSDimitry Andric return false;
10253dac3a9bSDimitry Andric }
1026d88c1a5aSDimitry Andric
parseNamedVirtualRegister(VRegInfo * & Info)10274ba319b5SDimitry Andric bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) {
10284ba319b5SDimitry Andric assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token");
10294ba319b5SDimitry Andric StringRef Name = Token.stringValue();
10304ba319b5SDimitry Andric // TODO: Check that the VReg name is not the same as a physical register name.
10314ba319b5SDimitry Andric // If it is, then print a warning (when warnings are implemented).
10324ba319b5SDimitry Andric Info = &PFS.getVRegInfoNamed(Name);
10334ba319b5SDimitry Andric return false;
10344ba319b5SDimitry Andric }
10354ba319b5SDimitry Andric
parseVirtualRegister(VRegInfo * & Info)1036d88c1a5aSDimitry Andric bool MIParser::parseVirtualRegister(VRegInfo *&Info) {
10374ba319b5SDimitry Andric if (Token.is(MIToken::NamedVirtualRegister))
10384ba319b5SDimitry Andric return parseNamedVirtualRegister(Info);
1039d88c1a5aSDimitry Andric assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token");
1040875ed548SDimitry Andric unsigned ID;
1041875ed548SDimitry Andric if (getUnsigned(ID))
1042875ed548SDimitry Andric return true;
1043d88c1a5aSDimitry Andric Info = &PFS.getVRegInfo(ID);
1044d88c1a5aSDimitry Andric return false;
1045875ed548SDimitry Andric }
1046d88c1a5aSDimitry Andric
parseRegister(unsigned & Reg,VRegInfo * & Info)1047d88c1a5aSDimitry Andric bool MIParser::parseRegister(unsigned &Reg, VRegInfo *&Info) {
1048d88c1a5aSDimitry Andric switch (Token.kind()) {
1049d88c1a5aSDimitry Andric case MIToken::underscore:
1050d88c1a5aSDimitry Andric Reg = 0;
1051d88c1a5aSDimitry Andric return false;
1052d88c1a5aSDimitry Andric case MIToken::NamedRegister:
1053d88c1a5aSDimitry Andric return parseNamedRegister(Reg);
10544ba319b5SDimitry Andric case MIToken::NamedVirtualRegister:
1055d88c1a5aSDimitry Andric case MIToken::VirtualRegister:
1056d88c1a5aSDimitry Andric if (parseVirtualRegister(Info))
1057d88c1a5aSDimitry Andric return true;
1058d88c1a5aSDimitry Andric Reg = Info->VReg;
1059d88c1a5aSDimitry Andric return false;
10603dac3a9bSDimitry Andric // TODO: Parse other register kinds.
10613dac3a9bSDimitry Andric default:
10623dac3a9bSDimitry Andric llvm_unreachable("The current token should be a register");
10633dac3a9bSDimitry Andric }
10643dac3a9bSDimitry Andric }
10653dac3a9bSDimitry Andric
parseRegisterClassOrBank(VRegInfo & RegInfo)10667a7e6055SDimitry Andric bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
10677a7e6055SDimitry Andric if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore))
10687a7e6055SDimitry Andric return error("expected '_', register class, or register bank name");
10697a7e6055SDimitry Andric StringRef::iterator Loc = Token.location();
10707a7e6055SDimitry Andric StringRef Name = Token.stringValue();
10717a7e6055SDimitry Andric
10727a7e6055SDimitry Andric // Was it a register class?
10737a7e6055SDimitry Andric auto RCNameI = PFS.Names2RegClasses.find(Name);
10747a7e6055SDimitry Andric if (RCNameI != PFS.Names2RegClasses.end()) {
10757a7e6055SDimitry Andric lex();
10767a7e6055SDimitry Andric const TargetRegisterClass &RC = *RCNameI->getValue();
10777a7e6055SDimitry Andric
10787a7e6055SDimitry Andric switch (RegInfo.Kind) {
10797a7e6055SDimitry Andric case VRegInfo::UNKNOWN:
10807a7e6055SDimitry Andric case VRegInfo::NORMAL:
10817a7e6055SDimitry Andric RegInfo.Kind = VRegInfo::NORMAL;
10827a7e6055SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RC != &RC) {
10837a7e6055SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
10847a7e6055SDimitry Andric return error(Loc, Twine("conflicting register classes, previously: ") +
10857a7e6055SDimitry Andric Twine(TRI.getRegClassName(RegInfo.D.RC)));
10867a7e6055SDimitry Andric }
10877a7e6055SDimitry Andric RegInfo.D.RC = &RC;
10887a7e6055SDimitry Andric RegInfo.Explicit = true;
10897a7e6055SDimitry Andric return false;
10907a7e6055SDimitry Andric
10917a7e6055SDimitry Andric case VRegInfo::GENERIC:
10927a7e6055SDimitry Andric case VRegInfo::REGBANK:
10937a7e6055SDimitry Andric return error(Loc, "register class specification on generic register");
10947a7e6055SDimitry Andric }
10957a7e6055SDimitry Andric llvm_unreachable("Unexpected register kind");
10967a7e6055SDimitry Andric }
10977a7e6055SDimitry Andric
10987a7e6055SDimitry Andric // Should be a register bank or a generic register.
10997a7e6055SDimitry Andric const RegisterBank *RegBank = nullptr;
11007a7e6055SDimitry Andric if (Name != "_") {
11017a7e6055SDimitry Andric auto RBNameI = PFS.Names2RegBanks.find(Name);
11027a7e6055SDimitry Andric if (RBNameI == PFS.Names2RegBanks.end())
11037a7e6055SDimitry Andric return error(Loc, "expected '_', register class, or register bank name");
11047a7e6055SDimitry Andric RegBank = RBNameI->getValue();
11057a7e6055SDimitry Andric }
11067a7e6055SDimitry Andric
11077a7e6055SDimitry Andric lex();
11087a7e6055SDimitry Andric
11097a7e6055SDimitry Andric switch (RegInfo.Kind) {
11107a7e6055SDimitry Andric case VRegInfo::UNKNOWN:
11117a7e6055SDimitry Andric case VRegInfo::GENERIC:
11127a7e6055SDimitry Andric case VRegInfo::REGBANK:
11137a7e6055SDimitry Andric RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC;
11147a7e6055SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank)
11157a7e6055SDimitry Andric return error(Loc, "conflicting generic register banks");
11167a7e6055SDimitry Andric RegInfo.D.RegBank = RegBank;
11177a7e6055SDimitry Andric RegInfo.Explicit = true;
11187a7e6055SDimitry Andric return false;
11197a7e6055SDimitry Andric
11207a7e6055SDimitry Andric case VRegInfo::NORMAL:
11217a7e6055SDimitry Andric return error(Loc, "register bank specification on normal register");
11227a7e6055SDimitry Andric }
11237a7e6055SDimitry Andric llvm_unreachable("Unexpected register kind");
11247a7e6055SDimitry Andric }
11257a7e6055SDimitry Andric
parseRegisterFlag(unsigned & Flags)1126875ed548SDimitry Andric bool MIParser::parseRegisterFlag(unsigned &Flags) {
11277d523365SDimitry Andric const unsigned OldFlags = Flags;
1128875ed548SDimitry Andric switch (Token.kind()) {
1129875ed548SDimitry Andric case MIToken::kw_implicit:
1130875ed548SDimitry Andric Flags |= RegState::Implicit;
1131875ed548SDimitry Andric break;
1132875ed548SDimitry Andric case MIToken::kw_implicit_define:
1133875ed548SDimitry Andric Flags |= RegState::ImplicitDefine;
1134875ed548SDimitry Andric break;
11357d523365SDimitry Andric case MIToken::kw_def:
11367d523365SDimitry Andric Flags |= RegState::Define;
11377d523365SDimitry Andric break;
1138875ed548SDimitry Andric case MIToken::kw_dead:
1139875ed548SDimitry Andric Flags |= RegState::Dead;
1140875ed548SDimitry Andric break;
1141875ed548SDimitry Andric case MIToken::kw_killed:
1142875ed548SDimitry Andric Flags |= RegState::Kill;
1143875ed548SDimitry Andric break;
1144875ed548SDimitry Andric case MIToken::kw_undef:
1145875ed548SDimitry Andric Flags |= RegState::Undef;
1146875ed548SDimitry Andric break;
11477d523365SDimitry Andric case MIToken::kw_internal:
11487d523365SDimitry Andric Flags |= RegState::InternalRead;
11497d523365SDimitry Andric break;
11507d523365SDimitry Andric case MIToken::kw_early_clobber:
11517d523365SDimitry Andric Flags |= RegState::EarlyClobber;
11527d523365SDimitry Andric break;
11537d523365SDimitry Andric case MIToken::kw_debug_use:
11547d523365SDimitry Andric Flags |= RegState::Debug;
11557d523365SDimitry Andric break;
11562cab237bSDimitry Andric case MIToken::kw_renamable:
11572cab237bSDimitry Andric Flags |= RegState::Renamable;
11582cab237bSDimitry Andric break;
1159875ed548SDimitry Andric default:
1160875ed548SDimitry Andric llvm_unreachable("The current token should be a register flag");
1161875ed548SDimitry Andric }
11627d523365SDimitry Andric if (OldFlags == Flags)
11637d523365SDimitry Andric // We know that the same flag is specified more than once when the flags
11647d523365SDimitry Andric // weren't modified.
11657d523365SDimitry Andric return error("duplicate '" + Token.stringValue() + "' register flag");
1166875ed548SDimitry Andric lex();
1167875ed548SDimitry Andric return false;
1168875ed548SDimitry Andric }
1169875ed548SDimitry Andric
parseSubRegisterIndex(unsigned & SubReg)1170875ed548SDimitry Andric bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
1171d88c1a5aSDimitry Andric assert(Token.is(MIToken::dot));
1172875ed548SDimitry Andric lex();
1173875ed548SDimitry Andric if (Token.isNot(MIToken::Identifier))
1174d88c1a5aSDimitry Andric return error("expected a subregister index after '.'");
1175875ed548SDimitry Andric auto Name = Token.stringValue();
1176875ed548SDimitry Andric SubReg = getSubRegIndex(Name);
1177875ed548SDimitry Andric if (!SubReg)
1178875ed548SDimitry Andric return error(Twine("use of unknown subregister index '") + Name + "'");
1179875ed548SDimitry Andric lex();
1180875ed548SDimitry Andric return false;
1181875ed548SDimitry Andric }
1182875ed548SDimitry Andric
parseRegisterTiedDefIndex(unsigned & TiedDefIdx)11837d523365SDimitry Andric bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
11847d523365SDimitry Andric if (!consumeIfPresent(MIToken::kw_tied_def))
1185d88c1a5aSDimitry Andric return true;
11867d523365SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
11877d523365SDimitry Andric return error("expected an integer literal after 'tied-def'");
11887d523365SDimitry Andric if (getUnsigned(TiedDefIdx))
11897d523365SDimitry Andric return true;
11907d523365SDimitry Andric lex();
11917d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
11927d523365SDimitry Andric return true;
11937d523365SDimitry Andric return false;
11947d523365SDimitry Andric }
11957d523365SDimitry Andric
assignRegisterTies(MachineInstr & MI,ArrayRef<ParsedMachineOperand> Operands)11967d523365SDimitry Andric bool MIParser::assignRegisterTies(MachineInstr &MI,
11977d523365SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) {
11987d523365SDimitry Andric SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs;
11997d523365SDimitry Andric for (unsigned I = 0, E = Operands.size(); I != E; ++I) {
12007d523365SDimitry Andric if (!Operands[I].TiedDefIdx)
12017d523365SDimitry Andric continue;
12027d523365SDimitry Andric // The parser ensures that this operand is a register use, so we just have
12037d523365SDimitry Andric // to check the tied-def operand.
12047d523365SDimitry Andric unsigned DefIdx = Operands[I].TiedDefIdx.getValue();
12057d523365SDimitry Andric if (DefIdx >= E)
12067d523365SDimitry Andric return error(Operands[I].Begin,
12077d523365SDimitry Andric Twine("use of invalid tied-def operand index '" +
12087d523365SDimitry Andric Twine(DefIdx) + "'; instruction has only ") +
12097d523365SDimitry Andric Twine(E) + " operands");
12107d523365SDimitry Andric const auto &DefOperand = Operands[DefIdx].Operand;
12117d523365SDimitry Andric if (!DefOperand.isReg() || !DefOperand.isDef())
12127d523365SDimitry Andric // FIXME: add note with the def operand.
12137d523365SDimitry Andric return error(Operands[I].Begin,
12147d523365SDimitry Andric Twine("use of invalid tied-def operand index '") +
12157d523365SDimitry Andric Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) +
12167d523365SDimitry Andric " isn't a defined register");
12177d523365SDimitry Andric // Check that the tied-def operand wasn't tied elsewhere.
12187d523365SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs) {
12197d523365SDimitry Andric if (TiedPair.first == DefIdx)
12207d523365SDimitry Andric return error(Operands[I].Begin,
12217d523365SDimitry Andric Twine("the tied-def operand #") + Twine(DefIdx) +
12227d523365SDimitry Andric " is already tied with another register operand");
12237d523365SDimitry Andric }
12247d523365SDimitry Andric TiedRegisterPairs.push_back(std::make_pair(DefIdx, I));
12257d523365SDimitry Andric }
12267d523365SDimitry Andric // FIXME: Verify that for non INLINEASM instructions, the def and use tied
12277d523365SDimitry Andric // indices must be less than tied max.
12287d523365SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs)
12297d523365SDimitry Andric MI.tieOperands(TiedPair.first, TiedPair.second);
12307d523365SDimitry Andric return false;
12317d523365SDimitry Andric }
12327d523365SDimitry Andric
parseRegisterOperand(MachineOperand & Dest,Optional<unsigned> & TiedDefIdx,bool IsDef)12337d523365SDimitry Andric bool MIParser::parseRegisterOperand(MachineOperand &Dest,
12347d523365SDimitry Andric Optional<unsigned> &TiedDefIdx,
12357d523365SDimitry Andric bool IsDef) {
1236875ed548SDimitry Andric unsigned Flags = IsDef ? RegState::Define : 0;
1237875ed548SDimitry Andric while (Token.isRegisterFlag()) {
1238875ed548SDimitry Andric if (parseRegisterFlag(Flags))
1239875ed548SDimitry Andric return true;
1240875ed548SDimitry Andric }
1241875ed548SDimitry Andric if (!Token.isRegister())
1242875ed548SDimitry Andric return error("expected a register after register flags");
1243d88c1a5aSDimitry Andric unsigned Reg;
1244d88c1a5aSDimitry Andric VRegInfo *RegInfo;
1245d88c1a5aSDimitry Andric if (parseRegister(Reg, RegInfo))
12463dac3a9bSDimitry Andric return true;
12473dac3a9bSDimitry Andric lex();
1248875ed548SDimitry Andric unsigned SubReg = 0;
1249d88c1a5aSDimitry Andric if (Token.is(MIToken::dot)) {
1250875ed548SDimitry Andric if (parseSubRegisterIndex(SubReg))
1251875ed548SDimitry Andric return true;
12523ca95b02SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg))
12533ca95b02SDimitry Andric return error("subregister index expects a virtual register");
1254875ed548SDimitry Andric }
12557a7e6055SDimitry Andric if (Token.is(MIToken::colon)) {
12567a7e6055SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg))
12577a7e6055SDimitry Andric return error("register class specification expects a virtual register");
12587a7e6055SDimitry Andric lex();
12597a7e6055SDimitry Andric if (parseRegisterClassOrBank(*RegInfo))
12607a7e6055SDimitry Andric return true;
12617a7e6055SDimitry Andric }
1262d88c1a5aSDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
12633ca95b02SDimitry Andric if ((Flags & RegState::Define) == 0) {
12643ca95b02SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
12657d523365SDimitry Andric unsigned Idx;
1266d88c1a5aSDimitry Andric if (!parseRegisterTiedDefIndex(Idx))
12677d523365SDimitry Andric TiedDefIdx = Idx;
1268d88c1a5aSDimitry Andric else {
1269d88c1a5aSDimitry Andric // Try a redundant low-level type.
1270d88c1a5aSDimitry Andric LLT Ty;
1271d88c1a5aSDimitry Andric if (parseLowLevelType(Token.location(), Ty))
1272d88c1a5aSDimitry Andric return error("expected tied-def or low-level type after '('");
1273d88c1a5aSDimitry Andric
1274d88c1a5aSDimitry Andric if (expectAndConsume(MIToken::rparen))
12753ca95b02SDimitry Andric return true;
12763ca95b02SDimitry Andric
1277d88c1a5aSDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
1278d88c1a5aSDimitry Andric return error("inconsistent type for generic virtual register");
1279d88c1a5aSDimitry Andric
1280d88c1a5aSDimitry Andric MRI.setType(Reg, Ty);
1281d88c1a5aSDimitry Andric }
1282d88c1a5aSDimitry Andric }
1283d88c1a5aSDimitry Andric } else if (consumeIfPresent(MIToken::lparen)) {
1284d88c1a5aSDimitry Andric // Virtual registers may have a tpe with GlobalISel.
1285d88c1a5aSDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg))
1286d88c1a5aSDimitry Andric return error("unexpected type on physical register");
1287d88c1a5aSDimitry Andric
1288d88c1a5aSDimitry Andric LLT Ty;
1289d88c1a5aSDimitry Andric if (parseLowLevelType(Token.location(), Ty))
1290d88c1a5aSDimitry Andric return true;
1291d88c1a5aSDimitry Andric
1292d88c1a5aSDimitry Andric if (expectAndConsume(MIToken::rparen))
1293d88c1a5aSDimitry Andric return true;
1294d88c1a5aSDimitry Andric
1295d88c1a5aSDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
1296d88c1a5aSDimitry Andric return error("inconsistent type for generic virtual register");
1297d88c1a5aSDimitry Andric
1298d88c1a5aSDimitry Andric MRI.setType(Reg, Ty);
1299d88c1a5aSDimitry Andric } else if (TargetRegisterInfo::isVirtualRegister(Reg)) {
1300d88c1a5aSDimitry Andric // Generic virtual registers must have a type.
1301d88c1a5aSDimitry Andric // If we end up here this means the type hasn't been specified and
13023ca95b02SDimitry Andric // this is bad!
1303d88c1a5aSDimitry Andric if (RegInfo->Kind == VRegInfo::GENERIC ||
1304d88c1a5aSDimitry Andric RegInfo->Kind == VRegInfo::REGBANK)
1305d88c1a5aSDimitry Andric return error("generic virtual registers must have a type");
13063ca95b02SDimitry Andric }
1307875ed548SDimitry Andric Dest = MachineOperand::CreateReg(
1308875ed548SDimitry Andric Reg, Flags & RegState::Define, Flags & RegState::Implicit,
1309875ed548SDimitry Andric Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef,
13107d523365SDimitry Andric Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug,
13112cab237bSDimitry Andric Flags & RegState::InternalRead, Flags & RegState::Renamable);
13122cab237bSDimitry Andric
13133dac3a9bSDimitry Andric return false;
13143dac3a9bSDimitry Andric }
13153dac3a9bSDimitry Andric
parseImmediateOperand(MachineOperand & Dest)13163dac3a9bSDimitry Andric bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
13173dac3a9bSDimitry Andric assert(Token.is(MIToken::IntegerLiteral));
13183dac3a9bSDimitry Andric const APSInt &Int = Token.integerValue();
13193dac3a9bSDimitry Andric if (Int.getMinSignedBits() > 64)
13207d523365SDimitry Andric return error("integer literal is too large to be an immediate operand");
13213dac3a9bSDimitry Andric Dest = MachineOperand::CreateImm(Int.getExtValue());
13223dac3a9bSDimitry Andric lex();
13233dac3a9bSDimitry Andric return false;
13243dac3a9bSDimitry Andric }
13253dac3a9bSDimitry Andric
parseIRConstant(StringRef::iterator Loc,StringRef StringValue,const Constant * & C)13267d523365SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
13277d523365SDimitry Andric const Constant *&C) {
13287d523365SDimitry Andric auto Source = StringValue.str(); // The source has to be null terminated.
13297d523365SDimitry Andric SMDiagnostic Err;
13302cab237bSDimitry Andric C = parseConstantValue(Source, Err, *MF.getFunction().getParent(),
13313ca95b02SDimitry Andric &PFS.IRSlots);
13327d523365SDimitry Andric if (!C)
13337d523365SDimitry Andric return error(Loc + Err.getColumnNo(), Err.getMessage());
13347d523365SDimitry Andric return false;
13357d523365SDimitry Andric }
13367d523365SDimitry Andric
parseIRConstant(StringRef::iterator Loc,const Constant * & C)13377d523365SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
13387d523365SDimitry Andric if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C))
13397d523365SDimitry Andric return true;
13407d523365SDimitry Andric lex();
13417d523365SDimitry Andric return false;
13427d523365SDimitry Andric }
13437d523365SDimitry Andric
parseLowLevelType(StringRef::iterator Loc,LLT & Ty)1344d88c1a5aSDimitry Andric bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
13454ba319b5SDimitry Andric if (Token.range().front() == 's' || Token.range().front() == 'p') {
13464ba319b5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
13474ba319b5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
13484ba319b5SDimitry Andric return error("expected integers after 's'/'p' type character");
13494ba319b5SDimitry Andric }
13504ba319b5SDimitry Andric
13514ba319b5SDimitry Andric if (Token.range().front() == 's') {
1352d88c1a5aSDimitry Andric Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue());
1353d88c1a5aSDimitry Andric lex();
1354d88c1a5aSDimitry Andric return false;
13554ba319b5SDimitry Andric } else if (Token.range().front() == 'p') {
13562cab237bSDimitry Andric const DataLayout &DL = MF.getDataLayout();
1357d88c1a5aSDimitry Andric unsigned AS = APSInt(Token.range().drop_front()).getZExtValue();
1358d88c1a5aSDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
1359d88c1a5aSDimitry Andric lex();
13603ca95b02SDimitry Andric return false;
13613ca95b02SDimitry Andric }
13623ca95b02SDimitry Andric
1363d88c1a5aSDimitry Andric // Now we're looking for a vector.
1364d88c1a5aSDimitry Andric if (Token.isNot(MIToken::less))
1365d88c1a5aSDimitry Andric return error(Loc,
13664ba319b5SDimitry Andric "expected sN, pA, <M x sN>, or <M x pA> for GlobalISel type");
1367d88c1a5aSDimitry Andric lex();
1368d88c1a5aSDimitry Andric
1369d88c1a5aSDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
13704ba319b5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
1371d88c1a5aSDimitry Andric uint64_t NumElements = Token.integerValue().getZExtValue();
1372d88c1a5aSDimitry Andric lex();
1373d88c1a5aSDimitry Andric
1374d88c1a5aSDimitry Andric if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
13754ba319b5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
1376d88c1a5aSDimitry Andric lex();
1377d88c1a5aSDimitry Andric
13784ba319b5SDimitry Andric if (Token.range().front() != 's' && Token.range().front() != 'p')
13794ba319b5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
13804ba319b5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
13814ba319b5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
13824ba319b5SDimitry Andric return error("expected integers after 's'/'p' type character");
13834ba319b5SDimitry Andric
13844ba319b5SDimitry Andric if (Token.range().front() == 's')
13854ba319b5SDimitry Andric Ty = LLT::scalar(APSInt(Token.range().drop_front()).getZExtValue());
13864ba319b5SDimitry Andric else if (Token.range().front() == 'p') {
13874ba319b5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
13884ba319b5SDimitry Andric unsigned AS = APSInt(Token.range().drop_front()).getZExtValue();
13894ba319b5SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
13904ba319b5SDimitry Andric } else
13914ba319b5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
1392d88c1a5aSDimitry Andric lex();
1393d88c1a5aSDimitry Andric
1394d88c1a5aSDimitry Andric if (Token.isNot(MIToken::greater))
13954ba319b5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
1396d88c1a5aSDimitry Andric lex();
1397d88c1a5aSDimitry Andric
13984ba319b5SDimitry Andric Ty = LLT::vector(NumElements, Ty);
13993ca95b02SDimitry Andric return false;
14003ca95b02SDimitry Andric }
14013ca95b02SDimitry Andric
parseTypedImmediateOperand(MachineOperand & Dest)14027d523365SDimitry Andric bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) {
14034ba319b5SDimitry Andric assert(Token.is(MIToken::Identifier));
14044ba319b5SDimitry Andric StringRef TypeStr = Token.range();
14054ba319b5SDimitry Andric if (TypeStr.front() != 'i' && TypeStr.front() != 's' &&
14064ba319b5SDimitry Andric TypeStr.front() != 'p')
14074ba319b5SDimitry Andric return error(
14084ba319b5SDimitry Andric "a typed immediate operand should start with one of 'i', 's', or 'p'");
14094ba319b5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
14104ba319b5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
14114ba319b5SDimitry Andric return error("expected integers after 'i'/'s'/'p' type character");
14124ba319b5SDimitry Andric
14137d523365SDimitry Andric auto Loc = Token.location();
14147d523365SDimitry Andric lex();
14154ba319b5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) {
14164ba319b5SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
14174ba319b5SDimitry Andric !(Token.range() == "true" || Token.range() == "false"))
14187d523365SDimitry Andric return error("expected an integer literal");
14194ba319b5SDimitry Andric }
14207d523365SDimitry Andric const Constant *C = nullptr;
14217d523365SDimitry Andric if (parseIRConstant(Loc, C))
14227d523365SDimitry Andric return true;
14237d523365SDimitry Andric Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C));
14247d523365SDimitry Andric return false;
14257d523365SDimitry Andric }
14267d523365SDimitry Andric
parseFPImmediateOperand(MachineOperand & Dest)14277d523365SDimitry Andric bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
14287d523365SDimitry Andric auto Loc = Token.location();
14297d523365SDimitry Andric lex();
1430d88c1a5aSDimitry Andric if (Token.isNot(MIToken::FloatingPointLiteral) &&
1431d88c1a5aSDimitry Andric Token.isNot(MIToken::HexLiteral))
14327d523365SDimitry Andric return error("expected a floating point literal");
14337d523365SDimitry Andric const Constant *C = nullptr;
14347d523365SDimitry Andric if (parseIRConstant(Loc, C))
14357d523365SDimitry Andric return true;
14367d523365SDimitry Andric Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C));
14377d523365SDimitry Andric return false;
14387d523365SDimitry Andric }
14397d523365SDimitry Andric
getUnsigned(unsigned & Result)14403dac3a9bSDimitry Andric bool MIParser::getUnsigned(unsigned &Result) {
1441d88c1a5aSDimitry Andric if (Token.hasIntegerValue()) {
14423dac3a9bSDimitry Andric const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
14433dac3a9bSDimitry Andric uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
14443dac3a9bSDimitry Andric if (Val64 == Limit)
14453dac3a9bSDimitry Andric return error("expected 32-bit integer (too large)");
14463dac3a9bSDimitry Andric Result = Val64;
14473dac3a9bSDimitry Andric return false;
14483dac3a9bSDimitry Andric }
1449d88c1a5aSDimitry Andric if (Token.is(MIToken::HexLiteral)) {
1450d88c1a5aSDimitry Andric APInt A;
1451d88c1a5aSDimitry Andric if (getHexUint(A))
1452d88c1a5aSDimitry Andric return true;
1453d88c1a5aSDimitry Andric if (A.getBitWidth() > 32)
1454d88c1a5aSDimitry Andric return error("expected 32-bit integer (too large)");
1455d88c1a5aSDimitry Andric Result = A.getZExtValue();
1456d88c1a5aSDimitry Andric return false;
1457d88c1a5aSDimitry Andric }
1458d88c1a5aSDimitry Andric return true;
1459d88c1a5aSDimitry Andric }
14603dac3a9bSDimitry Andric
parseMBBReference(MachineBasicBlock * & MBB)14613dac3a9bSDimitry Andric bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
14627d523365SDimitry Andric assert(Token.is(MIToken::MachineBasicBlock) ||
14637d523365SDimitry Andric Token.is(MIToken::MachineBasicBlockLabel));
14643dac3a9bSDimitry Andric unsigned Number;
14653dac3a9bSDimitry Andric if (getUnsigned(Number))
14663dac3a9bSDimitry Andric return true;
1467875ed548SDimitry Andric auto MBBInfo = PFS.MBBSlots.find(Number);
1468875ed548SDimitry Andric if (MBBInfo == PFS.MBBSlots.end())
14693dac3a9bSDimitry Andric return error(Twine("use of undefined machine basic block #") +
14703dac3a9bSDimitry Andric Twine(Number));
14713dac3a9bSDimitry Andric MBB = MBBInfo->second;
14722cab237bSDimitry Andric // TODO: Only parse the name if it's a MachineBasicBlockLabel. Deprecate once
14732cab237bSDimitry Andric // we drop the <irname> from the bb.<id>.<irname> format.
14743dac3a9bSDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
14753dac3a9bSDimitry Andric return error(Twine("the name of machine basic block #") + Twine(Number) +
14763dac3a9bSDimitry Andric " isn't '" + Token.stringValue() + "'");
14773dac3a9bSDimitry Andric return false;
14783dac3a9bSDimitry Andric }
14793dac3a9bSDimitry Andric
parseMBBOperand(MachineOperand & Dest)14803dac3a9bSDimitry Andric bool MIParser::parseMBBOperand(MachineOperand &Dest) {
14813dac3a9bSDimitry Andric MachineBasicBlock *MBB;
14823dac3a9bSDimitry Andric if (parseMBBReference(MBB))
14833dac3a9bSDimitry Andric return true;
14843dac3a9bSDimitry Andric Dest = MachineOperand::CreateMBB(MBB);
14853dac3a9bSDimitry Andric lex();
14863dac3a9bSDimitry Andric return false;
14873dac3a9bSDimitry Andric }
14883dac3a9bSDimitry Andric
parseStackFrameIndex(int & FI)14897d523365SDimitry Andric bool MIParser::parseStackFrameIndex(int &FI) {
14907d523365SDimitry Andric assert(Token.is(MIToken::StackObject));
14917d523365SDimitry Andric unsigned ID;
14927d523365SDimitry Andric if (getUnsigned(ID))
14937d523365SDimitry Andric return true;
14947d523365SDimitry Andric auto ObjectInfo = PFS.StackObjectSlots.find(ID);
14957d523365SDimitry Andric if (ObjectInfo == PFS.StackObjectSlots.end())
14967d523365SDimitry Andric return error(Twine("use of undefined stack object '%stack.") + Twine(ID) +
14977d523365SDimitry Andric "'");
14987d523365SDimitry Andric StringRef Name;
14997d523365SDimitry Andric if (const auto *Alloca =
1500d88c1a5aSDimitry Andric MF.getFrameInfo().getObjectAllocation(ObjectInfo->second))
15017d523365SDimitry Andric Name = Alloca->getName();
15027d523365SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != Name)
15037d523365SDimitry Andric return error(Twine("the name of the stack object '%stack.") + Twine(ID) +
15047d523365SDimitry Andric "' isn't '" + Token.stringValue() + "'");
15057d523365SDimitry Andric lex();
15067d523365SDimitry Andric FI = ObjectInfo->second;
15077d523365SDimitry Andric return false;
15087d523365SDimitry Andric }
15097d523365SDimitry Andric
parseStackObjectOperand(MachineOperand & Dest)15107d523365SDimitry Andric bool MIParser::parseStackObjectOperand(MachineOperand &Dest) {
15117d523365SDimitry Andric int FI;
15127d523365SDimitry Andric if (parseStackFrameIndex(FI))
15137d523365SDimitry Andric return true;
15147d523365SDimitry Andric Dest = MachineOperand::CreateFI(FI);
15157d523365SDimitry Andric return false;
15167d523365SDimitry Andric }
15177d523365SDimitry Andric
parseFixedStackFrameIndex(int & FI)15187d523365SDimitry Andric bool MIParser::parseFixedStackFrameIndex(int &FI) {
15197d523365SDimitry Andric assert(Token.is(MIToken::FixedStackObject));
15207d523365SDimitry Andric unsigned ID;
15217d523365SDimitry Andric if (getUnsigned(ID))
15227d523365SDimitry Andric return true;
15237d523365SDimitry Andric auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID);
15247d523365SDimitry Andric if (ObjectInfo == PFS.FixedStackObjectSlots.end())
15257d523365SDimitry Andric return error(Twine("use of undefined fixed stack object '%fixed-stack.") +
15267d523365SDimitry Andric Twine(ID) + "'");
15277d523365SDimitry Andric lex();
15287d523365SDimitry Andric FI = ObjectInfo->second;
15297d523365SDimitry Andric return false;
15307d523365SDimitry Andric }
15317d523365SDimitry Andric
parseFixedStackObjectOperand(MachineOperand & Dest)15327d523365SDimitry Andric bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
15337d523365SDimitry Andric int FI;
15347d523365SDimitry Andric if (parseFixedStackFrameIndex(FI))
15357d523365SDimitry Andric return true;
15367d523365SDimitry Andric Dest = MachineOperand::CreateFI(FI);
15377d523365SDimitry Andric return false;
15387d523365SDimitry Andric }
15397d523365SDimitry Andric
parseGlobalValue(GlobalValue * & GV)15407d523365SDimitry Andric bool MIParser::parseGlobalValue(GlobalValue *&GV) {
15413dac3a9bSDimitry Andric switch (Token.kind()) {
15423dac3a9bSDimitry Andric case MIToken::NamedGlobalValue: {
15432cab237bSDimitry Andric const Module *M = MF.getFunction().getParent();
15447d523365SDimitry Andric GV = M->getNamedValue(Token.stringValue());
15457d523365SDimitry Andric if (!GV)
15467d523365SDimitry Andric return error(Twine("use of undefined global value '") + Token.range() +
15477d523365SDimitry Andric "'");
15483dac3a9bSDimitry Andric break;
15493dac3a9bSDimitry Andric }
15503dac3a9bSDimitry Andric case MIToken::GlobalValue: {
15513dac3a9bSDimitry Andric unsigned GVIdx;
15523dac3a9bSDimitry Andric if (getUnsigned(GVIdx))
15533dac3a9bSDimitry Andric return true;
15543ca95b02SDimitry Andric if (GVIdx >= PFS.IRSlots.GlobalValues.size())
15553dac3a9bSDimitry Andric return error(Twine("use of undefined global value '@") + Twine(GVIdx) +
15563dac3a9bSDimitry Andric "'");
15573ca95b02SDimitry Andric GV = PFS.IRSlots.GlobalValues[GVIdx];
15583dac3a9bSDimitry Andric break;
15593dac3a9bSDimitry Andric }
15603dac3a9bSDimitry Andric default:
15613dac3a9bSDimitry Andric llvm_unreachable("The current token should be a global value");
15623dac3a9bSDimitry Andric }
15637d523365SDimitry Andric return false;
15647d523365SDimitry Andric }
15657d523365SDimitry Andric
parseGlobalAddressOperand(MachineOperand & Dest)15667d523365SDimitry Andric bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
15677d523365SDimitry Andric GlobalValue *GV = nullptr;
15687d523365SDimitry Andric if (parseGlobalValue(GV))
15697d523365SDimitry Andric return true;
15707d523365SDimitry Andric lex();
15717d523365SDimitry Andric Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
15727d523365SDimitry Andric if (parseOperandsOffset(Dest))
15737d523365SDimitry Andric return true;
15747d523365SDimitry Andric return false;
15757d523365SDimitry Andric }
15767d523365SDimitry Andric
parseConstantPoolIndexOperand(MachineOperand & Dest)15777d523365SDimitry Andric bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) {
15787d523365SDimitry Andric assert(Token.is(MIToken::ConstantPoolItem));
15797d523365SDimitry Andric unsigned ID;
15807d523365SDimitry Andric if (getUnsigned(ID))
15817d523365SDimitry Andric return true;
15827d523365SDimitry Andric auto ConstantInfo = PFS.ConstantPoolSlots.find(ID);
15837d523365SDimitry Andric if (ConstantInfo == PFS.ConstantPoolSlots.end())
15847d523365SDimitry Andric return error("use of undefined constant '%const." + Twine(ID) + "'");
15857d523365SDimitry Andric lex();
15867d523365SDimitry Andric Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0);
15877d523365SDimitry Andric if (parseOperandsOffset(Dest))
15887d523365SDimitry Andric return true;
15897d523365SDimitry Andric return false;
15907d523365SDimitry Andric }
15917d523365SDimitry Andric
parseJumpTableIndexOperand(MachineOperand & Dest)15927d523365SDimitry Andric bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
15937d523365SDimitry Andric assert(Token.is(MIToken::JumpTableIndex));
15947d523365SDimitry Andric unsigned ID;
15957d523365SDimitry Andric if (getUnsigned(ID))
15967d523365SDimitry Andric return true;
15977d523365SDimitry Andric auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID);
15987d523365SDimitry Andric if (JumpTableEntryInfo == PFS.JumpTableSlots.end())
15997d523365SDimitry Andric return error("use of undefined jump table '%jump-table." + Twine(ID) + "'");
16007d523365SDimitry Andric lex();
16017d523365SDimitry Andric Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second);
16027d523365SDimitry Andric return false;
16037d523365SDimitry Andric }
16047d523365SDimitry Andric
parseExternalSymbolOperand(MachineOperand & Dest)16057d523365SDimitry Andric bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
16067d523365SDimitry Andric assert(Token.is(MIToken::ExternalSymbol));
16077d523365SDimitry Andric const char *Symbol = MF.createExternalSymbolName(Token.stringValue());
16087d523365SDimitry Andric lex();
16097d523365SDimitry Andric Dest = MachineOperand::CreateES(Symbol);
16107d523365SDimitry Andric if (parseOperandsOffset(Dest))
16117d523365SDimitry Andric return true;
16127d523365SDimitry Andric return false;
16137d523365SDimitry Andric }
16147d523365SDimitry Andric
parseMCSymbolOperand(MachineOperand & Dest)1615*b5893f02SDimitry Andric bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) {
1616*b5893f02SDimitry Andric assert(Token.is(MIToken::MCSymbol));
1617*b5893f02SDimitry Andric MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue());
1618*b5893f02SDimitry Andric lex();
1619*b5893f02SDimitry Andric Dest = MachineOperand::CreateMCSymbol(Symbol);
1620*b5893f02SDimitry Andric if (parseOperandsOffset(Dest))
1621*b5893f02SDimitry Andric return true;
1622*b5893f02SDimitry Andric return false;
1623*b5893f02SDimitry Andric }
1624*b5893f02SDimitry Andric
parseSubRegisterIndexOperand(MachineOperand & Dest)16253ca95b02SDimitry Andric bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) {
16263ca95b02SDimitry Andric assert(Token.is(MIToken::SubRegisterIndex));
16273ca95b02SDimitry Andric StringRef Name = Token.stringValue();
16283ca95b02SDimitry Andric unsigned SubRegIndex = getSubRegIndex(Token.stringValue());
16293ca95b02SDimitry Andric if (SubRegIndex == 0)
16303ca95b02SDimitry Andric return error(Twine("unknown subregister index '") + Name + "'");
16313ca95b02SDimitry Andric lex();
16323ca95b02SDimitry Andric Dest = MachineOperand::CreateImm(SubRegIndex);
16333ca95b02SDimitry Andric return false;
16343ca95b02SDimitry Andric }
16353ca95b02SDimitry Andric
parseMDNode(MDNode * & Node)16367d523365SDimitry Andric bool MIParser::parseMDNode(MDNode *&Node) {
16377d523365SDimitry Andric assert(Token.is(MIToken::exclaim));
16382cab237bSDimitry Andric
16397d523365SDimitry Andric auto Loc = Token.location();
16407d523365SDimitry Andric lex();
16417d523365SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
16427d523365SDimitry Andric return error("expected metadata id after '!'");
16437d523365SDimitry Andric unsigned ID;
16447d523365SDimitry Andric if (getUnsigned(ID))
16457d523365SDimitry Andric return true;
16463ca95b02SDimitry Andric auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
16473ca95b02SDimitry Andric if (NodeInfo == PFS.IRSlots.MetadataNodes.end())
16487d523365SDimitry Andric return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
16497d523365SDimitry Andric lex();
16507d523365SDimitry Andric Node = NodeInfo->second.get();
16517d523365SDimitry Andric return false;
16527d523365SDimitry Andric }
16537d523365SDimitry Andric
parseDIExpression(MDNode * & Expr)16542cab237bSDimitry Andric bool MIParser::parseDIExpression(MDNode *&Expr) {
16552cab237bSDimitry Andric assert(Token.is(MIToken::md_diexpr));
16562cab237bSDimitry Andric lex();
16572cab237bSDimitry Andric
16582cab237bSDimitry Andric // FIXME: Share this parsing with the IL parser.
16592cab237bSDimitry Andric SmallVector<uint64_t, 8> Elements;
16602cab237bSDimitry Andric
16612cab237bSDimitry Andric if (expectAndConsume(MIToken::lparen))
16622cab237bSDimitry Andric return true;
16632cab237bSDimitry Andric
16642cab237bSDimitry Andric if (Token.isNot(MIToken::rparen)) {
16652cab237bSDimitry Andric do {
16662cab237bSDimitry Andric if (Token.is(MIToken::Identifier)) {
16672cab237bSDimitry Andric if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) {
16682cab237bSDimitry Andric lex();
16692cab237bSDimitry Andric Elements.push_back(Op);
16702cab237bSDimitry Andric continue;
16712cab237bSDimitry Andric }
16722cab237bSDimitry Andric return error(Twine("invalid DWARF op '") + Token.stringValue() + "'");
16732cab237bSDimitry Andric }
16742cab237bSDimitry Andric
16752cab237bSDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
16762cab237bSDimitry Andric Token.integerValue().isSigned())
16772cab237bSDimitry Andric return error("expected unsigned integer");
16782cab237bSDimitry Andric
16792cab237bSDimitry Andric auto &U = Token.integerValue();
16802cab237bSDimitry Andric if (U.ugt(UINT64_MAX))
16812cab237bSDimitry Andric return error("element too large, limit is " + Twine(UINT64_MAX));
16822cab237bSDimitry Andric Elements.push_back(U.getZExtValue());
16832cab237bSDimitry Andric lex();
16842cab237bSDimitry Andric
16852cab237bSDimitry Andric } while (consumeIfPresent(MIToken::comma));
16862cab237bSDimitry Andric }
16872cab237bSDimitry Andric
16882cab237bSDimitry Andric if (expectAndConsume(MIToken::rparen))
16892cab237bSDimitry Andric return true;
16902cab237bSDimitry Andric
16912cab237bSDimitry Andric Expr = DIExpression::get(MF.getFunction().getContext(), Elements);
16922cab237bSDimitry Andric return false;
16932cab237bSDimitry Andric }
16942cab237bSDimitry Andric
parseDILocation(MDNode * & Loc)1695*b5893f02SDimitry Andric bool MIParser::parseDILocation(MDNode *&Loc) {
1696*b5893f02SDimitry Andric assert(Token.is(MIToken::md_dilocation));
1697*b5893f02SDimitry Andric lex();
1698*b5893f02SDimitry Andric
1699*b5893f02SDimitry Andric bool HaveLine = false;
1700*b5893f02SDimitry Andric unsigned Line = 0;
1701*b5893f02SDimitry Andric unsigned Column = 0;
1702*b5893f02SDimitry Andric MDNode *Scope = nullptr;
1703*b5893f02SDimitry Andric MDNode *InlinedAt = nullptr;
1704*b5893f02SDimitry Andric bool ImplicitCode = false;
1705*b5893f02SDimitry Andric
1706*b5893f02SDimitry Andric if (expectAndConsume(MIToken::lparen))
1707*b5893f02SDimitry Andric return true;
1708*b5893f02SDimitry Andric
1709*b5893f02SDimitry Andric if (Token.isNot(MIToken::rparen)) {
1710*b5893f02SDimitry Andric do {
1711*b5893f02SDimitry Andric if (Token.is(MIToken::Identifier)) {
1712*b5893f02SDimitry Andric if (Token.stringValue() == "line") {
1713*b5893f02SDimitry Andric lex();
1714*b5893f02SDimitry Andric if (expectAndConsume(MIToken::colon))
1715*b5893f02SDimitry Andric return true;
1716*b5893f02SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
1717*b5893f02SDimitry Andric Token.integerValue().isSigned())
1718*b5893f02SDimitry Andric return error("expected unsigned integer");
1719*b5893f02SDimitry Andric Line = Token.integerValue().getZExtValue();
1720*b5893f02SDimitry Andric HaveLine = true;
1721*b5893f02SDimitry Andric lex();
1722*b5893f02SDimitry Andric continue;
1723*b5893f02SDimitry Andric }
1724*b5893f02SDimitry Andric if (Token.stringValue() == "column") {
1725*b5893f02SDimitry Andric lex();
1726*b5893f02SDimitry Andric if (expectAndConsume(MIToken::colon))
1727*b5893f02SDimitry Andric return true;
1728*b5893f02SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
1729*b5893f02SDimitry Andric Token.integerValue().isSigned())
1730*b5893f02SDimitry Andric return error("expected unsigned integer");
1731*b5893f02SDimitry Andric Column = Token.integerValue().getZExtValue();
1732*b5893f02SDimitry Andric lex();
1733*b5893f02SDimitry Andric continue;
1734*b5893f02SDimitry Andric }
1735*b5893f02SDimitry Andric if (Token.stringValue() == "scope") {
1736*b5893f02SDimitry Andric lex();
1737*b5893f02SDimitry Andric if (expectAndConsume(MIToken::colon))
1738*b5893f02SDimitry Andric return true;
1739*b5893f02SDimitry Andric if (parseMDNode(Scope))
1740*b5893f02SDimitry Andric return error("expected metadata node");
1741*b5893f02SDimitry Andric if (!isa<DIScope>(Scope))
1742*b5893f02SDimitry Andric return error("expected DIScope node");
1743*b5893f02SDimitry Andric continue;
1744*b5893f02SDimitry Andric }
1745*b5893f02SDimitry Andric if (Token.stringValue() == "inlinedAt") {
1746*b5893f02SDimitry Andric lex();
1747*b5893f02SDimitry Andric if (expectAndConsume(MIToken::colon))
1748*b5893f02SDimitry Andric return true;
1749*b5893f02SDimitry Andric if (Token.is(MIToken::exclaim)) {
1750*b5893f02SDimitry Andric if (parseMDNode(InlinedAt))
1751*b5893f02SDimitry Andric return true;
1752*b5893f02SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
1753*b5893f02SDimitry Andric if (parseDILocation(InlinedAt))
1754*b5893f02SDimitry Andric return true;
1755*b5893f02SDimitry Andric } else
1756*b5893f02SDimitry Andric return error("expected metadata node");
1757*b5893f02SDimitry Andric if (!isa<DILocation>(InlinedAt))
1758*b5893f02SDimitry Andric return error("expected DILocation node");
1759*b5893f02SDimitry Andric continue;
1760*b5893f02SDimitry Andric }
1761*b5893f02SDimitry Andric if (Token.stringValue() == "isImplicitCode") {
1762*b5893f02SDimitry Andric lex();
1763*b5893f02SDimitry Andric if (expectAndConsume(MIToken::colon))
1764*b5893f02SDimitry Andric return true;
1765*b5893f02SDimitry Andric if (!Token.is(MIToken::Identifier))
1766*b5893f02SDimitry Andric return error("expected true/false");
1767*b5893f02SDimitry Andric // As far as I can see, we don't have any existing need for parsing
1768*b5893f02SDimitry Andric // true/false in MIR yet. Do it ad-hoc until there's something else
1769*b5893f02SDimitry Andric // that needs it.
1770*b5893f02SDimitry Andric if (Token.stringValue() == "true")
1771*b5893f02SDimitry Andric ImplicitCode = true;
1772*b5893f02SDimitry Andric else if (Token.stringValue() == "false")
1773*b5893f02SDimitry Andric ImplicitCode = false;
1774*b5893f02SDimitry Andric else
1775*b5893f02SDimitry Andric return error("expected true/false");
1776*b5893f02SDimitry Andric lex();
1777*b5893f02SDimitry Andric continue;
1778*b5893f02SDimitry Andric }
1779*b5893f02SDimitry Andric }
1780*b5893f02SDimitry Andric return error(Twine("invalid DILocation argument '") +
1781*b5893f02SDimitry Andric Token.stringValue() + "'");
1782*b5893f02SDimitry Andric } while (consumeIfPresent(MIToken::comma));
1783*b5893f02SDimitry Andric }
1784*b5893f02SDimitry Andric
1785*b5893f02SDimitry Andric if (expectAndConsume(MIToken::rparen))
1786*b5893f02SDimitry Andric return true;
1787*b5893f02SDimitry Andric
1788*b5893f02SDimitry Andric if (!HaveLine)
1789*b5893f02SDimitry Andric return error("DILocation requires line number");
1790*b5893f02SDimitry Andric if (!Scope)
1791*b5893f02SDimitry Andric return error("DILocation requires a scope");
1792*b5893f02SDimitry Andric
1793*b5893f02SDimitry Andric Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope,
1794*b5893f02SDimitry Andric InlinedAt, ImplicitCode);
1795*b5893f02SDimitry Andric return false;
1796*b5893f02SDimitry Andric }
1797*b5893f02SDimitry Andric
parseMetadataOperand(MachineOperand & Dest)17987d523365SDimitry Andric bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
17997d523365SDimitry Andric MDNode *Node = nullptr;
18002cab237bSDimitry Andric if (Token.is(MIToken::exclaim)) {
18017d523365SDimitry Andric if (parseMDNode(Node))
18027d523365SDimitry Andric return true;
18032cab237bSDimitry Andric } else if (Token.is(MIToken::md_diexpr)) {
18042cab237bSDimitry Andric if (parseDIExpression(Node))
18052cab237bSDimitry Andric return true;
18062cab237bSDimitry Andric }
18077d523365SDimitry Andric Dest = MachineOperand::CreateMetadata(Node);
18087d523365SDimitry Andric return false;
18097d523365SDimitry Andric }
18107d523365SDimitry Andric
parseCFIOffset(int & Offset)18117d523365SDimitry Andric bool MIParser::parseCFIOffset(int &Offset) {
18127d523365SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
18137d523365SDimitry Andric return error("expected a cfi offset");
18147d523365SDimitry Andric if (Token.integerValue().getMinSignedBits() > 32)
18157d523365SDimitry Andric return error("expected a 32 bit integer (the cfi offset is too large)");
18167d523365SDimitry Andric Offset = (int)Token.integerValue().getExtValue();
18173dac3a9bSDimitry Andric lex();
18183dac3a9bSDimitry Andric return false;
18193dac3a9bSDimitry Andric }
18203dac3a9bSDimitry Andric
parseCFIRegister(unsigned & Reg)18217d523365SDimitry Andric bool MIParser::parseCFIRegister(unsigned &Reg) {
18227d523365SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
18237d523365SDimitry Andric return error("expected a cfi register");
18247d523365SDimitry Andric unsigned LLVMReg;
1825d88c1a5aSDimitry Andric if (parseNamedRegister(LLVMReg))
18267d523365SDimitry Andric return true;
18277d523365SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
18287d523365SDimitry Andric assert(TRI && "Expected target register info");
18297d523365SDimitry Andric int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true);
18307d523365SDimitry Andric if (DwarfReg < 0)
18317d523365SDimitry Andric return error("invalid DWARF register");
18327d523365SDimitry Andric Reg = (unsigned)DwarfReg;
18337d523365SDimitry Andric lex();
18347d523365SDimitry Andric return false;
18357d523365SDimitry Andric }
18367d523365SDimitry Andric
parseCFIEscapeValues(std::string & Values)18372cab237bSDimitry Andric bool MIParser::parseCFIEscapeValues(std::string &Values) {
18382cab237bSDimitry Andric do {
18392cab237bSDimitry Andric if (Token.isNot(MIToken::HexLiteral))
18402cab237bSDimitry Andric return error("expected a hexadecimal literal");
18412cab237bSDimitry Andric unsigned Value;
18422cab237bSDimitry Andric if (getUnsigned(Value))
18432cab237bSDimitry Andric return true;
18442cab237bSDimitry Andric if (Value > UINT8_MAX)
18452cab237bSDimitry Andric return error("expected a 8-bit integer (too large)");
18462cab237bSDimitry Andric Values.push_back(static_cast<uint8_t>(Value));
18472cab237bSDimitry Andric lex();
18482cab237bSDimitry Andric } while (consumeIfPresent(MIToken::comma));
18492cab237bSDimitry Andric return false;
18502cab237bSDimitry Andric }
18512cab237bSDimitry Andric
parseCFIOperand(MachineOperand & Dest)18527d523365SDimitry Andric bool MIParser::parseCFIOperand(MachineOperand &Dest) {
18537d523365SDimitry Andric auto Kind = Token.kind();
18547d523365SDimitry Andric lex();
18557d523365SDimitry Andric int Offset;
18567d523365SDimitry Andric unsigned Reg;
18577d523365SDimitry Andric unsigned CFIIndex;
18587d523365SDimitry Andric switch (Kind) {
18597d523365SDimitry Andric case MIToken::kw_cfi_same_value:
18607d523365SDimitry Andric if (parseCFIRegister(Reg))
18617d523365SDimitry Andric return true;
1862d88c1a5aSDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg));
18637d523365SDimitry Andric break;
18647d523365SDimitry Andric case MIToken::kw_cfi_offset:
18657d523365SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
18667d523365SDimitry Andric parseCFIOffset(Offset))
18677d523365SDimitry Andric return true;
18687d523365SDimitry Andric CFIIndex =
1869d88c1a5aSDimitry Andric MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
18707d523365SDimitry Andric break;
18712cab237bSDimitry Andric case MIToken::kw_cfi_rel_offset:
18722cab237bSDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
18732cab237bSDimitry Andric parseCFIOffset(Offset))
18742cab237bSDimitry Andric return true;
18752cab237bSDimitry Andric CFIIndex = MF.addFrameInst(
18762cab237bSDimitry Andric MCCFIInstruction::createRelOffset(nullptr, Reg, Offset));
18772cab237bSDimitry Andric break;
18787d523365SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
18797d523365SDimitry Andric if (parseCFIRegister(Reg))
18807d523365SDimitry Andric return true;
18817d523365SDimitry Andric CFIIndex =
1882d88c1a5aSDimitry Andric MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
18837d523365SDimitry Andric break;
18847d523365SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
18857d523365SDimitry Andric if (parseCFIOffset(Offset))
18867d523365SDimitry Andric return true;
18877d523365SDimitry Andric // NB: MCCFIInstruction::createDefCfaOffset negates the offset.
1888d88c1a5aSDimitry Andric CFIIndex = MF.addFrameInst(
18897d523365SDimitry Andric MCCFIInstruction::createDefCfaOffset(nullptr, -Offset));
18907d523365SDimitry Andric break;
18912cab237bSDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
18922cab237bSDimitry Andric if (parseCFIOffset(Offset))
18932cab237bSDimitry Andric return true;
18942cab237bSDimitry Andric CFIIndex = MF.addFrameInst(
18952cab237bSDimitry Andric MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset));
18962cab237bSDimitry Andric break;
18977d523365SDimitry Andric case MIToken::kw_cfi_def_cfa:
18987d523365SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
18997d523365SDimitry Andric parseCFIOffset(Offset))
19007d523365SDimitry Andric return true;
19017d523365SDimitry Andric // NB: MCCFIInstruction::createDefCfa negates the offset.
19027d523365SDimitry Andric CFIIndex =
1903d88c1a5aSDimitry Andric MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset));
19047d523365SDimitry Andric break;
19052cab237bSDimitry Andric case MIToken::kw_cfi_remember_state:
19062cab237bSDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
19072cab237bSDimitry Andric break;
19082cab237bSDimitry Andric case MIToken::kw_cfi_restore:
19092cab237bSDimitry Andric if (parseCFIRegister(Reg))
19102cab237bSDimitry Andric return true;
19112cab237bSDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
19122cab237bSDimitry Andric break;
19132cab237bSDimitry Andric case MIToken::kw_cfi_restore_state:
19142cab237bSDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr));
19152cab237bSDimitry Andric break;
19162cab237bSDimitry Andric case MIToken::kw_cfi_undefined:
19172cab237bSDimitry Andric if (parseCFIRegister(Reg))
19182cab237bSDimitry Andric return true;
19192cab237bSDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg));
19202cab237bSDimitry Andric break;
19212cab237bSDimitry Andric case MIToken::kw_cfi_register: {
19222cab237bSDimitry Andric unsigned Reg2;
19232cab237bSDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
19242cab237bSDimitry Andric parseCFIRegister(Reg2))
19252cab237bSDimitry Andric return true;
19262cab237bSDimitry Andric
19272cab237bSDimitry Andric CFIIndex =
19282cab237bSDimitry Andric MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2));
19292cab237bSDimitry Andric break;
19302cab237bSDimitry Andric }
19312cab237bSDimitry Andric case MIToken::kw_cfi_window_save:
19322cab237bSDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
19332cab237bSDimitry Andric break;
1934*b5893f02SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
1935*b5893f02SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
1936*b5893f02SDimitry Andric break;
19372cab237bSDimitry Andric case MIToken::kw_cfi_escape: {
19382cab237bSDimitry Andric std::string Values;
19392cab237bSDimitry Andric if (parseCFIEscapeValues(Values))
19402cab237bSDimitry Andric return true;
19412cab237bSDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values));
19422cab237bSDimitry Andric break;
19432cab237bSDimitry Andric }
19447d523365SDimitry Andric default:
19457d523365SDimitry Andric // TODO: Parse the other CFI operands.
19467d523365SDimitry Andric llvm_unreachable("The current token should be a cfi operand");
19477d523365SDimitry Andric }
19487d523365SDimitry Andric Dest = MachineOperand::CreateCFIIndex(CFIIndex);
19497d523365SDimitry Andric return false;
19507d523365SDimitry Andric }
19517d523365SDimitry Andric
parseIRBlock(BasicBlock * & BB,const Function & F)19527d523365SDimitry Andric bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
19537d523365SDimitry Andric switch (Token.kind()) {
19547d523365SDimitry Andric case MIToken::NamedIRBlock: {
19557d523365SDimitry Andric BB = dyn_cast_or_null<BasicBlock>(
1956d88c1a5aSDimitry Andric F.getValueSymbolTable()->lookup(Token.stringValue()));
19577d523365SDimitry Andric if (!BB)
19587d523365SDimitry Andric return error(Twine("use of undefined IR block '") + Token.range() + "'");
19597d523365SDimitry Andric break;
19607d523365SDimitry Andric }
19617d523365SDimitry Andric case MIToken::IRBlock: {
19627d523365SDimitry Andric unsigned SlotNumber = 0;
19637d523365SDimitry Andric if (getUnsigned(SlotNumber))
19647d523365SDimitry Andric return true;
19657d523365SDimitry Andric BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F));
19667d523365SDimitry Andric if (!BB)
19677d523365SDimitry Andric return error(Twine("use of undefined IR block '%ir-block.") +
19687d523365SDimitry Andric Twine(SlotNumber) + "'");
19697d523365SDimitry Andric break;
19707d523365SDimitry Andric }
19717d523365SDimitry Andric default:
19727d523365SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
19737d523365SDimitry Andric }
19747d523365SDimitry Andric return false;
19757d523365SDimitry Andric }
19767d523365SDimitry Andric
parseBlockAddressOperand(MachineOperand & Dest)19777d523365SDimitry Andric bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
19787d523365SDimitry Andric assert(Token.is(MIToken::kw_blockaddress));
19797d523365SDimitry Andric lex();
19807d523365SDimitry Andric if (expectAndConsume(MIToken::lparen))
19817d523365SDimitry Andric return true;
19827d523365SDimitry Andric if (Token.isNot(MIToken::GlobalValue) &&
19837d523365SDimitry Andric Token.isNot(MIToken::NamedGlobalValue))
19847d523365SDimitry Andric return error("expected a global value");
19857d523365SDimitry Andric GlobalValue *GV = nullptr;
19867d523365SDimitry Andric if (parseGlobalValue(GV))
19877d523365SDimitry Andric return true;
19887d523365SDimitry Andric auto *F = dyn_cast<Function>(GV);
19897d523365SDimitry Andric if (!F)
19907d523365SDimitry Andric return error("expected an IR function reference");
19917d523365SDimitry Andric lex();
19927d523365SDimitry Andric if (expectAndConsume(MIToken::comma))
19937d523365SDimitry Andric return true;
19947d523365SDimitry Andric BasicBlock *BB = nullptr;
19957d523365SDimitry Andric if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
19967d523365SDimitry Andric return error("expected an IR block reference");
19977d523365SDimitry Andric if (parseIRBlock(BB, *F))
19987d523365SDimitry Andric return true;
19997d523365SDimitry Andric lex();
20007d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
20017d523365SDimitry Andric return true;
20027d523365SDimitry Andric Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
20037d523365SDimitry Andric if (parseOperandsOffset(Dest))
20047d523365SDimitry Andric return true;
20057d523365SDimitry Andric return false;
20067d523365SDimitry Andric }
20077d523365SDimitry Andric
parseIntrinsicOperand(MachineOperand & Dest)2008d88c1a5aSDimitry Andric bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) {
2009d88c1a5aSDimitry Andric assert(Token.is(MIToken::kw_intrinsic));
2010d88c1a5aSDimitry Andric lex();
2011d88c1a5aSDimitry Andric if (expectAndConsume(MIToken::lparen))
2012d88c1a5aSDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
2013d88c1a5aSDimitry Andric
2014d88c1a5aSDimitry Andric if (Token.isNot(MIToken::NamedGlobalValue))
2015d88c1a5aSDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
2016d88c1a5aSDimitry Andric
2017d88c1a5aSDimitry Andric std::string Name = Token.stringValue();
2018d88c1a5aSDimitry Andric lex();
2019d88c1a5aSDimitry Andric
2020d88c1a5aSDimitry Andric if (expectAndConsume(MIToken::rparen))
2021d88c1a5aSDimitry Andric return error("expected ')' to terminate intrinsic name");
2022d88c1a5aSDimitry Andric
2023d88c1a5aSDimitry Andric // Find out what intrinsic we're dealing with, first try the global namespace
2024d88c1a5aSDimitry Andric // and then the target's private intrinsics if that fails.
2025d88c1a5aSDimitry Andric const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo();
2026d88c1a5aSDimitry Andric Intrinsic::ID ID = Function::lookupIntrinsicID(Name);
2027d88c1a5aSDimitry Andric if (ID == Intrinsic::not_intrinsic && TII)
2028d88c1a5aSDimitry Andric ID = static_cast<Intrinsic::ID>(TII->lookupName(Name));
2029d88c1a5aSDimitry Andric
2030d88c1a5aSDimitry Andric if (ID == Intrinsic::not_intrinsic)
2031d88c1a5aSDimitry Andric return error("unknown intrinsic name");
2032d88c1a5aSDimitry Andric Dest = MachineOperand::CreateIntrinsicID(ID);
2033d88c1a5aSDimitry Andric
2034d88c1a5aSDimitry Andric return false;
2035d88c1a5aSDimitry Andric }
2036d88c1a5aSDimitry Andric
parsePredicateOperand(MachineOperand & Dest)2037d88c1a5aSDimitry Andric bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
2038d88c1a5aSDimitry Andric assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred));
2039d88c1a5aSDimitry Andric bool IsFloat = Token.is(MIToken::kw_floatpred);
2040d88c1a5aSDimitry Andric lex();
2041d88c1a5aSDimitry Andric
2042d88c1a5aSDimitry Andric if (expectAndConsume(MIToken::lparen))
2043d88c1a5aSDimitry Andric return error("expected syntax intpred(whatever) or floatpred(whatever");
2044d88c1a5aSDimitry Andric
2045d88c1a5aSDimitry Andric if (Token.isNot(MIToken::Identifier))
2046d88c1a5aSDimitry Andric return error("whatever");
2047d88c1a5aSDimitry Andric
2048d88c1a5aSDimitry Andric CmpInst::Predicate Pred;
2049d88c1a5aSDimitry Andric if (IsFloat) {
2050d88c1a5aSDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
2051d88c1a5aSDimitry Andric .Case("false", CmpInst::FCMP_FALSE)
2052d88c1a5aSDimitry Andric .Case("oeq", CmpInst::FCMP_OEQ)
2053d88c1a5aSDimitry Andric .Case("ogt", CmpInst::FCMP_OGT)
2054d88c1a5aSDimitry Andric .Case("oge", CmpInst::FCMP_OGE)
2055d88c1a5aSDimitry Andric .Case("olt", CmpInst::FCMP_OLT)
2056d88c1a5aSDimitry Andric .Case("ole", CmpInst::FCMP_OLE)
2057d88c1a5aSDimitry Andric .Case("one", CmpInst::FCMP_ONE)
2058d88c1a5aSDimitry Andric .Case("ord", CmpInst::FCMP_ORD)
2059d88c1a5aSDimitry Andric .Case("uno", CmpInst::FCMP_UNO)
2060d88c1a5aSDimitry Andric .Case("ueq", CmpInst::FCMP_UEQ)
2061d88c1a5aSDimitry Andric .Case("ugt", CmpInst::FCMP_UGT)
2062d88c1a5aSDimitry Andric .Case("uge", CmpInst::FCMP_UGE)
2063d88c1a5aSDimitry Andric .Case("ult", CmpInst::FCMP_ULT)
2064d88c1a5aSDimitry Andric .Case("ule", CmpInst::FCMP_ULE)
2065d88c1a5aSDimitry Andric .Case("une", CmpInst::FCMP_UNE)
2066d88c1a5aSDimitry Andric .Case("true", CmpInst::FCMP_TRUE)
2067d88c1a5aSDimitry Andric .Default(CmpInst::BAD_FCMP_PREDICATE);
2068d88c1a5aSDimitry Andric if (!CmpInst::isFPPredicate(Pred))
2069d88c1a5aSDimitry Andric return error("invalid floating-point predicate");
2070d88c1a5aSDimitry Andric } else {
2071d88c1a5aSDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
2072d88c1a5aSDimitry Andric .Case("eq", CmpInst::ICMP_EQ)
2073d88c1a5aSDimitry Andric .Case("ne", CmpInst::ICMP_NE)
2074d88c1a5aSDimitry Andric .Case("sgt", CmpInst::ICMP_SGT)
2075d88c1a5aSDimitry Andric .Case("sge", CmpInst::ICMP_SGE)
2076d88c1a5aSDimitry Andric .Case("slt", CmpInst::ICMP_SLT)
2077d88c1a5aSDimitry Andric .Case("sle", CmpInst::ICMP_SLE)
2078d88c1a5aSDimitry Andric .Case("ugt", CmpInst::ICMP_UGT)
2079d88c1a5aSDimitry Andric .Case("uge", CmpInst::ICMP_UGE)
2080d88c1a5aSDimitry Andric .Case("ult", CmpInst::ICMP_ULT)
2081d88c1a5aSDimitry Andric .Case("ule", CmpInst::ICMP_ULE)
2082d88c1a5aSDimitry Andric .Default(CmpInst::BAD_ICMP_PREDICATE);
2083d88c1a5aSDimitry Andric if (!CmpInst::isIntPredicate(Pred))
2084d88c1a5aSDimitry Andric return error("invalid integer predicate");
2085d88c1a5aSDimitry Andric }
2086d88c1a5aSDimitry Andric
2087d88c1a5aSDimitry Andric lex();
2088d88c1a5aSDimitry Andric Dest = MachineOperand::CreatePredicate(Pred);
2089d88c1a5aSDimitry Andric if (expectAndConsume(MIToken::rparen))
2090d88c1a5aSDimitry Andric return error("predicate should be terminated by ')'.");
2091d88c1a5aSDimitry Andric
2092d88c1a5aSDimitry Andric return false;
2093d88c1a5aSDimitry Andric }
2094d88c1a5aSDimitry Andric
parseTargetIndexOperand(MachineOperand & Dest)20957d523365SDimitry Andric bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
20967d523365SDimitry Andric assert(Token.is(MIToken::kw_target_index));
20977d523365SDimitry Andric lex();
20987d523365SDimitry Andric if (expectAndConsume(MIToken::lparen))
20997d523365SDimitry Andric return true;
21007d523365SDimitry Andric if (Token.isNot(MIToken::Identifier))
21017d523365SDimitry Andric return error("expected the name of the target index");
21027d523365SDimitry Andric int Index = 0;
21037d523365SDimitry Andric if (getTargetIndex(Token.stringValue(), Index))
21047d523365SDimitry Andric return error("use of undefined target index '" + Token.stringValue() + "'");
21057d523365SDimitry Andric lex();
21067d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
21077d523365SDimitry Andric return true;
21087d523365SDimitry Andric Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0);
21097d523365SDimitry Andric if (parseOperandsOffset(Dest))
21107d523365SDimitry Andric return true;
21117d523365SDimitry Andric return false;
21127d523365SDimitry Andric }
21137d523365SDimitry Andric
parseCustomRegisterMaskOperand(MachineOperand & Dest)21147a7e6055SDimitry Andric bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) {
21157a7e6055SDimitry Andric assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask");
21167a7e6055SDimitry Andric lex();
21177a7e6055SDimitry Andric if (expectAndConsume(MIToken::lparen))
21187a7e6055SDimitry Andric return true;
21197a7e6055SDimitry Andric
21204ba319b5SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
21217a7e6055SDimitry Andric while (true) {
21227a7e6055SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
21237a7e6055SDimitry Andric return error("expected a named register");
21247a7e6055SDimitry Andric unsigned Reg;
21257a7e6055SDimitry Andric if (parseNamedRegister(Reg))
21267a7e6055SDimitry Andric return true;
21277a7e6055SDimitry Andric lex();
21287a7e6055SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32);
21297a7e6055SDimitry Andric // TODO: Report an error if the same register is used more than once.
21307a7e6055SDimitry Andric if (Token.isNot(MIToken::comma))
21317a7e6055SDimitry Andric break;
21327a7e6055SDimitry Andric lex();
21337a7e6055SDimitry Andric }
21347a7e6055SDimitry Andric
21357a7e6055SDimitry Andric if (expectAndConsume(MIToken::rparen))
21367a7e6055SDimitry Andric return true;
21377a7e6055SDimitry Andric Dest = MachineOperand::CreateRegMask(Mask);
21387a7e6055SDimitry Andric return false;
21397a7e6055SDimitry Andric }
21407a7e6055SDimitry Andric
parseLiveoutRegisterMaskOperand(MachineOperand & Dest)21417d523365SDimitry Andric bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) {
21427d523365SDimitry Andric assert(Token.is(MIToken::kw_liveout));
21434ba319b5SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
21447d523365SDimitry Andric lex();
21457d523365SDimitry Andric if (expectAndConsume(MIToken::lparen))
21467d523365SDimitry Andric return true;
21477d523365SDimitry Andric while (true) {
21487d523365SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
21497d523365SDimitry Andric return error("expected a named register");
2150d88c1a5aSDimitry Andric unsigned Reg;
2151d88c1a5aSDimitry Andric if (parseNamedRegister(Reg))
21527d523365SDimitry Andric return true;
21537d523365SDimitry Andric lex();
21547d523365SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32);
21557d523365SDimitry Andric // TODO: Report an error if the same register is used more than once.
21567d523365SDimitry Andric if (Token.isNot(MIToken::comma))
21577d523365SDimitry Andric break;
21587d523365SDimitry Andric lex();
21597d523365SDimitry Andric }
21607d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
21617d523365SDimitry Andric return true;
21627d523365SDimitry Andric Dest = MachineOperand::CreateRegLiveOut(Mask);
21637d523365SDimitry Andric return false;
21647d523365SDimitry Andric }
21657d523365SDimitry Andric
parseMachineOperand(MachineOperand & Dest,Optional<unsigned> & TiedDefIdx)21667d523365SDimitry Andric bool MIParser::parseMachineOperand(MachineOperand &Dest,
21677d523365SDimitry Andric Optional<unsigned> &TiedDefIdx) {
21683dac3a9bSDimitry Andric switch (Token.kind()) {
2169875ed548SDimitry Andric case MIToken::kw_implicit:
2170875ed548SDimitry Andric case MIToken::kw_implicit_define:
21717d523365SDimitry Andric case MIToken::kw_def:
2172875ed548SDimitry Andric case MIToken::kw_dead:
2173875ed548SDimitry Andric case MIToken::kw_killed:
2174875ed548SDimitry Andric case MIToken::kw_undef:
21757d523365SDimitry Andric case MIToken::kw_internal:
21767d523365SDimitry Andric case MIToken::kw_early_clobber:
21777d523365SDimitry Andric case MIToken::kw_debug_use:
21782cab237bSDimitry Andric case MIToken::kw_renamable:
21793dac3a9bSDimitry Andric case MIToken::underscore:
21803dac3a9bSDimitry Andric case MIToken::NamedRegister:
2181875ed548SDimitry Andric case MIToken::VirtualRegister:
21824ba319b5SDimitry Andric case MIToken::NamedVirtualRegister:
21837d523365SDimitry Andric return parseRegisterOperand(Dest, TiedDefIdx);
21843dac3a9bSDimitry Andric case MIToken::IntegerLiteral:
21853dac3a9bSDimitry Andric return parseImmediateOperand(Dest);
21867d523365SDimitry Andric case MIToken::kw_half:
21877d523365SDimitry Andric case MIToken::kw_float:
21887d523365SDimitry Andric case MIToken::kw_double:
21897d523365SDimitry Andric case MIToken::kw_x86_fp80:
21907d523365SDimitry Andric case MIToken::kw_fp128:
21917d523365SDimitry Andric case MIToken::kw_ppc_fp128:
21927d523365SDimitry Andric return parseFPImmediateOperand(Dest);
21933dac3a9bSDimitry Andric case MIToken::MachineBasicBlock:
21943dac3a9bSDimitry Andric return parseMBBOperand(Dest);
21957d523365SDimitry Andric case MIToken::StackObject:
21967d523365SDimitry Andric return parseStackObjectOperand(Dest);
21977d523365SDimitry Andric case MIToken::FixedStackObject:
21987d523365SDimitry Andric return parseFixedStackObjectOperand(Dest);
21993dac3a9bSDimitry Andric case MIToken::GlobalValue:
22003dac3a9bSDimitry Andric case MIToken::NamedGlobalValue:
22013dac3a9bSDimitry Andric return parseGlobalAddressOperand(Dest);
22027d523365SDimitry Andric case MIToken::ConstantPoolItem:
22037d523365SDimitry Andric return parseConstantPoolIndexOperand(Dest);
22047d523365SDimitry Andric case MIToken::JumpTableIndex:
22057d523365SDimitry Andric return parseJumpTableIndexOperand(Dest);
22067d523365SDimitry Andric case MIToken::ExternalSymbol:
22077d523365SDimitry Andric return parseExternalSymbolOperand(Dest);
2208*b5893f02SDimitry Andric case MIToken::MCSymbol:
2209*b5893f02SDimitry Andric return parseMCSymbolOperand(Dest);
22103ca95b02SDimitry Andric case MIToken::SubRegisterIndex:
22113ca95b02SDimitry Andric return parseSubRegisterIndexOperand(Dest);
22122cab237bSDimitry Andric case MIToken::md_diexpr:
22137d523365SDimitry Andric case MIToken::exclaim:
22147d523365SDimitry Andric return parseMetadataOperand(Dest);
22157d523365SDimitry Andric case MIToken::kw_cfi_same_value:
22167d523365SDimitry Andric case MIToken::kw_cfi_offset:
22172cab237bSDimitry Andric case MIToken::kw_cfi_rel_offset:
22187d523365SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
22197d523365SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
22202cab237bSDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
22212cab237bSDimitry Andric case MIToken::kw_cfi_escape:
22227d523365SDimitry Andric case MIToken::kw_cfi_def_cfa:
22232cab237bSDimitry Andric case MIToken::kw_cfi_register:
22242cab237bSDimitry Andric case MIToken::kw_cfi_remember_state:
22252cab237bSDimitry Andric case MIToken::kw_cfi_restore:
22262cab237bSDimitry Andric case MIToken::kw_cfi_restore_state:
22272cab237bSDimitry Andric case MIToken::kw_cfi_undefined:
22282cab237bSDimitry Andric case MIToken::kw_cfi_window_save:
2229*b5893f02SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
22307d523365SDimitry Andric return parseCFIOperand(Dest);
22317d523365SDimitry Andric case MIToken::kw_blockaddress:
22327d523365SDimitry Andric return parseBlockAddressOperand(Dest);
2233d88c1a5aSDimitry Andric case MIToken::kw_intrinsic:
2234d88c1a5aSDimitry Andric return parseIntrinsicOperand(Dest);
22357d523365SDimitry Andric case MIToken::kw_target_index:
22367d523365SDimitry Andric return parseTargetIndexOperand(Dest);
22377d523365SDimitry Andric case MIToken::kw_liveout:
22387d523365SDimitry Andric return parseLiveoutRegisterMaskOperand(Dest);
2239d88c1a5aSDimitry Andric case MIToken::kw_floatpred:
2240d88c1a5aSDimitry Andric case MIToken::kw_intpred:
2241d88c1a5aSDimitry Andric return parsePredicateOperand(Dest);
22423dac3a9bSDimitry Andric case MIToken::Error:
22433dac3a9bSDimitry Andric return true;
22443dac3a9bSDimitry Andric case MIToken::Identifier:
22453dac3a9bSDimitry Andric if (const auto *RegMask = getRegMask(Token.stringValue())) {
22463dac3a9bSDimitry Andric Dest = MachineOperand::CreateRegMask(RegMask);
22473dac3a9bSDimitry Andric lex();
22483dac3a9bSDimitry Andric break;
22494ba319b5SDimitry Andric } else if (Token.stringValue() == "CustomRegMask") {
22507a7e6055SDimitry Andric return parseCustomRegisterMaskOperand(Dest);
22514ba319b5SDimitry Andric } else
22524ba319b5SDimitry Andric return parseTypedImmediateOperand(Dest);
22533dac3a9bSDimitry Andric default:
22547d523365SDimitry Andric // FIXME: Parse the MCSymbol machine operand.
22553dac3a9bSDimitry Andric return error("expected a machine operand");
22563dac3a9bSDimitry Andric }
22573dac3a9bSDimitry Andric return false;
22583dac3a9bSDimitry Andric }
22593dac3a9bSDimitry Andric
parseMachineOperandAndTargetFlags(MachineOperand & Dest,Optional<unsigned> & TiedDefIdx)22607d523365SDimitry Andric bool MIParser::parseMachineOperandAndTargetFlags(
22617d523365SDimitry Andric MachineOperand &Dest, Optional<unsigned> &TiedDefIdx) {
22627d523365SDimitry Andric unsigned TF = 0;
22637d523365SDimitry Andric bool HasTargetFlags = false;
22647d523365SDimitry Andric if (Token.is(MIToken::kw_target_flags)) {
22657d523365SDimitry Andric HasTargetFlags = true;
22667d523365SDimitry Andric lex();
22677d523365SDimitry Andric if (expectAndConsume(MIToken::lparen))
22687d523365SDimitry Andric return true;
22697d523365SDimitry Andric if (Token.isNot(MIToken::Identifier))
22707d523365SDimitry Andric return error("expected the name of the target flag");
22717d523365SDimitry Andric if (getDirectTargetFlag(Token.stringValue(), TF)) {
22727d523365SDimitry Andric if (getBitmaskTargetFlag(Token.stringValue(), TF))
22737d523365SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
22747d523365SDimitry Andric "'");
22757d523365SDimitry Andric }
22767d523365SDimitry Andric lex();
22777d523365SDimitry Andric while (Token.is(MIToken::comma)) {
22787d523365SDimitry Andric lex();
22797d523365SDimitry Andric if (Token.isNot(MIToken::Identifier))
22807d523365SDimitry Andric return error("expected the name of the target flag");
22817d523365SDimitry Andric unsigned BitFlag = 0;
22827d523365SDimitry Andric if (getBitmaskTargetFlag(Token.stringValue(), BitFlag))
22837d523365SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
22847d523365SDimitry Andric "'");
22857d523365SDimitry Andric // TODO: Report an error when using a duplicate bit target flag.
22867d523365SDimitry Andric TF |= BitFlag;
22877d523365SDimitry Andric lex();
22887d523365SDimitry Andric }
22897d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
22907d523365SDimitry Andric return true;
22917d523365SDimitry Andric }
22927d523365SDimitry Andric auto Loc = Token.location();
22937d523365SDimitry Andric if (parseMachineOperand(Dest, TiedDefIdx))
22947d523365SDimitry Andric return true;
22957d523365SDimitry Andric if (!HasTargetFlags)
22967d523365SDimitry Andric return false;
22977d523365SDimitry Andric if (Dest.isReg())
22987d523365SDimitry Andric return error(Loc, "register operands can't have target flags");
22997d523365SDimitry Andric Dest.setTargetFlags(TF);
23007d523365SDimitry Andric return false;
23017d523365SDimitry Andric }
23027d523365SDimitry Andric
parseOffset(int64_t & Offset)23037d523365SDimitry Andric bool MIParser::parseOffset(int64_t &Offset) {
23047d523365SDimitry Andric if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus))
23057d523365SDimitry Andric return false;
23067d523365SDimitry Andric StringRef Sign = Token.range();
23077d523365SDimitry Andric bool IsNegative = Token.is(MIToken::minus);
23087d523365SDimitry Andric lex();
23097d523365SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
23107d523365SDimitry Andric return error("expected an integer literal after '" + Sign + "'");
23117d523365SDimitry Andric if (Token.integerValue().getMinSignedBits() > 64)
23127d523365SDimitry Andric return error("expected 64-bit integer (too large)");
23137d523365SDimitry Andric Offset = Token.integerValue().getExtValue();
23147d523365SDimitry Andric if (IsNegative)
23157d523365SDimitry Andric Offset = -Offset;
23167d523365SDimitry Andric lex();
23177d523365SDimitry Andric return false;
23187d523365SDimitry Andric }
23197d523365SDimitry Andric
parseAlignment(unsigned & Alignment)23207d523365SDimitry Andric bool MIParser::parseAlignment(unsigned &Alignment) {
23217d523365SDimitry Andric assert(Token.is(MIToken::kw_align));
23227d523365SDimitry Andric lex();
23237d523365SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
23247d523365SDimitry Andric return error("expected an integer literal after 'align'");
23257d523365SDimitry Andric if (getUnsigned(Alignment))
23267d523365SDimitry Andric return true;
23277d523365SDimitry Andric lex();
23287d523365SDimitry Andric return false;
23297d523365SDimitry Andric }
23307d523365SDimitry Andric
parseAddrspace(unsigned & Addrspace)23314ba319b5SDimitry Andric bool MIParser::parseAddrspace(unsigned &Addrspace) {
23324ba319b5SDimitry Andric assert(Token.is(MIToken::kw_addrspace));
23334ba319b5SDimitry Andric lex();
23344ba319b5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
23354ba319b5SDimitry Andric return error("expected an integer literal after 'addrspace'");
23364ba319b5SDimitry Andric if (getUnsigned(Addrspace))
23374ba319b5SDimitry Andric return true;
23384ba319b5SDimitry Andric lex();
23394ba319b5SDimitry Andric return false;
23404ba319b5SDimitry Andric }
23414ba319b5SDimitry Andric
parseOperandsOffset(MachineOperand & Op)23427d523365SDimitry Andric bool MIParser::parseOperandsOffset(MachineOperand &Op) {
23437d523365SDimitry Andric int64_t Offset = 0;
23447d523365SDimitry Andric if (parseOffset(Offset))
23457d523365SDimitry Andric return true;
23467d523365SDimitry Andric Op.setOffset(Offset);
23477d523365SDimitry Andric return false;
23487d523365SDimitry Andric }
23497d523365SDimitry Andric
parseIRValue(const Value * & V)23507d523365SDimitry Andric bool MIParser::parseIRValue(const Value *&V) {
23517d523365SDimitry Andric switch (Token.kind()) {
23527d523365SDimitry Andric case MIToken::NamedIRValue: {
23532cab237bSDimitry Andric V = MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue());
23547d523365SDimitry Andric break;
23557d523365SDimitry Andric }
23567d523365SDimitry Andric case MIToken::IRValue: {
23577d523365SDimitry Andric unsigned SlotNumber = 0;
23587d523365SDimitry Andric if (getUnsigned(SlotNumber))
23597d523365SDimitry Andric return true;
23607d523365SDimitry Andric V = getIRValue(SlotNumber);
23617d523365SDimitry Andric break;
23627d523365SDimitry Andric }
23637d523365SDimitry Andric case MIToken::NamedGlobalValue:
23647d523365SDimitry Andric case MIToken::GlobalValue: {
23657d523365SDimitry Andric GlobalValue *GV = nullptr;
23667d523365SDimitry Andric if (parseGlobalValue(GV))
23677d523365SDimitry Andric return true;
23687d523365SDimitry Andric V = GV;
23697d523365SDimitry Andric break;
23707d523365SDimitry Andric }
23717d523365SDimitry Andric case MIToken::QuotedIRValue: {
23727d523365SDimitry Andric const Constant *C = nullptr;
23737d523365SDimitry Andric if (parseIRConstant(Token.location(), Token.stringValue(), C))
23747d523365SDimitry Andric return true;
23757d523365SDimitry Andric V = C;
23767d523365SDimitry Andric break;
23777d523365SDimitry Andric }
23787d523365SDimitry Andric default:
23797d523365SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
23807d523365SDimitry Andric }
23817d523365SDimitry Andric if (!V)
23827d523365SDimitry Andric return error(Twine("use of undefined IR value '") + Token.range() + "'");
23837d523365SDimitry Andric return false;
23847d523365SDimitry Andric }
23857d523365SDimitry Andric
getUint64(uint64_t & Result)23867d523365SDimitry Andric bool MIParser::getUint64(uint64_t &Result) {
2387d88c1a5aSDimitry Andric if (Token.hasIntegerValue()) {
23887d523365SDimitry Andric if (Token.integerValue().getActiveBits() > 64)
23897d523365SDimitry Andric return error("expected 64-bit integer (too large)");
23907d523365SDimitry Andric Result = Token.integerValue().getZExtValue();
23917d523365SDimitry Andric return false;
23927d523365SDimitry Andric }
2393d88c1a5aSDimitry Andric if (Token.is(MIToken::HexLiteral)) {
2394d88c1a5aSDimitry Andric APInt A;
2395d88c1a5aSDimitry Andric if (getHexUint(A))
2396d88c1a5aSDimitry Andric return true;
2397d88c1a5aSDimitry Andric if (A.getBitWidth() > 64)
2398d88c1a5aSDimitry Andric return error("expected 64-bit integer (too large)");
2399d88c1a5aSDimitry Andric Result = A.getZExtValue();
2400d88c1a5aSDimitry Andric return false;
2401d88c1a5aSDimitry Andric }
2402d88c1a5aSDimitry Andric return true;
2403d88c1a5aSDimitry Andric }
2404d88c1a5aSDimitry Andric
getHexUint(APInt & Result)2405d88c1a5aSDimitry Andric bool MIParser::getHexUint(APInt &Result) {
2406d88c1a5aSDimitry Andric assert(Token.is(MIToken::HexLiteral));
2407d88c1a5aSDimitry Andric StringRef S = Token.range();
2408d88c1a5aSDimitry Andric assert(S[0] == '0' && tolower(S[1]) == 'x');
2409d88c1a5aSDimitry Andric // This could be a floating point literal with a special prefix.
2410d88c1a5aSDimitry Andric if (!isxdigit(S[2]))
2411d88c1a5aSDimitry Andric return true;
2412d88c1a5aSDimitry Andric StringRef V = S.substr(2);
2413d88c1a5aSDimitry Andric APInt A(V.size()*4, V, 16);
24142cab237bSDimitry Andric
24152cab237bSDimitry Andric // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make
24162cab237bSDimitry Andric // sure it isn't the case before constructing result.
24172cab237bSDimitry Andric unsigned NumBits = (A == 0) ? 32 : A.getActiveBits();
24182cab237bSDimitry Andric Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
2419d88c1a5aSDimitry Andric return false;
2420d88c1a5aSDimitry Andric }
24217d523365SDimitry Andric
parseMemoryOperandFlag(MachineMemOperand::Flags & Flags)24223ca95b02SDimitry Andric bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
24233ca95b02SDimitry Andric const auto OldFlags = Flags;
24247d523365SDimitry Andric switch (Token.kind()) {
24257d523365SDimitry Andric case MIToken::kw_volatile:
24267d523365SDimitry Andric Flags |= MachineMemOperand::MOVolatile;
24277d523365SDimitry Andric break;
24287d523365SDimitry Andric case MIToken::kw_non_temporal:
24297d523365SDimitry Andric Flags |= MachineMemOperand::MONonTemporal;
24307d523365SDimitry Andric break;
2431d88c1a5aSDimitry Andric case MIToken::kw_dereferenceable:
2432d88c1a5aSDimitry Andric Flags |= MachineMemOperand::MODereferenceable;
2433d88c1a5aSDimitry Andric break;
24347d523365SDimitry Andric case MIToken::kw_invariant:
24357d523365SDimitry Andric Flags |= MachineMemOperand::MOInvariant;
24367d523365SDimitry Andric break;
2437c4394386SDimitry Andric case MIToken::StringConstant: {
2438c4394386SDimitry Andric MachineMemOperand::Flags TF;
2439c4394386SDimitry Andric if (getMMOTargetFlag(Token.stringValue(), TF))
2440c4394386SDimitry Andric return error("use of undefined target MMO flag '" + Token.stringValue() +
2441c4394386SDimitry Andric "'");
2442c4394386SDimitry Andric Flags |= TF;
2443c4394386SDimitry Andric break;
2444c4394386SDimitry Andric }
24457d523365SDimitry Andric default:
24467d523365SDimitry Andric llvm_unreachable("The current token should be a memory operand flag");
24477d523365SDimitry Andric }
24487d523365SDimitry Andric if (OldFlags == Flags)
24497d523365SDimitry Andric // We know that the same flag is specified more than once when the flags
24507d523365SDimitry Andric // weren't modified.
24517d523365SDimitry Andric return error("duplicate '" + Token.stringValue() + "' memory operand flag");
24527d523365SDimitry Andric lex();
24537d523365SDimitry Andric return false;
24547d523365SDimitry Andric }
24557d523365SDimitry Andric
parseMemoryPseudoSourceValue(const PseudoSourceValue * & PSV)24567d523365SDimitry Andric bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) {
24577d523365SDimitry Andric switch (Token.kind()) {
24587d523365SDimitry Andric case MIToken::kw_stack:
24597d523365SDimitry Andric PSV = MF.getPSVManager().getStack();
24607d523365SDimitry Andric break;
24617d523365SDimitry Andric case MIToken::kw_got:
24627d523365SDimitry Andric PSV = MF.getPSVManager().getGOT();
24637d523365SDimitry Andric break;
24647d523365SDimitry Andric case MIToken::kw_jump_table:
24657d523365SDimitry Andric PSV = MF.getPSVManager().getJumpTable();
24667d523365SDimitry Andric break;
24677d523365SDimitry Andric case MIToken::kw_constant_pool:
24687d523365SDimitry Andric PSV = MF.getPSVManager().getConstantPool();
24697d523365SDimitry Andric break;
24707d523365SDimitry Andric case MIToken::FixedStackObject: {
24717d523365SDimitry Andric int FI;
24727d523365SDimitry Andric if (parseFixedStackFrameIndex(FI))
24737d523365SDimitry Andric return true;
24747d523365SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
24757d523365SDimitry Andric // The token was already consumed, so use return here instead of break.
24767d523365SDimitry Andric return false;
24777d523365SDimitry Andric }
24783ca95b02SDimitry Andric case MIToken::StackObject: {
24793ca95b02SDimitry Andric int FI;
24803ca95b02SDimitry Andric if (parseStackFrameIndex(FI))
24813ca95b02SDimitry Andric return true;
24823ca95b02SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
24833ca95b02SDimitry Andric // The token was already consumed, so use return here instead of break.
24843ca95b02SDimitry Andric return false;
24853ca95b02SDimitry Andric }
2486db17bf38SDimitry Andric case MIToken::kw_call_entry:
24877d523365SDimitry Andric lex();
24887d523365SDimitry Andric switch (Token.kind()) {
24897d523365SDimitry Andric case MIToken::GlobalValue:
24907d523365SDimitry Andric case MIToken::NamedGlobalValue: {
24917d523365SDimitry Andric GlobalValue *GV = nullptr;
24927d523365SDimitry Andric if (parseGlobalValue(GV))
24937d523365SDimitry Andric return true;
24947d523365SDimitry Andric PSV = MF.getPSVManager().getGlobalValueCallEntry(GV);
24957d523365SDimitry Andric break;
24967d523365SDimitry Andric }
24977d523365SDimitry Andric case MIToken::ExternalSymbol:
24987d523365SDimitry Andric PSV = MF.getPSVManager().getExternalSymbolCallEntry(
24997d523365SDimitry Andric MF.createExternalSymbolName(Token.stringValue()));
25007d523365SDimitry Andric break;
25017d523365SDimitry Andric default:
25027d523365SDimitry Andric return error(
25037d523365SDimitry Andric "expected a global value or an external symbol after 'call-entry'");
25047d523365SDimitry Andric }
25057d523365SDimitry Andric break;
25067d523365SDimitry Andric default:
25077d523365SDimitry Andric llvm_unreachable("The current token should be pseudo source value");
25087d523365SDimitry Andric }
25097d523365SDimitry Andric lex();
25107d523365SDimitry Andric return false;
25117d523365SDimitry Andric }
25127d523365SDimitry Andric
parseMachinePointerInfo(MachinePointerInfo & Dest)25137d523365SDimitry Andric bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
25147d523365SDimitry Andric if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) ||
25157d523365SDimitry Andric Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) ||
25163ca95b02SDimitry Andric Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) ||
25173ca95b02SDimitry Andric Token.is(MIToken::kw_call_entry)) {
25187d523365SDimitry Andric const PseudoSourceValue *PSV = nullptr;
25197d523365SDimitry Andric if (parseMemoryPseudoSourceValue(PSV))
25207d523365SDimitry Andric return true;
25217d523365SDimitry Andric int64_t Offset = 0;
25227d523365SDimitry Andric if (parseOffset(Offset))
25237d523365SDimitry Andric return true;
25247d523365SDimitry Andric Dest = MachinePointerInfo(PSV, Offset);
25257d523365SDimitry Andric return false;
25267d523365SDimitry Andric }
25277d523365SDimitry Andric if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) &&
25287d523365SDimitry Andric Token.isNot(MIToken::GlobalValue) &&
25297d523365SDimitry Andric Token.isNot(MIToken::NamedGlobalValue) &&
25307d523365SDimitry Andric Token.isNot(MIToken::QuotedIRValue))
25317d523365SDimitry Andric return error("expected an IR value reference");
25327d523365SDimitry Andric const Value *V = nullptr;
25337d523365SDimitry Andric if (parseIRValue(V))
25347d523365SDimitry Andric return true;
25357d523365SDimitry Andric if (!V->getType()->isPointerTy())
25367d523365SDimitry Andric return error("expected a pointer IR value");
25377d523365SDimitry Andric lex();
25387d523365SDimitry Andric int64_t Offset = 0;
25397d523365SDimitry Andric if (parseOffset(Offset))
25407d523365SDimitry Andric return true;
25417d523365SDimitry Andric Dest = MachinePointerInfo(V, Offset);
25427d523365SDimitry Andric return false;
25437d523365SDimitry Andric }
25447d523365SDimitry Andric
parseOptionalScope(LLVMContext & Context,SyncScope::ID & SSID)2545c4394386SDimitry Andric bool MIParser::parseOptionalScope(LLVMContext &Context,
2546c4394386SDimitry Andric SyncScope::ID &SSID) {
2547c4394386SDimitry Andric SSID = SyncScope::System;
2548c4394386SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") {
2549c4394386SDimitry Andric lex();
2550c4394386SDimitry Andric if (expectAndConsume(MIToken::lparen))
2551c4394386SDimitry Andric return error("expected '(' in syncscope");
2552c4394386SDimitry Andric
2553c4394386SDimitry Andric std::string SSN;
2554c4394386SDimitry Andric if (parseStringConstant(SSN))
2555c4394386SDimitry Andric return true;
2556c4394386SDimitry Andric
2557c4394386SDimitry Andric SSID = Context.getOrInsertSyncScopeID(SSN);
2558c4394386SDimitry Andric if (expectAndConsume(MIToken::rparen))
2559c4394386SDimitry Andric return error("expected ')' in syncscope");
2560c4394386SDimitry Andric }
2561c4394386SDimitry Andric
2562c4394386SDimitry Andric return false;
2563c4394386SDimitry Andric }
2564c4394386SDimitry Andric
parseOptionalAtomicOrdering(AtomicOrdering & Order)25657a7e6055SDimitry Andric bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) {
25667a7e6055SDimitry Andric Order = AtomicOrdering::NotAtomic;
25677a7e6055SDimitry Andric if (Token.isNot(MIToken::Identifier))
25687a7e6055SDimitry Andric return false;
25697a7e6055SDimitry Andric
25707a7e6055SDimitry Andric Order = StringSwitch<AtomicOrdering>(Token.stringValue())
25717a7e6055SDimitry Andric .Case("unordered", AtomicOrdering::Unordered)
25727a7e6055SDimitry Andric .Case("monotonic", AtomicOrdering::Monotonic)
25737a7e6055SDimitry Andric .Case("acquire", AtomicOrdering::Acquire)
25747a7e6055SDimitry Andric .Case("release", AtomicOrdering::Release)
25757a7e6055SDimitry Andric .Case("acq_rel", AtomicOrdering::AcquireRelease)
25767a7e6055SDimitry Andric .Case("seq_cst", AtomicOrdering::SequentiallyConsistent)
25777a7e6055SDimitry Andric .Default(AtomicOrdering::NotAtomic);
25787a7e6055SDimitry Andric
25797a7e6055SDimitry Andric if (Order != AtomicOrdering::NotAtomic) {
25807a7e6055SDimitry Andric lex();
25817a7e6055SDimitry Andric return false;
25827a7e6055SDimitry Andric }
25837a7e6055SDimitry Andric
2584*b5893f02SDimitry Andric return error("expected an atomic scope, ordering or a size specification");
25857a7e6055SDimitry Andric }
25867a7e6055SDimitry Andric
parseMachineMemoryOperand(MachineMemOperand * & Dest)25877d523365SDimitry Andric bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
25887d523365SDimitry Andric if (expectAndConsume(MIToken::lparen))
25897d523365SDimitry Andric return true;
25903ca95b02SDimitry Andric MachineMemOperand::Flags Flags = MachineMemOperand::MONone;
25917d523365SDimitry Andric while (Token.isMemoryOperandFlag()) {
25927d523365SDimitry Andric if (parseMemoryOperandFlag(Flags))
25937d523365SDimitry Andric return true;
25947d523365SDimitry Andric }
25957d523365SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
25967d523365SDimitry Andric (Token.stringValue() != "load" && Token.stringValue() != "store"))
25977d523365SDimitry Andric return error("expected 'load' or 'store' memory operation");
25987d523365SDimitry Andric if (Token.stringValue() == "load")
25997d523365SDimitry Andric Flags |= MachineMemOperand::MOLoad;
26007d523365SDimitry Andric else
26017d523365SDimitry Andric Flags |= MachineMemOperand::MOStore;
26027d523365SDimitry Andric lex();
26037d523365SDimitry Andric
26042cab237bSDimitry Andric // Optional 'store' for operands that both load and store.
26052cab237bSDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") {
26062cab237bSDimitry Andric Flags |= MachineMemOperand::MOStore;
26072cab237bSDimitry Andric lex();
26082cab237bSDimitry Andric }
26092cab237bSDimitry Andric
2610c4394386SDimitry Andric // Optional synchronization scope.
2611c4394386SDimitry Andric SyncScope::ID SSID;
26122cab237bSDimitry Andric if (parseOptionalScope(MF.getFunction().getContext(), SSID))
2613c4394386SDimitry Andric return true;
26147a7e6055SDimitry Andric
26157a7e6055SDimitry Andric // Up to two atomic orderings (cmpxchg provides guarantees on failure).
26167a7e6055SDimitry Andric AtomicOrdering Order, FailureOrder;
26177a7e6055SDimitry Andric if (parseOptionalAtomicOrdering(Order))
26187a7e6055SDimitry Andric return true;
26197a7e6055SDimitry Andric
26207a7e6055SDimitry Andric if (parseOptionalAtomicOrdering(FailureOrder))
26217a7e6055SDimitry Andric return true;
26227a7e6055SDimitry Andric
2623*b5893f02SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
2624*b5893f02SDimitry Andric Token.isNot(MIToken::kw_unknown_size))
2625*b5893f02SDimitry Andric return error("expected the size integer literal or 'unknown-size' after "
2626*b5893f02SDimitry Andric "memory operation");
26277d523365SDimitry Andric uint64_t Size;
2628*b5893f02SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
26297d523365SDimitry Andric if (getUint64(Size))
26307d523365SDimitry Andric return true;
2631*b5893f02SDimitry Andric } else if (Token.is(MIToken::kw_unknown_size)) {
2632*b5893f02SDimitry Andric Size = MemoryLocation::UnknownSize;
2633*b5893f02SDimitry Andric }
26347d523365SDimitry Andric lex();
26357d523365SDimitry Andric
26363ca95b02SDimitry Andric MachinePointerInfo Ptr = MachinePointerInfo();
26373ca95b02SDimitry Andric if (Token.is(MIToken::Identifier)) {
26382cab237bSDimitry Andric const char *Word =
26392cab237bSDimitry Andric ((Flags & MachineMemOperand::MOLoad) &&
26402cab237bSDimitry Andric (Flags & MachineMemOperand::MOStore))
26412cab237bSDimitry Andric ? "on"
26422cab237bSDimitry Andric : Flags & MachineMemOperand::MOLoad ? "from" : "into";
26433ca95b02SDimitry Andric if (Token.stringValue() != Word)
26447d523365SDimitry Andric return error(Twine("expected '") + Word + "'");
26457d523365SDimitry Andric lex();
26467d523365SDimitry Andric
26477d523365SDimitry Andric if (parseMachinePointerInfo(Ptr))
26487d523365SDimitry Andric return true;
26493ca95b02SDimitry Andric }
2650*b5893f02SDimitry Andric unsigned BaseAlignment = (Size != MemoryLocation::UnknownSize ? Size : 1);
26517d523365SDimitry Andric AAMDNodes AAInfo;
26527d523365SDimitry Andric MDNode *Range = nullptr;
26537d523365SDimitry Andric while (consumeIfPresent(MIToken::comma)) {
26547d523365SDimitry Andric switch (Token.kind()) {
26557d523365SDimitry Andric case MIToken::kw_align:
26567d523365SDimitry Andric if (parseAlignment(BaseAlignment))
26577d523365SDimitry Andric return true;
26587d523365SDimitry Andric break;
26594ba319b5SDimitry Andric case MIToken::kw_addrspace:
26604ba319b5SDimitry Andric if (parseAddrspace(Ptr.AddrSpace))
26614ba319b5SDimitry Andric return true;
26624ba319b5SDimitry Andric break;
26637d523365SDimitry Andric case MIToken::md_tbaa:
26647d523365SDimitry Andric lex();
26657d523365SDimitry Andric if (parseMDNode(AAInfo.TBAA))
26667d523365SDimitry Andric return true;
26677d523365SDimitry Andric break;
26687d523365SDimitry Andric case MIToken::md_alias_scope:
26697d523365SDimitry Andric lex();
26707d523365SDimitry Andric if (parseMDNode(AAInfo.Scope))
26717d523365SDimitry Andric return true;
26727d523365SDimitry Andric break;
26737d523365SDimitry Andric case MIToken::md_noalias:
26747d523365SDimitry Andric lex();
26757d523365SDimitry Andric if (parseMDNode(AAInfo.NoAlias))
26767d523365SDimitry Andric return true;
26777d523365SDimitry Andric break;
26787d523365SDimitry Andric case MIToken::md_range:
26797d523365SDimitry Andric lex();
26807d523365SDimitry Andric if (parseMDNode(Range))
26817d523365SDimitry Andric return true;
26827d523365SDimitry Andric break;
26837d523365SDimitry Andric // TODO: Report an error on duplicate metadata nodes.
26847d523365SDimitry Andric default:
26857d523365SDimitry Andric return error("expected 'align' or '!tbaa' or '!alias.scope' or "
26867d523365SDimitry Andric "'!noalias' or '!range'");
26877d523365SDimitry Andric }
26887d523365SDimitry Andric }
26897d523365SDimitry Andric if (expectAndConsume(MIToken::rparen))
26907d523365SDimitry Andric return true;
26917a7e6055SDimitry Andric Dest = MF.getMachineMemOperand(Ptr, Flags, Size, BaseAlignment, AAInfo, Range,
2692c4394386SDimitry Andric SSID, Order, FailureOrder);
26937d523365SDimitry Andric return false;
26947d523365SDimitry Andric }
26957d523365SDimitry Andric
parsePreOrPostInstrSymbol(MCSymbol * & Symbol)2696*b5893f02SDimitry Andric bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
2697*b5893f02SDimitry Andric assert((Token.is(MIToken::kw_pre_instr_symbol) ||
2698*b5893f02SDimitry Andric Token.is(MIToken::kw_post_instr_symbol)) &&
2699*b5893f02SDimitry Andric "Invalid token for a pre- post-instruction symbol!");
2700*b5893f02SDimitry Andric lex();
2701*b5893f02SDimitry Andric if (Token.isNot(MIToken::MCSymbol))
2702*b5893f02SDimitry Andric return error("expected a symbol after 'pre-instr-symbol'");
2703*b5893f02SDimitry Andric Symbol = getOrCreateMCSymbol(Token.stringValue());
2704*b5893f02SDimitry Andric lex();
2705*b5893f02SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
2706*b5893f02SDimitry Andric Token.is(MIToken::lbrace))
2707*b5893f02SDimitry Andric return false;
2708*b5893f02SDimitry Andric if (Token.isNot(MIToken::comma))
2709*b5893f02SDimitry Andric return error("expected ',' before the next machine operand");
2710*b5893f02SDimitry Andric lex();
2711*b5893f02SDimitry Andric return false;
2712*b5893f02SDimitry Andric }
2713*b5893f02SDimitry Andric
initNames2InstrOpCodes()27143dac3a9bSDimitry Andric void MIParser::initNames2InstrOpCodes() {
27153dac3a9bSDimitry Andric if (!Names2InstrOpCodes.empty())
27163dac3a9bSDimitry Andric return;
27173dac3a9bSDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
27183dac3a9bSDimitry Andric assert(TII && "Expected target instruction info");
27193dac3a9bSDimitry Andric for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I)
27203dac3a9bSDimitry Andric Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I));
27213dac3a9bSDimitry Andric }
27223dac3a9bSDimitry Andric
parseInstrName(StringRef InstrName,unsigned & OpCode)27233dac3a9bSDimitry Andric bool MIParser::parseInstrName(StringRef InstrName, unsigned &OpCode) {
27243dac3a9bSDimitry Andric initNames2InstrOpCodes();
27253dac3a9bSDimitry Andric auto InstrInfo = Names2InstrOpCodes.find(InstrName);
27263dac3a9bSDimitry Andric if (InstrInfo == Names2InstrOpCodes.end())
27273dac3a9bSDimitry Andric return true;
27283dac3a9bSDimitry Andric OpCode = InstrInfo->getValue();
27293dac3a9bSDimitry Andric return false;
27303dac3a9bSDimitry Andric }
27313dac3a9bSDimitry Andric
initNames2Regs()27323dac3a9bSDimitry Andric void MIParser::initNames2Regs() {
27333dac3a9bSDimitry Andric if (!Names2Regs.empty())
27343dac3a9bSDimitry Andric return;
27353dac3a9bSDimitry Andric // The '%noreg' register is the register 0.
27363dac3a9bSDimitry Andric Names2Regs.insert(std::make_pair("noreg", 0));
27373dac3a9bSDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
27383dac3a9bSDimitry Andric assert(TRI && "Expected target register info");
27393dac3a9bSDimitry Andric for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
27403dac3a9bSDimitry Andric bool WasInserted =
27413dac3a9bSDimitry Andric Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I))
27423dac3a9bSDimitry Andric .second;
27433dac3a9bSDimitry Andric (void)WasInserted;
27443dac3a9bSDimitry Andric assert(WasInserted && "Expected registers to be unique case-insensitively");
27453dac3a9bSDimitry Andric }
27463dac3a9bSDimitry Andric }
27473dac3a9bSDimitry Andric
getRegisterByName(StringRef RegName,unsigned & Reg)27483dac3a9bSDimitry Andric bool MIParser::getRegisterByName(StringRef RegName, unsigned &Reg) {
27493dac3a9bSDimitry Andric initNames2Regs();
27503dac3a9bSDimitry Andric auto RegInfo = Names2Regs.find(RegName);
27513dac3a9bSDimitry Andric if (RegInfo == Names2Regs.end())
27523dac3a9bSDimitry Andric return true;
27533dac3a9bSDimitry Andric Reg = RegInfo->getValue();
27543dac3a9bSDimitry Andric return false;
27553dac3a9bSDimitry Andric }
27563dac3a9bSDimitry Andric
initNames2RegMasks()27573dac3a9bSDimitry Andric void MIParser::initNames2RegMasks() {
27583dac3a9bSDimitry Andric if (!Names2RegMasks.empty())
27593dac3a9bSDimitry Andric return;
27603dac3a9bSDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
27613dac3a9bSDimitry Andric assert(TRI && "Expected target register info");
27623dac3a9bSDimitry Andric ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks();
27633dac3a9bSDimitry Andric ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames();
27643dac3a9bSDimitry Andric assert(RegMasks.size() == RegMaskNames.size());
27653dac3a9bSDimitry Andric for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
27663dac3a9bSDimitry Andric Names2RegMasks.insert(
27673dac3a9bSDimitry Andric std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
27683dac3a9bSDimitry Andric }
27693dac3a9bSDimitry Andric
getRegMask(StringRef Identifier)27703dac3a9bSDimitry Andric const uint32_t *MIParser::getRegMask(StringRef Identifier) {
27713dac3a9bSDimitry Andric initNames2RegMasks();
27723dac3a9bSDimitry Andric auto RegMaskInfo = Names2RegMasks.find(Identifier);
27733dac3a9bSDimitry Andric if (RegMaskInfo == Names2RegMasks.end())
27743dac3a9bSDimitry Andric return nullptr;
27753dac3a9bSDimitry Andric return RegMaskInfo->getValue();
27763dac3a9bSDimitry Andric }
27773dac3a9bSDimitry Andric
initNames2SubRegIndices()2778875ed548SDimitry Andric void MIParser::initNames2SubRegIndices() {
2779875ed548SDimitry Andric if (!Names2SubRegIndices.empty())
2780875ed548SDimitry Andric return;
2781875ed548SDimitry Andric const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
2782875ed548SDimitry Andric for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I)
2783875ed548SDimitry Andric Names2SubRegIndices.insert(
2784875ed548SDimitry Andric std::make_pair(StringRef(TRI->getSubRegIndexName(I)).lower(), I));
27853dac3a9bSDimitry Andric }
27863dac3a9bSDimitry Andric
getSubRegIndex(StringRef Name)2787875ed548SDimitry Andric unsigned MIParser::getSubRegIndex(StringRef Name) {
2788875ed548SDimitry Andric initNames2SubRegIndices();
2789875ed548SDimitry Andric auto SubRegInfo = Names2SubRegIndices.find(Name);
2790875ed548SDimitry Andric if (SubRegInfo == Names2SubRegIndices.end())
2791875ed548SDimitry Andric return 0;
2792875ed548SDimitry Andric return SubRegInfo->getValue();
2793875ed548SDimitry Andric }
2794875ed548SDimitry Andric
initSlots2BasicBlocks(const Function & F,DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)27957d523365SDimitry Andric static void initSlots2BasicBlocks(
27967d523365SDimitry Andric const Function &F,
27977d523365SDimitry Andric DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
27987d523365SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
27997d523365SDimitry Andric MST.incorporateFunction(F);
28007d523365SDimitry Andric for (auto &BB : F) {
28017d523365SDimitry Andric if (BB.hasName())
28027d523365SDimitry Andric continue;
28037d523365SDimitry Andric int Slot = MST.getLocalSlot(&BB);
28047d523365SDimitry Andric if (Slot == -1)
28057d523365SDimitry Andric continue;
28067d523365SDimitry Andric Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB));
28077d523365SDimitry Andric }
28087d523365SDimitry Andric }
28097d523365SDimitry Andric
getIRBlockFromSlot(unsigned Slot,const DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)28107d523365SDimitry Andric static const BasicBlock *getIRBlockFromSlot(
28117d523365SDimitry Andric unsigned Slot,
28127d523365SDimitry Andric const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
28137d523365SDimitry Andric auto BlockInfo = Slots2BasicBlocks.find(Slot);
28147d523365SDimitry Andric if (BlockInfo == Slots2BasicBlocks.end())
28157d523365SDimitry Andric return nullptr;
28167d523365SDimitry Andric return BlockInfo->second;
28177d523365SDimitry Andric }
28187d523365SDimitry Andric
getIRBlock(unsigned Slot)28197d523365SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot) {
28207d523365SDimitry Andric if (Slots2BasicBlocks.empty())
28212cab237bSDimitry Andric initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks);
28227d523365SDimitry Andric return getIRBlockFromSlot(Slot, Slots2BasicBlocks);
28237d523365SDimitry Andric }
28247d523365SDimitry Andric
getIRBlock(unsigned Slot,const Function & F)28257d523365SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) {
28262cab237bSDimitry Andric if (&F == &MF.getFunction())
28277d523365SDimitry Andric return getIRBlock(Slot);
28287d523365SDimitry Andric DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks;
28297d523365SDimitry Andric initSlots2BasicBlocks(F, CustomSlots2BasicBlocks);
28307d523365SDimitry Andric return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks);
28317d523365SDimitry Andric }
28327d523365SDimitry Andric
mapValueToSlot(const Value * V,ModuleSlotTracker & MST,DenseMap<unsigned,const Value * > & Slots2Values)28337d523365SDimitry Andric static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
28347d523365SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) {
28357d523365SDimitry Andric int Slot = MST.getLocalSlot(V);
28367d523365SDimitry Andric if (Slot == -1)
28377d523365SDimitry Andric return;
28387d523365SDimitry Andric Slots2Values.insert(std::make_pair(unsigned(Slot), V));
28397d523365SDimitry Andric }
28407d523365SDimitry Andric
28417d523365SDimitry Andric /// Creates the mapping from slot numbers to function's unnamed IR values.
initSlots2Values(const Function & F,DenseMap<unsigned,const Value * > & Slots2Values)28427d523365SDimitry Andric static void initSlots2Values(const Function &F,
28437d523365SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) {
28447d523365SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
28457d523365SDimitry Andric MST.incorporateFunction(F);
28467d523365SDimitry Andric for (const auto &Arg : F.args())
28477d523365SDimitry Andric mapValueToSlot(&Arg, MST, Slots2Values);
28487d523365SDimitry Andric for (const auto &BB : F) {
28497d523365SDimitry Andric mapValueToSlot(&BB, MST, Slots2Values);
28507d523365SDimitry Andric for (const auto &I : BB)
28517d523365SDimitry Andric mapValueToSlot(&I, MST, Slots2Values);
28527d523365SDimitry Andric }
28537d523365SDimitry Andric }
28547d523365SDimitry Andric
getIRValue(unsigned Slot)28557d523365SDimitry Andric const Value *MIParser::getIRValue(unsigned Slot) {
28567d523365SDimitry Andric if (Slots2Values.empty())
28572cab237bSDimitry Andric initSlots2Values(MF.getFunction(), Slots2Values);
28587d523365SDimitry Andric auto ValueInfo = Slots2Values.find(Slot);
28597d523365SDimitry Andric if (ValueInfo == Slots2Values.end())
28607d523365SDimitry Andric return nullptr;
28617d523365SDimitry Andric return ValueInfo->second;
28627d523365SDimitry Andric }
28637d523365SDimitry Andric
initNames2TargetIndices()28647d523365SDimitry Andric void MIParser::initNames2TargetIndices() {
28657d523365SDimitry Andric if (!Names2TargetIndices.empty())
28667d523365SDimitry Andric return;
28677d523365SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
28687d523365SDimitry Andric assert(TII && "Expected target instruction info");
28697d523365SDimitry Andric auto Indices = TII->getSerializableTargetIndices();
28707d523365SDimitry Andric for (const auto &I : Indices)
28717d523365SDimitry Andric Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first));
28727d523365SDimitry Andric }
28737d523365SDimitry Andric
getTargetIndex(StringRef Name,int & Index)28747d523365SDimitry Andric bool MIParser::getTargetIndex(StringRef Name, int &Index) {
28757d523365SDimitry Andric initNames2TargetIndices();
28767d523365SDimitry Andric auto IndexInfo = Names2TargetIndices.find(Name);
28777d523365SDimitry Andric if (IndexInfo == Names2TargetIndices.end())
28787d523365SDimitry Andric return true;
28797d523365SDimitry Andric Index = IndexInfo->second;
28807d523365SDimitry Andric return false;
28817d523365SDimitry Andric }
28827d523365SDimitry Andric
initNames2DirectTargetFlags()28837d523365SDimitry Andric void MIParser::initNames2DirectTargetFlags() {
28847d523365SDimitry Andric if (!Names2DirectTargetFlags.empty())
28857d523365SDimitry Andric return;
28867d523365SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
28877d523365SDimitry Andric assert(TII && "Expected target instruction info");
28887d523365SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
28897d523365SDimitry Andric for (const auto &I : Flags)
28907d523365SDimitry Andric Names2DirectTargetFlags.insert(
28917d523365SDimitry Andric std::make_pair(StringRef(I.second), I.first));
28927d523365SDimitry Andric }
28937d523365SDimitry Andric
getDirectTargetFlag(StringRef Name,unsigned & Flag)28947d523365SDimitry Andric bool MIParser::getDirectTargetFlag(StringRef Name, unsigned &Flag) {
28957d523365SDimitry Andric initNames2DirectTargetFlags();
28967d523365SDimitry Andric auto FlagInfo = Names2DirectTargetFlags.find(Name);
28977d523365SDimitry Andric if (FlagInfo == Names2DirectTargetFlags.end())
28987d523365SDimitry Andric return true;
28997d523365SDimitry Andric Flag = FlagInfo->second;
29007d523365SDimitry Andric return false;
29017d523365SDimitry Andric }
29027d523365SDimitry Andric
initNames2BitmaskTargetFlags()29037d523365SDimitry Andric void MIParser::initNames2BitmaskTargetFlags() {
29047d523365SDimitry Andric if (!Names2BitmaskTargetFlags.empty())
29057d523365SDimitry Andric return;
29067d523365SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
29077d523365SDimitry Andric assert(TII && "Expected target instruction info");
29087d523365SDimitry Andric auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags();
29097d523365SDimitry Andric for (const auto &I : Flags)
29107d523365SDimitry Andric Names2BitmaskTargetFlags.insert(
29117d523365SDimitry Andric std::make_pair(StringRef(I.second), I.first));
29127d523365SDimitry Andric }
29137d523365SDimitry Andric
getBitmaskTargetFlag(StringRef Name,unsigned & Flag)29147d523365SDimitry Andric bool MIParser::getBitmaskTargetFlag(StringRef Name, unsigned &Flag) {
29157d523365SDimitry Andric initNames2BitmaskTargetFlags();
29167d523365SDimitry Andric auto FlagInfo = Names2BitmaskTargetFlags.find(Name);
29177d523365SDimitry Andric if (FlagInfo == Names2BitmaskTargetFlags.end())
29187d523365SDimitry Andric return true;
29197d523365SDimitry Andric Flag = FlagInfo->second;
29207d523365SDimitry Andric return false;
29217d523365SDimitry Andric }
29227d523365SDimitry Andric
initNames2MMOTargetFlags()2923c4394386SDimitry Andric void MIParser::initNames2MMOTargetFlags() {
2924c4394386SDimitry Andric if (!Names2MMOTargetFlags.empty())
2925c4394386SDimitry Andric return;
2926c4394386SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
2927c4394386SDimitry Andric assert(TII && "Expected target instruction info");
2928c4394386SDimitry Andric auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
2929c4394386SDimitry Andric for (const auto &I : Flags)
2930c4394386SDimitry Andric Names2MMOTargetFlags.insert(
2931c4394386SDimitry Andric std::make_pair(StringRef(I.second), I.first));
2932c4394386SDimitry Andric }
2933c4394386SDimitry Andric
getMMOTargetFlag(StringRef Name,MachineMemOperand::Flags & Flag)2934c4394386SDimitry Andric bool MIParser::getMMOTargetFlag(StringRef Name,
2935c4394386SDimitry Andric MachineMemOperand::Flags &Flag) {
2936c4394386SDimitry Andric initNames2MMOTargetFlags();
2937c4394386SDimitry Andric auto FlagInfo = Names2MMOTargetFlags.find(Name);
2938c4394386SDimitry Andric if (FlagInfo == Names2MMOTargetFlags.end())
2939c4394386SDimitry Andric return true;
2940c4394386SDimitry Andric Flag = FlagInfo->second;
2941c4394386SDimitry Andric return false;
2942c4394386SDimitry Andric }
2943c4394386SDimitry Andric
getOrCreateMCSymbol(StringRef Name)2944*b5893f02SDimitry Andric MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) {
2945*b5893f02SDimitry Andric // FIXME: Currently we can't recognize temporary or local symbols and call all
2946*b5893f02SDimitry Andric // of the appropriate forms to create them. However, this handles basic cases
2947*b5893f02SDimitry Andric // well as most of the special aspects are recognized by a prefix on their
2948*b5893f02SDimitry Andric // name, and the input names should already be unique. For test cases, keeping
2949*b5893f02SDimitry Andric // the symbol name out of the symbol table isn't terribly important.
2950*b5893f02SDimitry Andric return MF.getContext().getOrCreateSymbol(Name);
2951*b5893f02SDimitry Andric }
2952*b5893f02SDimitry Andric
parseStringConstant(std::string & Result)2953c4394386SDimitry Andric bool MIParser::parseStringConstant(std::string &Result) {
2954c4394386SDimitry Andric if (Token.isNot(MIToken::StringConstant))
2955c4394386SDimitry Andric return error("expected string constant");
2956c4394386SDimitry Andric Result = Token.stringValue();
2957c4394386SDimitry Andric lex();
2958c4394386SDimitry Andric return false;
2959c4394386SDimitry Andric }
2960c4394386SDimitry Andric
parseMachineBasicBlockDefinitions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)29613ca95b02SDimitry Andric bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
29623ca95b02SDimitry Andric StringRef Src,
29637d523365SDimitry Andric SMDiagnostic &Error) {
29643ca95b02SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots);
29657d523365SDimitry Andric }
29667d523365SDimitry Andric
parseMachineInstructions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)2967d88c1a5aSDimitry Andric bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS,
29683ca95b02SDimitry Andric StringRef Src, SMDiagnostic &Error) {
29693ca95b02SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlocks();
29703ca95b02SDimitry Andric }
29713ca95b02SDimitry Andric
parseMBBReference(PerFunctionMIParsingState & PFS,MachineBasicBlock * & MBB,StringRef Src,SMDiagnostic & Error)2972d88c1a5aSDimitry Andric bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS,
29733ca95b02SDimitry Andric MachineBasicBlock *&MBB, StringRef Src,
29747d523365SDimitry Andric SMDiagnostic &Error) {
29753ca95b02SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB);
2976875ed548SDimitry Andric }
2977875ed548SDimitry Andric
parseRegisterReference(PerFunctionMIParsingState & PFS,unsigned & Reg,StringRef Src,SMDiagnostic & Error)2978d88c1a5aSDimitry Andric bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS,
2979d88c1a5aSDimitry Andric unsigned &Reg, StringRef Src,
2980d88c1a5aSDimitry Andric SMDiagnostic &Error) {
2981d88c1a5aSDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg);
2982d88c1a5aSDimitry Andric }
2983d88c1a5aSDimitry Andric
parseNamedRegisterReference(PerFunctionMIParsingState & PFS,unsigned & Reg,StringRef Src,SMDiagnostic & Error)2984d88c1a5aSDimitry Andric bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS,
29853ca95b02SDimitry Andric unsigned &Reg, StringRef Src,
2986875ed548SDimitry Andric SMDiagnostic &Error) {
29873ca95b02SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg);
29887d523365SDimitry Andric }
29897d523365SDimitry Andric
parseVirtualRegisterReference(PerFunctionMIParsingState & PFS,VRegInfo * & Info,StringRef Src,SMDiagnostic & Error)2990d88c1a5aSDimitry Andric bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
2991d88c1a5aSDimitry Andric VRegInfo *&Info, StringRef Src,
29927d523365SDimitry Andric SMDiagnostic &Error) {
2993d88c1a5aSDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info);
29947d523365SDimitry Andric }
29957d523365SDimitry Andric
parseStackObjectReference(PerFunctionMIParsingState & PFS,int & FI,StringRef Src,SMDiagnostic & Error)2996d88c1a5aSDimitry Andric bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS,
29973ca95b02SDimitry Andric int &FI, StringRef Src,
29987d523365SDimitry Andric SMDiagnostic &Error) {
29993ca95b02SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI);
30007d523365SDimitry Andric }
30017d523365SDimitry Andric
parseMDNode(PerFunctionMIParsingState & PFS,MDNode * & Node,StringRef Src,SMDiagnostic & Error)3002d88c1a5aSDimitry Andric bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
30033ca95b02SDimitry Andric MDNode *&Node, StringRef Src, SMDiagnostic &Error) {
30043ca95b02SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
30053dac3a9bSDimitry Andric }
3006