11a82d4c0SDimitry Andric //===- MIParser.cpp - Machine instructions parser implementation ----------===//
21a82d4c0SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61a82d4c0SDimitry Andric //
71a82d4c0SDimitry Andric //===----------------------------------------------------------------------===//
81a82d4c0SDimitry Andric //
91a82d4c0SDimitry Andric // This file implements the parsing of machine instructions.
101a82d4c0SDimitry Andric //
111a82d4c0SDimitry Andric //===----------------------------------------------------------------------===//
121a82d4c0SDimitry Andric
13e6d15924SDimitry Andric #include "llvm/CodeGen/MIRParser/MIParser.h"
14044eb2f6SDimitry Andric #include "MILexer.h"
157ab83427SDimitry Andric #include "llvm/ADT/APInt.h"
167ab83427SDimitry Andric #include "llvm/ADT/APSInt.h"
177ab83427SDimitry Andric #include "llvm/ADT/ArrayRef.h"
187ab83427SDimitry Andric #include "llvm/ADT/DenseMap.h"
197ab83427SDimitry Andric #include "llvm/ADT/SmallVector.h"
201a82d4c0SDimitry Andric #include "llvm/ADT/StringMap.h"
217ab83427SDimitry Andric #include "llvm/ADT/StringRef.h"
22044eb2f6SDimitry Andric #include "llvm/ADT/StringSwitch.h"
237ab83427SDimitry Andric #include "llvm/ADT/Twine.h"
24d8e91e46SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
25dd58ef01SDimitry Andric #include "llvm/AsmParser/Parser.h"
261a82d4c0SDimitry Andric #include "llvm/AsmParser/SlotMapping.h"
27706b4fc4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h"
28c46e6a59SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
291a82d4c0SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
30dd58ef01SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
3101095a5dSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
321a82d4c0SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
33ee8648bdSDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
34dd58ef01SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
357ab83427SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
3601095a5dSDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
37b1c73532SDimitry Andric #include "llvm/CodeGen/PseudoSourceValueManager.h"
38145449b1SDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
39145449b1SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h"
40044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
41044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
42044eb2f6SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
43ac9a064cSDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
447ab83427SDimitry Andric #include "llvm/IR/BasicBlock.h"
45dd58ef01SDimitry Andric #include "llvm/IR/Constants.h"
467ab83427SDimitry Andric #include "llvm/IR/DataLayout.h"
47044eb2f6SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
487ab83427SDimitry Andric #include "llvm/IR/DebugLoc.h"
497ab83427SDimitry Andric #include "llvm/IR/Function.h"
507ab83427SDimitry Andric #include "llvm/IR/InstrTypes.h"
5101095a5dSDimitry Andric #include "llvm/IR/Instructions.h"
52b915e9e0SDimitry Andric #include "llvm/IR/Intrinsics.h"
537ab83427SDimitry Andric #include "llvm/IR/Metadata.h"
541a82d4c0SDimitry Andric #include "llvm/IR/Module.h"
55dd58ef01SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
567ab83427SDimitry Andric #include "llvm/IR/Type.h"
577ab83427SDimitry Andric #include "llvm/IR/Value.h"
58dd58ef01SDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
597ab83427SDimitry Andric #include "llvm/MC/LaneBitmask.h"
60d8e91e46SDimitry Andric #include "llvm/MC/MCContext.h"
617ab83427SDimitry Andric #include "llvm/MC/MCDwarf.h"
627ab83427SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
637ab83427SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
647ab83427SDimitry Andric #include "llvm/Support/BranchProbability.h"
657ab83427SDimitry Andric #include "llvm/Support/Casting.h"
667ab83427SDimitry Andric #include "llvm/Support/ErrorHandling.h"
677ab83427SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
687ab83427SDimitry Andric #include "llvm/Support/SMLoc.h"
691a82d4c0SDimitry Andric #include "llvm/Support/SourceMgr.h"
70b915e9e0SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
717ab83427SDimitry Andric #include "llvm/Target/TargetMachine.h"
727ab83427SDimitry Andric #include <cassert>
73b915e9e0SDimitry Andric #include <cctype>
747ab83427SDimitry Andric #include <cstddef>
757ab83427SDimitry Andric #include <cstdint>
767ab83427SDimitry Andric #include <limits>
777ab83427SDimitry Andric #include <string>
787ab83427SDimitry Andric #include <utility>
791a82d4c0SDimitry Andric
801a82d4c0SDimitry Andric using namespace llvm;
811a82d4c0SDimitry Andric
setTarget(const TargetSubtargetInfo & NewSubtarget)82e6d15924SDimitry Andric void PerTargetMIParsingState::setTarget(
83e6d15924SDimitry Andric const TargetSubtargetInfo &NewSubtarget) {
84e6d15924SDimitry Andric
85e6d15924SDimitry Andric // If the subtarget changed, over conservatively assume everything is invalid.
86e6d15924SDimitry Andric if (&Subtarget == &NewSubtarget)
87e6d15924SDimitry Andric return;
88e6d15924SDimitry Andric
89e6d15924SDimitry Andric Names2InstrOpCodes.clear();
90e6d15924SDimitry Andric Names2Regs.clear();
91e6d15924SDimitry Andric Names2RegMasks.clear();
92e6d15924SDimitry Andric Names2SubRegIndices.clear();
93e6d15924SDimitry Andric Names2TargetIndices.clear();
94e6d15924SDimitry Andric Names2DirectTargetFlags.clear();
95e6d15924SDimitry Andric Names2BitmaskTargetFlags.clear();
96e6d15924SDimitry Andric Names2MMOTargetFlags.clear();
97e6d15924SDimitry Andric
98e6d15924SDimitry Andric initNames2RegClasses();
99e6d15924SDimitry Andric initNames2RegBanks();
100e6d15924SDimitry Andric }
101e6d15924SDimitry Andric
initNames2Regs()102e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2Regs() {
103e6d15924SDimitry Andric if (!Names2Regs.empty())
104e6d15924SDimitry Andric return;
105e6d15924SDimitry Andric
106e6d15924SDimitry Andric // The '%noreg' register is the register 0.
107e6d15924SDimitry Andric Names2Regs.insert(std::make_pair("noreg", 0));
108e6d15924SDimitry Andric const auto *TRI = Subtarget.getRegisterInfo();
109e6d15924SDimitry Andric assert(TRI && "Expected target register info");
110e6d15924SDimitry Andric
111e6d15924SDimitry Andric for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
112e6d15924SDimitry Andric bool WasInserted =
113e6d15924SDimitry Andric Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I))
114e6d15924SDimitry Andric .second;
115e6d15924SDimitry Andric (void)WasInserted;
116e6d15924SDimitry Andric assert(WasInserted && "Expected registers to be unique case-insensitively");
117e6d15924SDimitry Andric }
118e6d15924SDimitry Andric }
119e6d15924SDimitry Andric
getRegisterByName(StringRef RegName,Register & Reg)120e6d15924SDimitry Andric bool PerTargetMIParsingState::getRegisterByName(StringRef RegName,
121cfca06d7SDimitry Andric Register &Reg) {
122e6d15924SDimitry Andric initNames2Regs();
123e6d15924SDimitry Andric auto RegInfo = Names2Regs.find(RegName);
124e6d15924SDimitry Andric if (RegInfo == Names2Regs.end())
125e6d15924SDimitry Andric return true;
126e6d15924SDimitry Andric Reg = RegInfo->getValue();
127e6d15924SDimitry Andric return false;
128e6d15924SDimitry Andric }
129e6d15924SDimitry Andric
initNames2InstrOpCodes()130e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2InstrOpCodes() {
131e6d15924SDimitry Andric if (!Names2InstrOpCodes.empty())
132e6d15924SDimitry Andric return;
133e6d15924SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
134e6d15924SDimitry Andric assert(TII && "Expected target instruction info");
135e6d15924SDimitry Andric for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I)
136e6d15924SDimitry Andric Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I));
137e6d15924SDimitry Andric }
138e6d15924SDimitry Andric
parseInstrName(StringRef InstrName,unsigned & OpCode)139e6d15924SDimitry Andric bool PerTargetMIParsingState::parseInstrName(StringRef InstrName,
140e6d15924SDimitry Andric unsigned &OpCode) {
141e6d15924SDimitry Andric initNames2InstrOpCodes();
142e6d15924SDimitry Andric auto InstrInfo = Names2InstrOpCodes.find(InstrName);
143e6d15924SDimitry Andric if (InstrInfo == Names2InstrOpCodes.end())
144e6d15924SDimitry Andric return true;
145e6d15924SDimitry Andric OpCode = InstrInfo->getValue();
146e6d15924SDimitry Andric return false;
147e6d15924SDimitry Andric }
148e6d15924SDimitry Andric
initNames2RegMasks()149e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2RegMasks() {
150e6d15924SDimitry Andric if (!Names2RegMasks.empty())
151e6d15924SDimitry Andric return;
152e6d15924SDimitry Andric const auto *TRI = Subtarget.getRegisterInfo();
153e6d15924SDimitry Andric assert(TRI && "Expected target register info");
154e6d15924SDimitry Andric ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks();
155e6d15924SDimitry Andric ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames();
156e6d15924SDimitry Andric assert(RegMasks.size() == RegMaskNames.size());
157e6d15924SDimitry Andric for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
158e6d15924SDimitry Andric Names2RegMasks.insert(
159e6d15924SDimitry Andric std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
160e6d15924SDimitry Andric }
161e6d15924SDimitry Andric
getRegMask(StringRef Identifier)162e6d15924SDimitry Andric const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) {
163e6d15924SDimitry Andric initNames2RegMasks();
164e6d15924SDimitry Andric auto RegMaskInfo = Names2RegMasks.find(Identifier);
165e6d15924SDimitry Andric if (RegMaskInfo == Names2RegMasks.end())
166e6d15924SDimitry Andric return nullptr;
167e6d15924SDimitry Andric return RegMaskInfo->getValue();
168e6d15924SDimitry Andric }
169e6d15924SDimitry Andric
initNames2SubRegIndices()170e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2SubRegIndices() {
171e6d15924SDimitry Andric if (!Names2SubRegIndices.empty())
172e6d15924SDimitry Andric return;
173e6d15924SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
174e6d15924SDimitry Andric for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I)
175e6d15924SDimitry Andric Names2SubRegIndices.insert(
176e6d15924SDimitry Andric std::make_pair(TRI->getSubRegIndexName(I), I));
177e6d15924SDimitry Andric }
178e6d15924SDimitry Andric
getSubRegIndex(StringRef Name)179e6d15924SDimitry Andric unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) {
180e6d15924SDimitry Andric initNames2SubRegIndices();
181e6d15924SDimitry Andric auto SubRegInfo = Names2SubRegIndices.find(Name);
182e6d15924SDimitry Andric if (SubRegInfo == Names2SubRegIndices.end())
183e6d15924SDimitry Andric return 0;
184e6d15924SDimitry Andric return SubRegInfo->getValue();
185e6d15924SDimitry Andric }
186e6d15924SDimitry Andric
initNames2TargetIndices()187e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2TargetIndices() {
188e6d15924SDimitry Andric if (!Names2TargetIndices.empty())
189e6d15924SDimitry Andric return;
190e6d15924SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
191e6d15924SDimitry Andric assert(TII && "Expected target instruction info");
192e6d15924SDimitry Andric auto Indices = TII->getSerializableTargetIndices();
193e6d15924SDimitry Andric for (const auto &I : Indices)
194e6d15924SDimitry Andric Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first));
195e6d15924SDimitry Andric }
196e6d15924SDimitry Andric
getTargetIndex(StringRef Name,int & Index)197e6d15924SDimitry Andric bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) {
198e6d15924SDimitry Andric initNames2TargetIndices();
199e6d15924SDimitry Andric auto IndexInfo = Names2TargetIndices.find(Name);
200e6d15924SDimitry Andric if (IndexInfo == Names2TargetIndices.end())
201e6d15924SDimitry Andric return true;
202e6d15924SDimitry Andric Index = IndexInfo->second;
203e6d15924SDimitry Andric return false;
204e6d15924SDimitry Andric }
205e6d15924SDimitry Andric
initNames2DirectTargetFlags()206e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2DirectTargetFlags() {
207e6d15924SDimitry Andric if (!Names2DirectTargetFlags.empty())
208e6d15924SDimitry Andric return;
209e6d15924SDimitry Andric
210e6d15924SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
211e6d15924SDimitry Andric assert(TII && "Expected target instruction info");
212e6d15924SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
213e6d15924SDimitry Andric for (const auto &I : Flags)
214e6d15924SDimitry Andric Names2DirectTargetFlags.insert(
215e6d15924SDimitry Andric std::make_pair(StringRef(I.second), I.first));
216e6d15924SDimitry Andric }
217e6d15924SDimitry Andric
getDirectTargetFlag(StringRef Name,unsigned & Flag)218e6d15924SDimitry Andric bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name,
219e6d15924SDimitry Andric unsigned &Flag) {
220e6d15924SDimitry Andric initNames2DirectTargetFlags();
221e6d15924SDimitry Andric auto FlagInfo = Names2DirectTargetFlags.find(Name);
222e6d15924SDimitry Andric if (FlagInfo == Names2DirectTargetFlags.end())
223e6d15924SDimitry Andric return true;
224e6d15924SDimitry Andric Flag = FlagInfo->second;
225e6d15924SDimitry Andric return false;
226e6d15924SDimitry Andric }
227e6d15924SDimitry Andric
initNames2BitmaskTargetFlags()228e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2BitmaskTargetFlags() {
229e6d15924SDimitry Andric if (!Names2BitmaskTargetFlags.empty())
230e6d15924SDimitry Andric return;
231e6d15924SDimitry Andric
232e6d15924SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
233e6d15924SDimitry Andric assert(TII && "Expected target instruction info");
234e6d15924SDimitry Andric auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags();
235e6d15924SDimitry Andric for (const auto &I : Flags)
236e6d15924SDimitry Andric Names2BitmaskTargetFlags.insert(
237e6d15924SDimitry Andric std::make_pair(StringRef(I.second), I.first));
238e6d15924SDimitry Andric }
239e6d15924SDimitry Andric
getBitmaskTargetFlag(StringRef Name,unsigned & Flag)240e6d15924SDimitry Andric bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name,
241e6d15924SDimitry Andric unsigned &Flag) {
242e6d15924SDimitry Andric initNames2BitmaskTargetFlags();
243e6d15924SDimitry Andric auto FlagInfo = Names2BitmaskTargetFlags.find(Name);
244e6d15924SDimitry Andric if (FlagInfo == Names2BitmaskTargetFlags.end())
245e6d15924SDimitry Andric return true;
246e6d15924SDimitry Andric Flag = FlagInfo->second;
247e6d15924SDimitry Andric return false;
248e6d15924SDimitry Andric }
249e6d15924SDimitry Andric
initNames2MMOTargetFlags()250e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2MMOTargetFlags() {
251e6d15924SDimitry Andric if (!Names2MMOTargetFlags.empty())
252e6d15924SDimitry Andric return;
253e6d15924SDimitry Andric
254e6d15924SDimitry Andric const auto *TII = Subtarget.getInstrInfo();
255e6d15924SDimitry Andric assert(TII && "Expected target instruction info");
256e6d15924SDimitry Andric auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
257e6d15924SDimitry Andric for (const auto &I : Flags)
258e6d15924SDimitry Andric Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first));
259e6d15924SDimitry Andric }
260e6d15924SDimitry Andric
getMMOTargetFlag(StringRef Name,MachineMemOperand::Flags & Flag)261e6d15924SDimitry Andric bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name,
262e6d15924SDimitry Andric MachineMemOperand::Flags &Flag) {
263e6d15924SDimitry Andric initNames2MMOTargetFlags();
264e6d15924SDimitry Andric auto FlagInfo = Names2MMOTargetFlags.find(Name);
265e6d15924SDimitry Andric if (FlagInfo == Names2MMOTargetFlags.end())
266e6d15924SDimitry Andric return true;
267e6d15924SDimitry Andric Flag = FlagInfo->second;
268e6d15924SDimitry Andric return false;
269e6d15924SDimitry Andric }
270e6d15924SDimitry Andric
initNames2RegClasses()271e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2RegClasses() {
272e6d15924SDimitry Andric if (!Names2RegClasses.empty())
273e6d15924SDimitry Andric return;
274e6d15924SDimitry Andric
275e6d15924SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
276e6d15924SDimitry Andric for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
277e6d15924SDimitry Andric const auto *RC = TRI->getRegClass(I);
278e6d15924SDimitry Andric Names2RegClasses.insert(
279e6d15924SDimitry Andric std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
280e6d15924SDimitry Andric }
281e6d15924SDimitry Andric }
282e6d15924SDimitry Andric
initNames2RegBanks()283e6d15924SDimitry Andric void PerTargetMIParsingState::initNames2RegBanks() {
284e6d15924SDimitry Andric if (!Names2RegBanks.empty())
285e6d15924SDimitry Andric return;
286e6d15924SDimitry Andric
287e6d15924SDimitry Andric const RegisterBankInfo *RBI = Subtarget.getRegBankInfo();
288e6d15924SDimitry Andric // If the target does not support GlobalISel, we may not have a
289e6d15924SDimitry Andric // register bank info.
290e6d15924SDimitry Andric if (!RBI)
291e6d15924SDimitry Andric return;
292e6d15924SDimitry Andric
293e6d15924SDimitry Andric for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) {
294e6d15924SDimitry Andric const auto &RegBank = RBI->getRegBank(I);
295e6d15924SDimitry Andric Names2RegBanks.insert(
296e6d15924SDimitry Andric std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank));
297e6d15924SDimitry Andric }
298e6d15924SDimitry Andric }
299e6d15924SDimitry Andric
300e6d15924SDimitry Andric const TargetRegisterClass *
getRegClass(StringRef Name)301e6d15924SDimitry Andric PerTargetMIParsingState::getRegClass(StringRef Name) {
302e6d15924SDimitry Andric auto RegClassInfo = Names2RegClasses.find(Name);
303e6d15924SDimitry Andric if (RegClassInfo == Names2RegClasses.end())
304e6d15924SDimitry Andric return nullptr;
305e6d15924SDimitry Andric return RegClassInfo->getValue();
306e6d15924SDimitry Andric }
307e6d15924SDimitry Andric
getRegBank(StringRef Name)308e6d15924SDimitry Andric const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) {
309e6d15924SDimitry Andric auto RegBankInfo = Names2RegBanks.find(Name);
310e6d15924SDimitry Andric if (RegBankInfo == Names2RegBanks.end())
311e6d15924SDimitry Andric return nullptr;
312e6d15924SDimitry Andric return RegBankInfo->getValue();
313e6d15924SDimitry Andric }
314e6d15924SDimitry Andric
PerFunctionMIParsingState(MachineFunction & MF,SourceMgr & SM,const SlotMapping & IRSlots,PerTargetMIParsingState & T)31501095a5dSDimitry Andric PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF,
316e6d15924SDimitry Andric SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T)
317e6d15924SDimitry Andric : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) {
31801095a5dSDimitry Andric }
31901095a5dSDimitry Andric
getVRegInfo(Register Num)320cfca06d7SDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfo(Register Num) {
321b915e9e0SDimitry Andric auto I = VRegInfos.insert(std::make_pair(Num, nullptr));
322b915e9e0SDimitry Andric if (I.second) {
323b915e9e0SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
324b915e9e0SDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo;
325b915e9e0SDimitry Andric Info->VReg = MRI.createIncompleteVirtualRegister();
326b915e9e0SDimitry Andric I.first->second = Info;
327b915e9e0SDimitry Andric }
328b915e9e0SDimitry Andric return *I.first->second;
329b915e9e0SDimitry Andric }
330b915e9e0SDimitry Andric
getVRegInfoNamed(StringRef RegName)331eb11fae6SDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) {
332eb11fae6SDimitry Andric assert(RegName != "" && "Expected named reg.");
333eb11fae6SDimitry Andric
334eb11fae6SDimitry Andric auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr));
335eb11fae6SDimitry Andric if (I.second) {
336eb11fae6SDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo;
337eb11fae6SDimitry Andric Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName);
338eb11fae6SDimitry Andric I.first->second = Info;
339eb11fae6SDimitry Andric }
340eb11fae6SDimitry Andric return *I.first->second;
341eb11fae6SDimitry Andric }
342eb11fae6SDimitry Andric
mapValueToSlot(const Value * V,ModuleSlotTracker & MST,DenseMap<unsigned,const Value * > & Slots2Values)343706b4fc4SDimitry Andric static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
344706b4fc4SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) {
345706b4fc4SDimitry Andric int Slot = MST.getLocalSlot(V);
346706b4fc4SDimitry Andric if (Slot == -1)
347706b4fc4SDimitry Andric return;
348706b4fc4SDimitry Andric Slots2Values.insert(std::make_pair(unsigned(Slot), V));
349706b4fc4SDimitry Andric }
350706b4fc4SDimitry Andric
351706b4fc4SDimitry Andric /// Creates the mapping from slot numbers to function's unnamed IR values.
initSlots2Values(const Function & F,DenseMap<unsigned,const Value * > & Slots2Values)352706b4fc4SDimitry Andric static void initSlots2Values(const Function &F,
353706b4fc4SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) {
354706b4fc4SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
355706b4fc4SDimitry Andric MST.incorporateFunction(F);
356706b4fc4SDimitry Andric for (const auto &Arg : F.args())
357706b4fc4SDimitry Andric mapValueToSlot(&Arg, MST, Slots2Values);
358706b4fc4SDimitry Andric for (const auto &BB : F) {
359706b4fc4SDimitry Andric mapValueToSlot(&BB, MST, Slots2Values);
360706b4fc4SDimitry Andric for (const auto &I : BB)
361706b4fc4SDimitry Andric mapValueToSlot(&I, MST, Slots2Values);
362706b4fc4SDimitry Andric }
363706b4fc4SDimitry Andric }
364706b4fc4SDimitry Andric
getIRValue(unsigned Slot)365706b4fc4SDimitry Andric const Value* PerFunctionMIParsingState::getIRValue(unsigned Slot) {
366706b4fc4SDimitry Andric if (Slots2Values.empty())
367706b4fc4SDimitry Andric initSlots2Values(MF.getFunction(), Slots2Values);
368b60736ecSDimitry Andric return Slots2Values.lookup(Slot);
369706b4fc4SDimitry Andric }
370706b4fc4SDimitry Andric
3711a82d4c0SDimitry Andric namespace {
3721a82d4c0SDimitry Andric
373ee8648bdSDimitry Andric /// A wrapper struct around the 'MachineOperand' struct that includes a source
374dd58ef01SDimitry Andric /// range and other attributes.
375dd58ef01SDimitry Andric struct ParsedMachineOperand {
376ee8648bdSDimitry Andric MachineOperand Operand;
377ee8648bdSDimitry Andric StringRef::iterator Begin;
378ee8648bdSDimitry Andric StringRef::iterator End;
379e3b55780SDimitry Andric std::optional<unsigned> TiedDefIdx;
380ee8648bdSDimitry Andric
ParsedMachineOperand__anon5566a6300111::ParsedMachineOperand381dd58ef01SDimitry Andric ParsedMachineOperand(const MachineOperand &Operand, StringRef::iterator Begin,
382e3b55780SDimitry Andric StringRef::iterator End,
383e3b55780SDimitry Andric std::optional<unsigned> &TiedDefIdx)
384dd58ef01SDimitry Andric : Operand(Operand), Begin(Begin), End(End), TiedDefIdx(TiedDefIdx) {
385dd58ef01SDimitry Andric if (TiedDefIdx)
386dd58ef01SDimitry Andric assert(Operand.isReg() && Operand.isUse() &&
387dd58ef01SDimitry Andric "Only used register operands can be tied");
388dd58ef01SDimitry Andric }
389ee8648bdSDimitry Andric };
390ee8648bdSDimitry Andric
3911a82d4c0SDimitry Andric class MIParser {
3921a82d4c0SDimitry Andric MachineFunction &MF;
3931a82d4c0SDimitry Andric SMDiagnostic &Error;
3941a82d4c0SDimitry Andric StringRef Source, CurrentSource;
395344a3780SDimitry Andric SMRange SourceRange;
3961a82d4c0SDimitry Andric MIToken Token;
397b915e9e0SDimitry Andric PerFunctionMIParsingState &PFS;
398dd58ef01SDimitry Andric /// Maps from slot numbers to function's unnamed basic blocks.
399dd58ef01SDimitry Andric DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
4001a82d4c0SDimitry Andric
4011a82d4c0SDimitry Andric public:
402b915e9e0SDimitry Andric MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
40301095a5dSDimitry Andric StringRef Source);
404344a3780SDimitry Andric MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
405344a3780SDimitry Andric StringRef Source, SMRange SourceRange);
4061a82d4c0SDimitry Andric
40701095a5dSDimitry Andric /// \p SkipChar gives the number of characters to skip before looking
40801095a5dSDimitry Andric /// for the next token.
40901095a5dSDimitry Andric void lex(unsigned SkipChar = 0);
4101a82d4c0SDimitry Andric
4111a82d4c0SDimitry Andric /// Report an error at the current location with the given message.
4121a82d4c0SDimitry Andric ///
4131a82d4c0SDimitry Andric /// This function always return true.
4141a82d4c0SDimitry Andric bool error(const Twine &Msg);
4151a82d4c0SDimitry Andric
4161a82d4c0SDimitry Andric /// Report an error at the given location with the given message.
4171a82d4c0SDimitry Andric ///
4181a82d4c0SDimitry Andric /// This function always return true.
4191a82d4c0SDimitry Andric bool error(StringRef::iterator Loc, const Twine &Msg);
4201a82d4c0SDimitry Andric
421dd58ef01SDimitry Andric bool
422dd58ef01SDimitry Andric parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
423dd58ef01SDimitry Andric bool parseBasicBlocks();
4241a82d4c0SDimitry Andric bool parse(MachineInstr *&MI);
425dd58ef01SDimitry Andric bool parseStandaloneMBB(MachineBasicBlock *&MBB);
426cfca06d7SDimitry Andric bool parseStandaloneNamedRegister(Register &Reg);
427b915e9e0SDimitry Andric bool parseStandaloneVirtualRegister(VRegInfo *&Info);
428cfca06d7SDimitry Andric bool parseStandaloneRegister(Register &Reg);
429dd58ef01SDimitry Andric bool parseStandaloneStackObject(int &FI);
430dd58ef01SDimitry Andric bool parseStandaloneMDNode(MDNode *&Node);
431344a3780SDimitry Andric bool parseMachineMetadata();
432344a3780SDimitry Andric bool parseMDTuple(MDNode *&MD, bool IsDistinct);
433344a3780SDimitry Andric bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
434344a3780SDimitry Andric bool parseMetadata(Metadata *&MD);
435dd58ef01SDimitry Andric
436dd58ef01SDimitry Andric bool
437dd58ef01SDimitry Andric parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
438c46e6a59SDimitry Andric bool parseBasicBlock(MachineBasicBlock &MBB,
439c46e6a59SDimitry Andric MachineBasicBlock *&AddFalthroughFrom);
440dd58ef01SDimitry Andric bool parseBasicBlockLiveins(MachineBasicBlock &MBB);
441dd58ef01SDimitry Andric bool parseBasicBlockSuccessors(MachineBasicBlock &MBB);
4421a82d4c0SDimitry Andric
443cfca06d7SDimitry Andric bool parseNamedRegister(Register &Reg);
444b915e9e0SDimitry Andric bool parseVirtualRegister(VRegInfo *&Info);
445eb11fae6SDimitry Andric bool parseNamedVirtualRegister(VRegInfo *&Info);
446cfca06d7SDimitry Andric bool parseRegister(Register &Reg, VRegInfo *&VRegInfo);
447ee8648bdSDimitry Andric bool parseRegisterFlag(unsigned &Flags);
44871d5a254SDimitry Andric bool parseRegisterClassOrBank(VRegInfo &RegInfo);
449ee8648bdSDimitry Andric bool parseSubRegisterIndex(unsigned &SubReg);
450dd58ef01SDimitry Andric bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx);
451dd58ef01SDimitry Andric bool parseRegisterOperand(MachineOperand &Dest,
452e3b55780SDimitry Andric std::optional<unsigned> &TiedDefIdx,
453e3b55780SDimitry Andric bool IsDef = false);
4541a82d4c0SDimitry Andric bool parseImmediateOperand(MachineOperand &Dest);
455eb11fae6SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
456dd58ef01SDimitry Andric const Constant *&C);
457dd58ef01SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
458b915e9e0SDimitry Andric bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty);
459dd58ef01SDimitry Andric bool parseTypedImmediateOperand(MachineOperand &Dest);
460dd58ef01SDimitry Andric bool parseFPImmediateOperand(MachineOperand &Dest);
4611a82d4c0SDimitry Andric bool parseMBBReference(MachineBasicBlock *&MBB);
4621a82d4c0SDimitry Andric bool parseMBBOperand(MachineOperand &Dest);
463dd58ef01SDimitry Andric bool parseStackFrameIndex(int &FI);
464dd58ef01SDimitry Andric bool parseStackObjectOperand(MachineOperand &Dest);
465dd58ef01SDimitry Andric bool parseFixedStackFrameIndex(int &FI);
466dd58ef01SDimitry Andric bool parseFixedStackObjectOperand(MachineOperand &Dest);
467dd58ef01SDimitry Andric bool parseGlobalValue(GlobalValue *&GV);
4681a82d4c0SDimitry Andric bool parseGlobalAddressOperand(MachineOperand &Dest);
469dd58ef01SDimitry Andric bool parseConstantPoolIndexOperand(MachineOperand &Dest);
47001095a5dSDimitry Andric bool parseSubRegisterIndexOperand(MachineOperand &Dest);
471dd58ef01SDimitry Andric bool parseJumpTableIndexOperand(MachineOperand &Dest);
472dd58ef01SDimitry Andric bool parseExternalSymbolOperand(MachineOperand &Dest);
473d8e91e46SDimitry Andric bool parseMCSymbolOperand(MachineOperand &Dest);
4747fa27ce4SDimitry Andric [[nodiscard]] bool parseMDNode(MDNode *&Node);
475eb11fae6SDimitry Andric bool parseDIExpression(MDNode *&Expr);
476d8e91e46SDimitry Andric bool parseDILocation(MDNode *&Expr);
477dd58ef01SDimitry Andric bool parseMetadataOperand(MachineOperand &Dest);
478dd58ef01SDimitry Andric bool parseCFIOffset(int &Offset);
479cfca06d7SDimitry Andric bool parseCFIRegister(Register &Reg);
480344a3780SDimitry Andric bool parseCFIAddressSpace(unsigned &AddressSpace);
481044eb2f6SDimitry Andric bool parseCFIEscapeValues(std::string& Values);
482dd58ef01SDimitry Andric bool parseCFIOperand(MachineOperand &Dest);
483dd58ef01SDimitry Andric bool parseIRBlock(BasicBlock *&BB, const Function &F);
484dd58ef01SDimitry Andric bool parseBlockAddressOperand(MachineOperand &Dest);
485b915e9e0SDimitry Andric bool parseIntrinsicOperand(MachineOperand &Dest);
486b915e9e0SDimitry Andric bool parsePredicateOperand(MachineOperand &Dest);
4871d5ae102SDimitry Andric bool parseShuffleMaskOperand(MachineOperand &Dest);
488dd58ef01SDimitry Andric bool parseTargetIndexOperand(MachineOperand &Dest);
489e3b55780SDimitry Andric bool parseDbgInstrRefOperand(MachineOperand &Dest);
49071d5a254SDimitry Andric bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
491dd58ef01SDimitry Andric bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
492706b4fc4SDimitry Andric bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
493706b4fc4SDimitry Andric MachineOperand &Dest,
494e3b55780SDimitry Andric std::optional<unsigned> &TiedDefIdx);
495706b4fc4SDimitry Andric bool parseMachineOperandAndTargetFlags(const unsigned OpCode,
496706b4fc4SDimitry Andric const unsigned OpIdx,
497706b4fc4SDimitry Andric MachineOperand &Dest,
498e3b55780SDimitry Andric std::optional<unsigned> &TiedDefIdx);
499dd58ef01SDimitry Andric bool parseOffset(int64_t &Offset);
500e3b55780SDimitry Andric bool parseIRBlockAddressTaken(BasicBlock *&BB);
501c0981da4SDimitry Andric bool parseAlignment(uint64_t &Alignment);
502eb11fae6SDimitry Andric bool parseAddrspace(unsigned &Addrspace);
503e3b55780SDimitry Andric bool parseSectionID(std::optional<MBBSectionID> &SID);
504b1c73532SDimitry Andric bool parseBBID(std::optional<UniqueBBID> &BBID);
505b1c73532SDimitry Andric bool parseCallFrameSize(unsigned &CallFrameSize);
506dd58ef01SDimitry Andric bool parseOperandsOffset(MachineOperand &Op);
507dd58ef01SDimitry Andric bool parseIRValue(const Value *&V);
50801095a5dSDimitry Andric bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
509dd58ef01SDimitry Andric bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV);
510dd58ef01SDimitry Andric bool parseMachinePointerInfo(MachinePointerInfo &Dest);
511ca089b24SDimitry Andric bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID);
51271d5a254SDimitry Andric bool parseOptionalAtomicOrdering(AtomicOrdering &Order);
513dd58ef01SDimitry Andric bool parseMachineMemoryOperand(MachineMemOperand *&Dest);
514d8e91e46SDimitry Andric bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol);
515706b4fc4SDimitry Andric bool parseHeapAllocMarker(MDNode *&Node);
516e3b55780SDimitry Andric bool parsePCSections(MDNode *&Node);
517706b4fc4SDimitry Andric
518706b4fc4SDimitry Andric bool parseTargetImmMnemonic(const unsigned OpCode, const unsigned OpIdx,
519706b4fc4SDimitry Andric MachineOperand &Dest, const MIRFormatter &MF);
5201a82d4c0SDimitry Andric
5211a82d4c0SDimitry Andric private:
5221a82d4c0SDimitry Andric /// Convert the integer literal in the current token into an unsigned integer.
5231a82d4c0SDimitry Andric ///
5241a82d4c0SDimitry Andric /// Return true if an error occurred.
5251a82d4c0SDimitry Andric bool getUnsigned(unsigned &Result);
5261a82d4c0SDimitry Andric
527dd58ef01SDimitry Andric /// Convert the integer literal in the current token into an uint64.
528dd58ef01SDimitry Andric ///
529dd58ef01SDimitry Andric /// Return true if an error occurred.
530dd58ef01SDimitry Andric bool getUint64(uint64_t &Result);
531dd58ef01SDimitry Andric
532b915e9e0SDimitry Andric /// Convert the hexadecimal literal in the current token into an unsigned
533b915e9e0SDimitry Andric /// APInt with a minimum bitwidth required to represent the value.
534b915e9e0SDimitry Andric ///
535b915e9e0SDimitry Andric /// Return true if the literal does not represent an integer value.
536b915e9e0SDimitry Andric bool getHexUint(APInt &Result);
537b915e9e0SDimitry Andric
538dd58ef01SDimitry Andric /// If the current token is of the given kind, consume it and return false.
539dd58ef01SDimitry Andric /// Otherwise report an error and return true.
540dd58ef01SDimitry Andric bool expectAndConsume(MIToken::TokenKind TokenKind);
541dd58ef01SDimitry Andric
542dd58ef01SDimitry Andric /// If the current token is of the given kind, consume it and return true.
543dd58ef01SDimitry Andric /// Otherwise return false.
544dd58ef01SDimitry Andric bool consumeIfPresent(MIToken::TokenKind TokenKind);
545dd58ef01SDimitry Andric
546dd58ef01SDimitry Andric bool parseInstruction(unsigned &OpCode, unsigned &Flags);
5471a82d4c0SDimitry Andric
548dd58ef01SDimitry Andric bool assignRegisterTies(MachineInstr &MI,
549dd58ef01SDimitry Andric ArrayRef<ParsedMachineOperand> Operands);
550dd58ef01SDimitry Andric
551dd58ef01SDimitry Andric bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
552ee8648bdSDimitry Andric const MCInstrDesc &MCID);
553ee8648bdSDimitry Andric
554dd58ef01SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot);
555dd58ef01SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot, const Function &F);
556dd58ef01SDimitry Andric
557d8e91e46SDimitry Andric /// Get or create an MCSymbol for a given name.
558d8e91e46SDimitry Andric MCSymbol *getOrCreateMCSymbol(StringRef Name);
559d8e91e46SDimitry Andric
560ca089b24SDimitry Andric /// parseStringConstant
561ca089b24SDimitry Andric /// ::= StringConstant
562ca089b24SDimitry Andric bool parseStringConstant(std::string &Result);
563344a3780SDimitry Andric
564344a3780SDimitry Andric /// Map the location in the MI string to the corresponding location specified
565344a3780SDimitry Andric /// in `SourceRange`.
566344a3780SDimitry Andric SMLoc mapSMLoc(StringRef::iterator Loc);
5671a82d4c0SDimitry Andric };
5681a82d4c0SDimitry Andric
5691a82d4c0SDimitry Andric } // end anonymous namespace
5701a82d4c0SDimitry Andric
MIParser(PerFunctionMIParsingState & PFS,SMDiagnostic & Error,StringRef Source)571b915e9e0SDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
57201095a5dSDimitry Andric StringRef Source)
57301095a5dSDimitry Andric : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS)
57401095a5dSDimitry Andric {}
5751a82d4c0SDimitry Andric
MIParser(PerFunctionMIParsingState & PFS,SMDiagnostic & Error,StringRef Source,SMRange SourceRange)576344a3780SDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
577344a3780SDimitry Andric StringRef Source, SMRange SourceRange)
578344a3780SDimitry Andric : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source),
579344a3780SDimitry Andric SourceRange(SourceRange), PFS(PFS) {}
580344a3780SDimitry Andric
lex(unsigned SkipChar)58101095a5dSDimitry Andric void MIParser::lex(unsigned SkipChar) {
5821a82d4c0SDimitry Andric CurrentSource = lexMIToken(
583cfca06d7SDimitry Andric CurrentSource.slice(SkipChar, StringRef::npos), Token,
5841a82d4c0SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); });
5851a82d4c0SDimitry Andric }
5861a82d4c0SDimitry Andric
error(const Twine & Msg)5871a82d4c0SDimitry Andric bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); }
5881a82d4c0SDimitry Andric
error(StringRef::iterator Loc,const Twine & Msg)5891a82d4c0SDimitry Andric bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
59001095a5dSDimitry Andric const SourceMgr &SM = *PFS.SM;
5911a82d4c0SDimitry Andric assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
592dd58ef01SDimitry Andric const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID());
593dd58ef01SDimitry Andric if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) {
594dd58ef01SDimitry Andric // Create an ordinary diagnostic when the source manager's buffer is the
595dd58ef01SDimitry Andric // source string.
596dd58ef01SDimitry Andric Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
5971a82d4c0SDimitry Andric return true;
5981a82d4c0SDimitry Andric }
599dd58ef01SDimitry Andric // Create a diagnostic for a YAML string literal.
600dd58ef01SDimitry Andric Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1,
601dd58ef01SDimitry Andric Loc - Source.data(), SourceMgr::DK_Error, Msg.str(),
602e3b55780SDimitry Andric Source, std::nullopt, std::nullopt);
603dd58ef01SDimitry Andric return true;
604dd58ef01SDimitry Andric }
605dd58ef01SDimitry Andric
mapSMLoc(StringRef::iterator Loc)606344a3780SDimitry Andric SMLoc MIParser::mapSMLoc(StringRef::iterator Loc) {
607344a3780SDimitry Andric assert(SourceRange.isValid() && "Invalid source range");
608344a3780SDimitry Andric assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
609344a3780SDimitry Andric return SMLoc::getFromPointer(SourceRange.Start.getPointer() +
610344a3780SDimitry Andric (Loc - Source.data()));
611344a3780SDimitry Andric }
612344a3780SDimitry Andric
613706b4fc4SDimitry Andric typedef function_ref<bool(StringRef::iterator Loc, const Twine &)>
614706b4fc4SDimitry Andric ErrorCallbackType;
615706b4fc4SDimitry Andric
toString(MIToken::TokenKind TokenKind)616dd58ef01SDimitry Andric static const char *toString(MIToken::TokenKind TokenKind) {
617dd58ef01SDimitry Andric switch (TokenKind) {
618dd58ef01SDimitry Andric case MIToken::comma:
619dd58ef01SDimitry Andric return "','";
620dd58ef01SDimitry Andric case MIToken::equal:
621dd58ef01SDimitry Andric return "'='";
622dd58ef01SDimitry Andric case MIToken::colon:
623dd58ef01SDimitry Andric return "':'";
624dd58ef01SDimitry Andric case MIToken::lparen:
625dd58ef01SDimitry Andric return "'('";
626dd58ef01SDimitry Andric case MIToken::rparen:
627dd58ef01SDimitry Andric return "')'";
628dd58ef01SDimitry Andric default:
629dd58ef01SDimitry Andric return "<unknown token>";
630dd58ef01SDimitry Andric }
631dd58ef01SDimitry Andric }
632dd58ef01SDimitry Andric
expectAndConsume(MIToken::TokenKind TokenKind)633dd58ef01SDimitry Andric bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) {
634dd58ef01SDimitry Andric if (Token.isNot(TokenKind))
635dd58ef01SDimitry Andric return error(Twine("expected ") + toString(TokenKind));
636dd58ef01SDimitry Andric lex();
637dd58ef01SDimitry Andric return false;
638dd58ef01SDimitry Andric }
639dd58ef01SDimitry Andric
consumeIfPresent(MIToken::TokenKind TokenKind)640dd58ef01SDimitry Andric bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) {
641dd58ef01SDimitry Andric if (Token.isNot(TokenKind))
642dd58ef01SDimitry Andric return false;
643dd58ef01SDimitry Andric lex();
644dd58ef01SDimitry Andric return true;
645dd58ef01SDimitry Andric }
646dd58ef01SDimitry Andric
647cfca06d7SDimitry Andric // Parse Machine Basic Block Section ID.
parseSectionID(std::optional<MBBSectionID> & SID)648e3b55780SDimitry Andric bool MIParser::parseSectionID(std::optional<MBBSectionID> &SID) {
649cfca06d7SDimitry Andric assert(Token.is(MIToken::kw_bbsections));
650cfca06d7SDimitry Andric lex();
651cfca06d7SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
652cfca06d7SDimitry Andric unsigned Value = 0;
653cfca06d7SDimitry Andric if (getUnsigned(Value))
654cfca06d7SDimitry Andric return error("Unknown Section ID");
655cfca06d7SDimitry Andric SID = MBBSectionID{Value};
656cfca06d7SDimitry Andric } else {
657cfca06d7SDimitry Andric const StringRef &S = Token.stringValue();
658cfca06d7SDimitry Andric if (S == "Exception")
659cfca06d7SDimitry Andric SID = MBBSectionID::ExceptionSectionID;
660cfca06d7SDimitry Andric else if (S == "Cold")
661cfca06d7SDimitry Andric SID = MBBSectionID::ColdSectionID;
662cfca06d7SDimitry Andric else
663cfca06d7SDimitry Andric return error("Unknown Section ID");
664cfca06d7SDimitry Andric }
665cfca06d7SDimitry Andric lex();
666cfca06d7SDimitry Andric return false;
667cfca06d7SDimitry Andric }
668cfca06d7SDimitry Andric
669e3b55780SDimitry Andric // Parse Machine Basic Block ID.
parseBBID(std::optional<UniqueBBID> & BBID)670b1c73532SDimitry Andric bool MIParser::parseBBID(std::optional<UniqueBBID> &BBID) {
671e3b55780SDimitry Andric assert(Token.is(MIToken::kw_bb_id));
672e3b55780SDimitry Andric lex();
673b1c73532SDimitry Andric unsigned BaseID = 0;
674b1c73532SDimitry Andric unsigned CloneID = 0;
675b1c73532SDimitry Andric if (getUnsigned(BaseID))
676b1c73532SDimitry Andric return error("Unknown BB ID");
677b1c73532SDimitry Andric lex();
678b1c73532SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
679b1c73532SDimitry Andric if (getUnsigned(CloneID))
680b1c73532SDimitry Andric return error("Unknown Clone ID");
681b1c73532SDimitry Andric lex();
682b1c73532SDimitry Andric }
683b1c73532SDimitry Andric BBID = {BaseID, CloneID};
684b1c73532SDimitry Andric return false;
685b1c73532SDimitry Andric }
686b1c73532SDimitry Andric
687b1c73532SDimitry Andric // Parse basic block call frame size.
parseCallFrameSize(unsigned & CallFrameSize)688b1c73532SDimitry Andric bool MIParser::parseCallFrameSize(unsigned &CallFrameSize) {
689b1c73532SDimitry Andric assert(Token.is(MIToken::kw_call_frame_size));
690b1c73532SDimitry Andric lex();
691e3b55780SDimitry Andric unsigned Value = 0;
692e3b55780SDimitry Andric if (getUnsigned(Value))
693b1c73532SDimitry Andric return error("Unknown call frame size");
694b1c73532SDimitry Andric CallFrameSize = Value;
695e3b55780SDimitry Andric lex();
696e3b55780SDimitry Andric return false;
697e3b55780SDimitry Andric }
698e3b55780SDimitry Andric
parseBasicBlockDefinition(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)699dd58ef01SDimitry Andric bool MIParser::parseBasicBlockDefinition(
700dd58ef01SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
701dd58ef01SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
702dd58ef01SDimitry Andric unsigned ID = 0;
703dd58ef01SDimitry Andric if (getUnsigned(ID))
704dd58ef01SDimitry Andric return true;
705dd58ef01SDimitry Andric auto Loc = Token.location();
706dd58ef01SDimitry Andric auto Name = Token.stringValue();
707dd58ef01SDimitry Andric lex();
708e3b55780SDimitry Andric bool MachineBlockAddressTaken = false;
709e3b55780SDimitry Andric BasicBlock *AddressTakenIRBlock = nullptr;
710dd58ef01SDimitry Andric bool IsLandingPad = false;
711c0981da4SDimitry Andric bool IsInlineAsmBrIndirectTarget = false;
712cfca06d7SDimitry Andric bool IsEHFuncletEntry = false;
713e3b55780SDimitry Andric std::optional<MBBSectionID> SectionID;
714c0981da4SDimitry Andric uint64_t Alignment = 0;
715b1c73532SDimitry Andric std::optional<UniqueBBID> BBID;
716b1c73532SDimitry Andric unsigned CallFrameSize = 0;
717dd58ef01SDimitry Andric BasicBlock *BB = nullptr;
718dd58ef01SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
719dd58ef01SDimitry Andric do {
720dd58ef01SDimitry Andric // TODO: Report an error when multiple same attributes are specified.
721dd58ef01SDimitry Andric switch (Token.kind()) {
722e3b55780SDimitry Andric case MIToken::kw_machine_block_address_taken:
723e3b55780SDimitry Andric MachineBlockAddressTaken = true;
724dd58ef01SDimitry Andric lex();
725dd58ef01SDimitry Andric break;
726e3b55780SDimitry Andric case MIToken::kw_ir_block_address_taken:
727e3b55780SDimitry Andric if (parseIRBlockAddressTaken(AddressTakenIRBlock))
728e3b55780SDimitry Andric return true;
729e3b55780SDimitry Andric break;
730dd58ef01SDimitry Andric case MIToken::kw_landing_pad:
731dd58ef01SDimitry Andric IsLandingPad = true;
732dd58ef01SDimitry Andric lex();
733dd58ef01SDimitry Andric break;
734c0981da4SDimitry Andric case MIToken::kw_inlineasm_br_indirect_target:
735c0981da4SDimitry Andric IsInlineAsmBrIndirectTarget = true;
736c0981da4SDimitry Andric lex();
737c0981da4SDimitry Andric break;
738cfca06d7SDimitry Andric case MIToken::kw_ehfunclet_entry:
739cfca06d7SDimitry Andric IsEHFuncletEntry = true;
740cfca06d7SDimitry Andric lex();
741cfca06d7SDimitry Andric break;
742dd58ef01SDimitry Andric case MIToken::kw_align:
743dd58ef01SDimitry Andric if (parseAlignment(Alignment))
744dd58ef01SDimitry Andric return true;
745dd58ef01SDimitry Andric break;
746dd58ef01SDimitry Andric case MIToken::IRBlock:
747e3b55780SDimitry Andric case MIToken::NamedIRBlock:
748dd58ef01SDimitry Andric // TODO: Report an error when both name and ir block are specified.
749044eb2f6SDimitry Andric if (parseIRBlock(BB, MF.getFunction()))
750dd58ef01SDimitry Andric return true;
751dd58ef01SDimitry Andric lex();
752dd58ef01SDimitry Andric break;
753cfca06d7SDimitry Andric case MIToken::kw_bbsections:
754cfca06d7SDimitry Andric if (parseSectionID(SectionID))
755cfca06d7SDimitry Andric return true;
756cfca06d7SDimitry Andric break;
757e3b55780SDimitry Andric case MIToken::kw_bb_id:
758e3b55780SDimitry Andric if (parseBBID(BBID))
759e3b55780SDimitry Andric return true;
760e3b55780SDimitry Andric break;
761b1c73532SDimitry Andric case MIToken::kw_call_frame_size:
762b1c73532SDimitry Andric if (parseCallFrameSize(CallFrameSize))
763b1c73532SDimitry Andric return true;
764b1c73532SDimitry Andric break;
765dd58ef01SDimitry Andric default:
766dd58ef01SDimitry Andric break;
767dd58ef01SDimitry Andric }
768dd58ef01SDimitry Andric } while (consumeIfPresent(MIToken::comma));
769dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
770dd58ef01SDimitry Andric return true;
771dd58ef01SDimitry Andric }
772dd58ef01SDimitry Andric if (expectAndConsume(MIToken::colon))
773dd58ef01SDimitry Andric return true;
774dd58ef01SDimitry Andric
775dd58ef01SDimitry Andric if (!Name.empty()) {
776dd58ef01SDimitry Andric BB = dyn_cast_or_null<BasicBlock>(
777044eb2f6SDimitry Andric MF.getFunction().getValueSymbolTable()->lookup(Name));
778dd58ef01SDimitry Andric if (!BB)
779dd58ef01SDimitry Andric return error(Loc, Twine("basic block '") + Name +
780dd58ef01SDimitry Andric "' is not defined in the function '" +
781dd58ef01SDimitry Andric MF.getName() + "'");
782dd58ef01SDimitry Andric }
783dd58ef01SDimitry Andric auto *MBB = MF.CreateMachineBasicBlock(BB);
784dd58ef01SDimitry Andric MF.insert(MF.end(), MBB);
785dd58ef01SDimitry Andric bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second;
786dd58ef01SDimitry Andric if (!WasInserted)
787dd58ef01SDimitry Andric return error(Loc, Twine("redefinition of machine basic block with id #") +
788dd58ef01SDimitry Andric Twine(ID));
789dd58ef01SDimitry Andric if (Alignment)
7901d5ae102SDimitry Andric MBB->setAlignment(Align(Alignment));
791e3b55780SDimitry Andric if (MachineBlockAddressTaken)
792e3b55780SDimitry Andric MBB->setMachineBlockAddressTaken();
793e3b55780SDimitry Andric if (AddressTakenIRBlock)
794e3b55780SDimitry Andric MBB->setAddressTakenIRBlock(AddressTakenIRBlock);
795dd58ef01SDimitry Andric MBB->setIsEHPad(IsLandingPad);
796c0981da4SDimitry Andric MBB->setIsInlineAsmBrIndirectTarget(IsInlineAsmBrIndirectTarget);
797cfca06d7SDimitry Andric MBB->setIsEHFuncletEntry(IsEHFuncletEntry);
798145449b1SDimitry Andric if (SectionID) {
799e3b55780SDimitry Andric MBB->setSectionID(*SectionID);
800cfca06d7SDimitry Andric MF.setBBSectionsType(BasicBlockSection::List);
801cfca06d7SDimitry Andric }
802e3b55780SDimitry Andric if (BBID.has_value()) {
803e3b55780SDimitry Andric // BBSectionsType is set to `List` if any basic blocks has `SectionID`.
804e3b55780SDimitry Andric // Here, we set it to `Labels` if it hasn't been set above.
805e3b55780SDimitry Andric if (!MF.hasBBSections())
806e3b55780SDimitry Andric MF.setBBSectionsType(BasicBlockSection::Labels);
807e3b55780SDimitry Andric MBB->setBBID(BBID.value());
808e3b55780SDimitry Andric }
809b1c73532SDimitry Andric MBB->setCallFrameSize(CallFrameSize);
810dd58ef01SDimitry Andric return false;
811dd58ef01SDimitry Andric }
812dd58ef01SDimitry Andric
parseBasicBlockDefinitions(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)813dd58ef01SDimitry Andric bool MIParser::parseBasicBlockDefinitions(
814dd58ef01SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
815dd58ef01SDimitry Andric lex();
816dd58ef01SDimitry Andric // Skip until the first machine basic block.
817dd58ef01SDimitry Andric while (Token.is(MIToken::Newline))
818dd58ef01SDimitry Andric lex();
819dd58ef01SDimitry Andric if (Token.isErrorOrEOF())
820dd58ef01SDimitry Andric return Token.isError();
821dd58ef01SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlockLabel))
822dd58ef01SDimitry Andric return error("expected a basic block definition before instructions");
823dd58ef01SDimitry Andric unsigned BraceDepth = 0;
824dd58ef01SDimitry Andric do {
825dd58ef01SDimitry Andric if (parseBasicBlockDefinition(MBBSlots))
826dd58ef01SDimitry Andric return true;
827dd58ef01SDimitry Andric bool IsAfterNewline = false;
828dd58ef01SDimitry Andric // Skip until the next machine basic block.
829dd58ef01SDimitry Andric while (true) {
830dd58ef01SDimitry Andric if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) ||
831dd58ef01SDimitry Andric Token.isErrorOrEOF())
832dd58ef01SDimitry Andric break;
833dd58ef01SDimitry Andric else if (Token.is(MIToken::MachineBasicBlockLabel))
834dd58ef01SDimitry Andric return error("basic block definition should be located at the start of "
835dd58ef01SDimitry Andric "the line");
836dd58ef01SDimitry Andric else if (consumeIfPresent(MIToken::Newline)) {
837dd58ef01SDimitry Andric IsAfterNewline = true;
838dd58ef01SDimitry Andric continue;
839dd58ef01SDimitry Andric }
840dd58ef01SDimitry Andric IsAfterNewline = false;
841dd58ef01SDimitry Andric if (Token.is(MIToken::lbrace))
842dd58ef01SDimitry Andric ++BraceDepth;
843dd58ef01SDimitry Andric if (Token.is(MIToken::rbrace)) {
844dd58ef01SDimitry Andric if (!BraceDepth)
845dd58ef01SDimitry Andric return error("extraneous closing brace ('}')");
846dd58ef01SDimitry Andric --BraceDepth;
847dd58ef01SDimitry Andric }
848dd58ef01SDimitry Andric lex();
849dd58ef01SDimitry Andric }
850dd58ef01SDimitry Andric // Verify that we closed all of the '{' at the end of a file or a block.
851dd58ef01SDimitry Andric if (!Token.isError() && BraceDepth)
852dd58ef01SDimitry Andric return error("expected '}'"); // FIXME: Report a note that shows '{'.
853dd58ef01SDimitry Andric } while (!Token.isErrorOrEOF());
854dd58ef01SDimitry Andric return Token.isError();
855dd58ef01SDimitry Andric }
856dd58ef01SDimitry Andric
parseBasicBlockLiveins(MachineBasicBlock & MBB)857dd58ef01SDimitry Andric bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) {
858dd58ef01SDimitry Andric assert(Token.is(MIToken::kw_liveins));
859dd58ef01SDimitry Andric lex();
860dd58ef01SDimitry Andric if (expectAndConsume(MIToken::colon))
861dd58ef01SDimitry Andric return true;
862dd58ef01SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of liveins.
863dd58ef01SDimitry Andric return false;
864dd58ef01SDimitry Andric do {
865dd58ef01SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
866dd58ef01SDimitry Andric return error("expected a named register");
867cfca06d7SDimitry Andric Register Reg;
868b915e9e0SDimitry Andric if (parseNamedRegister(Reg))
869dd58ef01SDimitry Andric return true;
870dd58ef01SDimitry Andric lex();
871b915e9e0SDimitry Andric LaneBitmask Mask = LaneBitmask::getAll();
872b915e9e0SDimitry Andric if (consumeIfPresent(MIToken::colon)) {
873b915e9e0SDimitry Andric // Parse lane mask.
874b915e9e0SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
875b915e9e0SDimitry Andric Token.isNot(MIToken::HexLiteral))
876b915e9e0SDimitry Andric return error("expected a lane mask");
877cfca06d7SDimitry Andric static_assert(sizeof(LaneBitmask::Type) == sizeof(uint64_t),
878b915e9e0SDimitry Andric "Use correct get-function for lane mask");
879b915e9e0SDimitry Andric LaneBitmask::Type V;
880cfca06d7SDimitry Andric if (getUint64(V))
881b915e9e0SDimitry Andric return error("invalid lane mask value");
882b915e9e0SDimitry Andric Mask = LaneBitmask(V);
883b915e9e0SDimitry Andric lex();
884b915e9e0SDimitry Andric }
885b915e9e0SDimitry Andric MBB.addLiveIn(Reg, Mask);
886dd58ef01SDimitry Andric } while (consumeIfPresent(MIToken::comma));
887dd58ef01SDimitry Andric return false;
888dd58ef01SDimitry Andric }
889dd58ef01SDimitry Andric
parseBasicBlockSuccessors(MachineBasicBlock & MBB)890dd58ef01SDimitry Andric bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) {
891dd58ef01SDimitry Andric assert(Token.is(MIToken::kw_successors));
892dd58ef01SDimitry Andric lex();
893dd58ef01SDimitry Andric if (expectAndConsume(MIToken::colon))
894dd58ef01SDimitry Andric return true;
895dd58ef01SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of successors.
896dd58ef01SDimitry Andric return false;
897dd58ef01SDimitry Andric do {
898dd58ef01SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock))
899dd58ef01SDimitry Andric return error("expected a machine basic block reference");
900dd58ef01SDimitry Andric MachineBasicBlock *SuccMBB = nullptr;
901dd58ef01SDimitry Andric if (parseMBBReference(SuccMBB))
902dd58ef01SDimitry Andric return true;
903dd58ef01SDimitry Andric lex();
904dd58ef01SDimitry Andric unsigned Weight = 0;
905dd58ef01SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
906b915e9e0SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
907b915e9e0SDimitry Andric Token.isNot(MIToken::HexLiteral))
908dd58ef01SDimitry Andric return error("expected an integer literal after '('");
909dd58ef01SDimitry Andric if (getUnsigned(Weight))
910dd58ef01SDimitry Andric return true;
911dd58ef01SDimitry Andric lex();
912dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
913dd58ef01SDimitry Andric return true;
914dd58ef01SDimitry Andric }
915dd58ef01SDimitry Andric MBB.addSuccessor(SuccMBB, BranchProbability::getRaw(Weight));
916dd58ef01SDimitry Andric } while (consumeIfPresent(MIToken::comma));
917dd58ef01SDimitry Andric MBB.normalizeSuccProbs();
918dd58ef01SDimitry Andric return false;
919dd58ef01SDimitry Andric }
920dd58ef01SDimitry Andric
parseBasicBlock(MachineBasicBlock & MBB,MachineBasicBlock * & AddFalthroughFrom)921c46e6a59SDimitry Andric bool MIParser::parseBasicBlock(MachineBasicBlock &MBB,
922c46e6a59SDimitry Andric MachineBasicBlock *&AddFalthroughFrom) {
923dd58ef01SDimitry Andric // Skip the definition.
924dd58ef01SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
925dd58ef01SDimitry Andric lex();
926dd58ef01SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
927dd58ef01SDimitry Andric while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF())
928dd58ef01SDimitry Andric lex();
929dd58ef01SDimitry Andric consumeIfPresent(MIToken::rparen);
930dd58ef01SDimitry Andric }
931dd58ef01SDimitry Andric consumeIfPresent(MIToken::colon);
932dd58ef01SDimitry Andric
933dd58ef01SDimitry Andric // Parse the liveins and successors.
934dd58ef01SDimitry Andric // N.B: Multiple lists of successors and liveins are allowed and they're
935dd58ef01SDimitry Andric // merged into one.
936dd58ef01SDimitry Andric // Example:
9376f8fc217SDimitry Andric // liveins: $edi
9386f8fc217SDimitry Andric // liveins: $esi
939dd58ef01SDimitry Andric //
940dd58ef01SDimitry Andric // is equivalent to
9416f8fc217SDimitry Andric // liveins: $edi, $esi
9429df3605dSDimitry Andric bool ExplicitSuccessors = false;
943dd58ef01SDimitry Andric while (true) {
944dd58ef01SDimitry Andric if (Token.is(MIToken::kw_successors)) {
945dd58ef01SDimitry Andric if (parseBasicBlockSuccessors(MBB))
946dd58ef01SDimitry Andric return true;
9479df3605dSDimitry Andric ExplicitSuccessors = true;
948dd58ef01SDimitry Andric } else if (Token.is(MIToken::kw_liveins)) {
949dd58ef01SDimitry Andric if (parseBasicBlockLiveins(MBB))
950dd58ef01SDimitry Andric return true;
951dd58ef01SDimitry Andric } else if (consumeIfPresent(MIToken::Newline)) {
952dd58ef01SDimitry Andric continue;
953dd58ef01SDimitry Andric } else
954dd58ef01SDimitry Andric break;
955dd58ef01SDimitry Andric if (!Token.isNewlineOrEOF())
956dd58ef01SDimitry Andric return error("expected line break at the end of a list");
957dd58ef01SDimitry Andric lex();
958dd58ef01SDimitry Andric }
959dd58ef01SDimitry Andric
960dd58ef01SDimitry Andric // Parse the instructions.
961dd58ef01SDimitry Andric bool IsInBundle = false;
962dd58ef01SDimitry Andric MachineInstr *PrevMI = nullptr;
963c46e6a59SDimitry Andric while (!Token.is(MIToken::MachineBasicBlockLabel) &&
964c46e6a59SDimitry Andric !Token.is(MIToken::Eof)) {
965c46e6a59SDimitry Andric if (consumeIfPresent(MIToken::Newline))
966dd58ef01SDimitry Andric continue;
967dd58ef01SDimitry Andric if (consumeIfPresent(MIToken::rbrace)) {
968dd58ef01SDimitry Andric // The first parsing pass should verify that all closing '}' have an
969dd58ef01SDimitry Andric // opening '{'.
970dd58ef01SDimitry Andric assert(IsInBundle);
971dd58ef01SDimitry Andric IsInBundle = false;
972dd58ef01SDimitry Andric continue;
973dd58ef01SDimitry Andric }
974dd58ef01SDimitry Andric MachineInstr *MI = nullptr;
975dd58ef01SDimitry Andric if (parse(MI))
976dd58ef01SDimitry Andric return true;
977dd58ef01SDimitry Andric MBB.insert(MBB.end(), MI);
978dd58ef01SDimitry Andric if (IsInBundle) {
979dd58ef01SDimitry Andric PrevMI->setFlag(MachineInstr::BundledSucc);
980dd58ef01SDimitry Andric MI->setFlag(MachineInstr::BundledPred);
981dd58ef01SDimitry Andric }
982dd58ef01SDimitry Andric PrevMI = MI;
983dd58ef01SDimitry Andric if (Token.is(MIToken::lbrace)) {
984dd58ef01SDimitry Andric if (IsInBundle)
985dd58ef01SDimitry Andric return error("nested instruction bundles are not allowed");
986dd58ef01SDimitry Andric lex();
987dd58ef01SDimitry Andric // This instruction is the start of the bundle.
988dd58ef01SDimitry Andric MI->setFlag(MachineInstr::BundledSucc);
989dd58ef01SDimitry Andric IsInBundle = true;
990dd58ef01SDimitry Andric if (!Token.is(MIToken::Newline))
991dd58ef01SDimitry Andric // The next instruction can be on the same line.
992dd58ef01SDimitry Andric continue;
993dd58ef01SDimitry Andric }
994dd58ef01SDimitry Andric assert(Token.isNewlineOrEOF() && "MI is not fully parsed");
995dd58ef01SDimitry Andric lex();
996dd58ef01SDimitry Andric }
997c46e6a59SDimitry Andric
998c46e6a59SDimitry Andric // Construct successor list by searching for basic block machine operands.
9999df3605dSDimitry Andric if (!ExplicitSuccessors) {
1000c46e6a59SDimitry Andric SmallVector<MachineBasicBlock*,4> Successors;
1001c46e6a59SDimitry Andric bool IsFallthrough;
1002c46e6a59SDimitry Andric guessSuccessors(MBB, Successors, IsFallthrough);
1003c46e6a59SDimitry Andric for (MachineBasicBlock *Succ : Successors)
1004c46e6a59SDimitry Andric MBB.addSuccessor(Succ);
1005c46e6a59SDimitry Andric
1006c46e6a59SDimitry Andric if (IsFallthrough) {
1007c46e6a59SDimitry Andric AddFalthroughFrom = &MBB;
1008c46e6a59SDimitry Andric } else {
1009c46e6a59SDimitry Andric MBB.normalizeSuccProbs();
1010c46e6a59SDimitry Andric }
1011c46e6a59SDimitry Andric }
1012c46e6a59SDimitry Andric
1013dd58ef01SDimitry Andric return false;
1014dd58ef01SDimitry Andric }
1015dd58ef01SDimitry Andric
parseBasicBlocks()1016dd58ef01SDimitry Andric bool MIParser::parseBasicBlocks() {
1017dd58ef01SDimitry Andric lex();
1018dd58ef01SDimitry Andric // Skip until the first machine basic block.
1019dd58ef01SDimitry Andric while (Token.is(MIToken::Newline))
1020dd58ef01SDimitry Andric lex();
1021dd58ef01SDimitry Andric if (Token.isErrorOrEOF())
1022dd58ef01SDimitry Andric return Token.isError();
1023dd58ef01SDimitry Andric // The first parsing pass should have verified that this token is a MBB label
1024dd58ef01SDimitry Andric // in the 'parseBasicBlockDefinitions' method.
1025dd58ef01SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel));
1026c46e6a59SDimitry Andric MachineBasicBlock *AddFalthroughFrom = nullptr;
1027dd58ef01SDimitry Andric do {
1028dd58ef01SDimitry Andric MachineBasicBlock *MBB = nullptr;
1029dd58ef01SDimitry Andric if (parseMBBReference(MBB))
1030dd58ef01SDimitry Andric return true;
1031c46e6a59SDimitry Andric if (AddFalthroughFrom) {
1032c46e6a59SDimitry Andric if (!AddFalthroughFrom->isSuccessor(MBB))
1033c46e6a59SDimitry Andric AddFalthroughFrom->addSuccessor(MBB);
1034c46e6a59SDimitry Andric AddFalthroughFrom->normalizeSuccProbs();
1035c46e6a59SDimitry Andric AddFalthroughFrom = nullptr;
1036c46e6a59SDimitry Andric }
1037c46e6a59SDimitry Andric if (parseBasicBlock(*MBB, AddFalthroughFrom))
1038dd58ef01SDimitry Andric return true;
1039dd58ef01SDimitry Andric // The method 'parseBasicBlock' should parse the whole block until the next
1040dd58ef01SDimitry Andric // block or the end of file.
1041dd58ef01SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof));
1042dd58ef01SDimitry Andric } while (Token.isNot(MIToken::Eof));
1043dd58ef01SDimitry Andric return false;
1044dd58ef01SDimitry Andric }
10451a82d4c0SDimitry Andric
parse(MachineInstr * & MI)10461a82d4c0SDimitry Andric bool MIParser::parse(MachineInstr *&MI) {
10471a82d4c0SDimitry Andric // Parse any register operands before '='
10481a82d4c0SDimitry Andric MachineOperand MO = MachineOperand::CreateImm(0);
1049dd58ef01SDimitry Andric SmallVector<ParsedMachineOperand, 8> Operands;
1050dd58ef01SDimitry Andric while (Token.isRegister() || Token.isRegisterFlag()) {
1051ee8648bdSDimitry Andric auto Loc = Token.location();
1052e3b55780SDimitry Andric std::optional<unsigned> TiedDefIdx;
1053dd58ef01SDimitry Andric if (parseRegisterOperand(MO, TiedDefIdx, /*IsDef=*/true))
10541a82d4c0SDimitry Andric return true;
1055dd58ef01SDimitry Andric Operands.push_back(
1056dd58ef01SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
1057dd58ef01SDimitry Andric if (Token.isNot(MIToken::comma))
1058dd58ef01SDimitry Andric break;
10591a82d4c0SDimitry Andric lex();
10601a82d4c0SDimitry Andric }
1061dd58ef01SDimitry Andric if (!Operands.empty() && expectAndConsume(MIToken::equal))
10621a82d4c0SDimitry Andric return true;
10631a82d4c0SDimitry Andric
1064dd58ef01SDimitry Andric unsigned OpCode, Flags = 0;
1065dd58ef01SDimitry Andric if (Token.isError() || parseInstruction(OpCode, Flags))
1066dd58ef01SDimitry Andric return true;
10671a82d4c0SDimitry Andric
10681a82d4c0SDimitry Andric // Parse the remaining machine operands.
1069d8e91e46SDimitry Andric while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) &&
1070d8e91e46SDimitry Andric Token.isNot(MIToken::kw_post_instr_symbol) &&
1071706b4fc4SDimitry Andric Token.isNot(MIToken::kw_heap_alloc_marker) &&
1072e3b55780SDimitry Andric Token.isNot(MIToken::kw_pcsections) &&
1073e3b55780SDimitry Andric Token.isNot(MIToken::kw_cfi_type) &&
1074d8e91e46SDimitry Andric Token.isNot(MIToken::kw_debug_location) &&
1075b60736ecSDimitry Andric Token.isNot(MIToken::kw_debug_instr_number) &&
1076dd58ef01SDimitry Andric Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
1077ee8648bdSDimitry Andric auto Loc = Token.location();
1078e3b55780SDimitry Andric std::optional<unsigned> TiedDefIdx;
1079706b4fc4SDimitry Andric if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx))
10801a82d4c0SDimitry Andric return true;
1081dd58ef01SDimitry Andric Operands.push_back(
1082dd58ef01SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
1083dd58ef01SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
1084dd58ef01SDimitry Andric Token.is(MIToken::lbrace))
10851a82d4c0SDimitry Andric break;
10861a82d4c0SDimitry Andric if (Token.isNot(MIToken::comma))
10871a82d4c0SDimitry Andric return error("expected ',' before the next machine operand");
10881a82d4c0SDimitry Andric lex();
10891a82d4c0SDimitry Andric }
10901a82d4c0SDimitry Andric
1091d8e91e46SDimitry Andric MCSymbol *PreInstrSymbol = nullptr;
1092d8e91e46SDimitry Andric if (Token.is(MIToken::kw_pre_instr_symbol))
1093d8e91e46SDimitry Andric if (parsePreOrPostInstrSymbol(PreInstrSymbol))
1094d8e91e46SDimitry Andric return true;
1095d8e91e46SDimitry Andric MCSymbol *PostInstrSymbol = nullptr;
1096d8e91e46SDimitry Andric if (Token.is(MIToken::kw_post_instr_symbol))
1097d8e91e46SDimitry Andric if (parsePreOrPostInstrSymbol(PostInstrSymbol))
1098d8e91e46SDimitry Andric return true;
1099706b4fc4SDimitry Andric MDNode *HeapAllocMarker = nullptr;
1100706b4fc4SDimitry Andric if (Token.is(MIToken::kw_heap_alloc_marker))
1101706b4fc4SDimitry Andric if (parseHeapAllocMarker(HeapAllocMarker))
1102706b4fc4SDimitry Andric return true;
1103e3b55780SDimitry Andric MDNode *PCSections = nullptr;
1104e3b55780SDimitry Andric if (Token.is(MIToken::kw_pcsections))
1105e3b55780SDimitry Andric if (parsePCSections(PCSections))
1106e3b55780SDimitry Andric return true;
1107e3b55780SDimitry Andric
1108e3b55780SDimitry Andric unsigned CFIType = 0;
1109e3b55780SDimitry Andric if (Token.is(MIToken::kw_cfi_type)) {
1110e3b55780SDimitry Andric lex();
1111e3b55780SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
1112e3b55780SDimitry Andric return error("expected an integer literal after 'cfi-type'");
1113e3b55780SDimitry Andric // getUnsigned is sufficient for 32-bit integers.
1114e3b55780SDimitry Andric if (getUnsigned(CFIType))
1115e3b55780SDimitry Andric return true;
1116e3b55780SDimitry Andric lex();
1117e3b55780SDimitry Andric // Lex past trailing comma if present.
1118e3b55780SDimitry Andric if (Token.is(MIToken::comma))
1119e3b55780SDimitry Andric lex();
1120e3b55780SDimitry Andric }
1121d8e91e46SDimitry Andric
1122b60736ecSDimitry Andric unsigned InstrNum = 0;
1123b60736ecSDimitry Andric if (Token.is(MIToken::kw_debug_instr_number)) {
1124b60736ecSDimitry Andric lex();
1125b60736ecSDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
1126b60736ecSDimitry Andric return error("expected an integer literal after 'debug-instr-number'");
1127b60736ecSDimitry Andric if (getUnsigned(InstrNum))
1128b60736ecSDimitry Andric return true;
1129b60736ecSDimitry Andric lex();
1130b60736ecSDimitry Andric // Lex past trailing comma if present.
1131b60736ecSDimitry Andric if (Token.is(MIToken::comma))
1132b60736ecSDimitry Andric lex();
1133b60736ecSDimitry Andric }
1134b60736ecSDimitry Andric
1135dd58ef01SDimitry Andric DebugLoc DebugLocation;
1136dd58ef01SDimitry Andric if (Token.is(MIToken::kw_debug_location)) {
1137dd58ef01SDimitry Andric lex();
1138dd58ef01SDimitry Andric MDNode *Node = nullptr;
1139d8e91e46SDimitry Andric if (Token.is(MIToken::exclaim)) {
1140dd58ef01SDimitry Andric if (parseMDNode(Node))
1141dd58ef01SDimitry Andric return true;
1142d8e91e46SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
1143d8e91e46SDimitry Andric if (parseDILocation(Node))
1144d8e91e46SDimitry Andric return true;
1145d8e91e46SDimitry Andric } else
1146d8e91e46SDimitry Andric return error("expected a metadata node after 'debug-location'");
1147d8e91e46SDimitry Andric if (!isa<DILocation>(Node))
1148d8e91e46SDimitry Andric return error("referenced metadata is not a DILocation");
1149dd58ef01SDimitry Andric DebugLocation = DebugLoc(Node);
1150dd58ef01SDimitry Andric }
1151dd58ef01SDimitry Andric
1152dd58ef01SDimitry Andric // Parse the machine memory operands.
1153dd58ef01SDimitry Andric SmallVector<MachineMemOperand *, 2> MemOperands;
1154dd58ef01SDimitry Andric if (Token.is(MIToken::coloncolon)) {
1155dd58ef01SDimitry Andric lex();
1156dd58ef01SDimitry Andric while (!Token.isNewlineOrEOF()) {
1157dd58ef01SDimitry Andric MachineMemOperand *MemOp = nullptr;
1158dd58ef01SDimitry Andric if (parseMachineMemoryOperand(MemOp))
1159dd58ef01SDimitry Andric return true;
1160dd58ef01SDimitry Andric MemOperands.push_back(MemOp);
1161dd58ef01SDimitry Andric if (Token.isNewlineOrEOF())
1162dd58ef01SDimitry Andric break;
1163dd58ef01SDimitry Andric if (Token.isNot(MIToken::comma))
1164dd58ef01SDimitry Andric return error("expected ',' before the next machine memory operand");
1165dd58ef01SDimitry Andric lex();
1166dd58ef01SDimitry Andric }
1167dd58ef01SDimitry Andric }
1168dd58ef01SDimitry Andric
11691a82d4c0SDimitry Andric const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode);
11701a82d4c0SDimitry Andric if (!MCID.isVariadic()) {
1171ee8648bdSDimitry Andric // FIXME: Move the implicit operand verification to the machine verifier.
1172ee8648bdSDimitry Andric if (verifyImplicitOperands(Operands, MCID))
1173ee8648bdSDimitry Andric return true;
11741a82d4c0SDimitry Andric }
11751a82d4c0SDimitry Andric
1176dd58ef01SDimitry Andric MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
1177dd58ef01SDimitry Andric MI->setFlags(Flags);
1178145449b1SDimitry Andric
1179b1c73532SDimitry Andric // Don't check the operands make sense, let the verifier catch any
1180b1c73532SDimitry Andric // improprieties.
1181b1c73532SDimitry Andric for (const auto &Operand : Operands)
1182ee8648bdSDimitry Andric MI->addOperand(MF, Operand.Operand);
1183145449b1SDimitry Andric
1184dd58ef01SDimitry Andric if (assignRegisterTies(*MI, Operands))
1185dd58ef01SDimitry Andric return true;
1186d8e91e46SDimitry Andric if (PreInstrSymbol)
1187d8e91e46SDimitry Andric MI->setPreInstrSymbol(MF, PreInstrSymbol);
1188d8e91e46SDimitry Andric if (PostInstrSymbol)
1189d8e91e46SDimitry Andric MI->setPostInstrSymbol(MF, PostInstrSymbol);
1190706b4fc4SDimitry Andric if (HeapAllocMarker)
1191706b4fc4SDimitry Andric MI->setHeapAllocMarker(MF, HeapAllocMarker);
1192e3b55780SDimitry Andric if (PCSections)
1193e3b55780SDimitry Andric MI->setPCSections(MF, PCSections);
1194e3b55780SDimitry Andric if (CFIType)
1195e3b55780SDimitry Andric MI->setCFIType(MF, CFIType);
1196d8e91e46SDimitry Andric if (!MemOperands.empty())
1197d8e91e46SDimitry Andric MI->setMemRefs(MF, MemOperands);
1198b60736ecSDimitry Andric if (InstrNum)
1199b60736ecSDimitry Andric MI->setDebugInstrNum(InstrNum);
12001a82d4c0SDimitry Andric return false;
12011a82d4c0SDimitry Andric }
12021a82d4c0SDimitry Andric
parseStandaloneMBB(MachineBasicBlock * & MBB)1203dd58ef01SDimitry Andric bool MIParser::parseStandaloneMBB(MachineBasicBlock *&MBB) {
12041a82d4c0SDimitry Andric lex();
12051a82d4c0SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock))
12061a82d4c0SDimitry Andric return error("expected a machine basic block reference");
12071a82d4c0SDimitry Andric if (parseMBBReference(MBB))
12081a82d4c0SDimitry Andric return true;
12091a82d4c0SDimitry Andric lex();
12101a82d4c0SDimitry Andric if (Token.isNot(MIToken::Eof))
12111a82d4c0SDimitry Andric return error(
12121a82d4c0SDimitry Andric "expected end of string after the machine basic block reference");
12131a82d4c0SDimitry Andric return false;
12141a82d4c0SDimitry Andric }
12151a82d4c0SDimitry Andric
parseStandaloneNamedRegister(Register & Reg)1216cfca06d7SDimitry Andric bool MIParser::parseStandaloneNamedRegister(Register &Reg) {
1217ee8648bdSDimitry Andric lex();
1218ee8648bdSDimitry Andric if (Token.isNot(MIToken::NamedRegister))
1219ee8648bdSDimitry Andric return error("expected a named register");
1220b915e9e0SDimitry Andric if (parseNamedRegister(Reg))
1221dd58ef01SDimitry Andric return true;
1222ee8648bdSDimitry Andric lex();
1223ee8648bdSDimitry Andric if (Token.isNot(MIToken::Eof))
1224ee8648bdSDimitry Andric return error("expected end of string after the register reference");
1225ee8648bdSDimitry Andric return false;
1226ee8648bdSDimitry Andric }
1227ee8648bdSDimitry Andric
parseStandaloneVirtualRegister(VRegInfo * & Info)1228b915e9e0SDimitry Andric bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) {
1229dd58ef01SDimitry Andric lex();
1230dd58ef01SDimitry Andric if (Token.isNot(MIToken::VirtualRegister))
1231dd58ef01SDimitry Andric return error("expected a virtual register");
1232b915e9e0SDimitry Andric if (parseVirtualRegister(Info))
1233dd58ef01SDimitry Andric return true;
1234dd58ef01SDimitry Andric lex();
1235dd58ef01SDimitry Andric if (Token.isNot(MIToken::Eof))
1236dd58ef01SDimitry Andric return error("expected end of string after the register reference");
1237dd58ef01SDimitry Andric return false;
1238dd58ef01SDimitry Andric }
1239dd58ef01SDimitry Andric
parseStandaloneRegister(Register & Reg)1240cfca06d7SDimitry Andric bool MIParser::parseStandaloneRegister(Register &Reg) {
1241b915e9e0SDimitry Andric lex();
1242b915e9e0SDimitry Andric if (Token.isNot(MIToken::NamedRegister) &&
1243b915e9e0SDimitry Andric Token.isNot(MIToken::VirtualRegister))
1244b915e9e0SDimitry Andric return error("expected either a named or virtual register");
1245b915e9e0SDimitry Andric
1246b915e9e0SDimitry Andric VRegInfo *Info;
1247b915e9e0SDimitry Andric if (parseRegister(Reg, Info))
1248b915e9e0SDimitry Andric return true;
1249b915e9e0SDimitry Andric
1250b915e9e0SDimitry Andric lex();
1251b915e9e0SDimitry Andric if (Token.isNot(MIToken::Eof))
1252b915e9e0SDimitry Andric return error("expected end of string after the register reference");
1253b915e9e0SDimitry Andric return false;
1254b915e9e0SDimitry Andric }
1255b915e9e0SDimitry Andric
parseStandaloneStackObject(int & FI)1256dd58ef01SDimitry Andric bool MIParser::parseStandaloneStackObject(int &FI) {
1257dd58ef01SDimitry Andric lex();
1258dd58ef01SDimitry Andric if (Token.isNot(MIToken::StackObject))
1259dd58ef01SDimitry Andric return error("expected a stack object");
1260dd58ef01SDimitry Andric if (parseStackFrameIndex(FI))
1261dd58ef01SDimitry Andric return true;
1262dd58ef01SDimitry Andric if (Token.isNot(MIToken::Eof))
1263dd58ef01SDimitry Andric return error("expected end of string after the stack object reference");
1264dd58ef01SDimitry Andric return false;
1265dd58ef01SDimitry Andric }
1266dd58ef01SDimitry Andric
parseStandaloneMDNode(MDNode * & Node)1267dd58ef01SDimitry Andric bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
1268dd58ef01SDimitry Andric lex();
1269044eb2f6SDimitry Andric if (Token.is(MIToken::exclaim)) {
1270dd58ef01SDimitry Andric if (parseMDNode(Node))
1271dd58ef01SDimitry Andric return true;
1272044eb2f6SDimitry Andric } else if (Token.is(MIToken::md_diexpr)) {
1273044eb2f6SDimitry Andric if (parseDIExpression(Node))
1274044eb2f6SDimitry Andric return true;
1275d8e91e46SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
1276d8e91e46SDimitry Andric if (parseDILocation(Node))
1277d8e91e46SDimitry Andric return true;
1278044eb2f6SDimitry Andric } else
1279044eb2f6SDimitry Andric return error("expected a metadata node");
1280dd58ef01SDimitry Andric if (Token.isNot(MIToken::Eof))
1281dd58ef01SDimitry Andric return error("expected end of string after the metadata node");
1282dd58ef01SDimitry Andric return false;
1283dd58ef01SDimitry Andric }
1284dd58ef01SDimitry Andric
parseMachineMetadata()1285344a3780SDimitry Andric bool MIParser::parseMachineMetadata() {
1286344a3780SDimitry Andric lex();
1287344a3780SDimitry Andric if (Token.isNot(MIToken::exclaim))
1288344a3780SDimitry Andric return error("expected a metadata node");
1289344a3780SDimitry Andric
1290344a3780SDimitry Andric lex();
1291344a3780SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1292344a3780SDimitry Andric return error("expected metadata id after '!'");
1293344a3780SDimitry Andric unsigned ID = 0;
1294344a3780SDimitry Andric if (getUnsigned(ID))
1295344a3780SDimitry Andric return true;
1296344a3780SDimitry Andric lex();
1297344a3780SDimitry Andric if (expectAndConsume(MIToken::equal))
1298344a3780SDimitry Andric return true;
1299344a3780SDimitry Andric bool IsDistinct = Token.is(MIToken::kw_distinct);
1300344a3780SDimitry Andric if (IsDistinct)
1301344a3780SDimitry Andric lex();
1302344a3780SDimitry Andric if (Token.isNot(MIToken::exclaim))
1303344a3780SDimitry Andric return error("expected a metadata node");
1304344a3780SDimitry Andric lex();
1305344a3780SDimitry Andric
1306344a3780SDimitry Andric MDNode *MD;
1307344a3780SDimitry Andric if (parseMDTuple(MD, IsDistinct))
1308344a3780SDimitry Andric return true;
1309344a3780SDimitry Andric
1310344a3780SDimitry Andric auto FI = PFS.MachineForwardRefMDNodes.find(ID);
1311344a3780SDimitry Andric if (FI != PFS.MachineForwardRefMDNodes.end()) {
1312344a3780SDimitry Andric FI->second.first->replaceAllUsesWith(MD);
1313344a3780SDimitry Andric PFS.MachineForwardRefMDNodes.erase(FI);
1314344a3780SDimitry Andric
1315344a3780SDimitry Andric assert(PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work");
1316344a3780SDimitry Andric } else {
1317344a3780SDimitry Andric if (PFS.MachineMetadataNodes.count(ID))
1318344a3780SDimitry Andric return error("Metadata id is already used");
1319344a3780SDimitry Andric PFS.MachineMetadataNodes[ID].reset(MD);
1320344a3780SDimitry Andric }
1321344a3780SDimitry Andric
1322344a3780SDimitry Andric return false;
1323344a3780SDimitry Andric }
1324344a3780SDimitry Andric
parseMDTuple(MDNode * & MD,bool IsDistinct)1325344a3780SDimitry Andric bool MIParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
1326344a3780SDimitry Andric SmallVector<Metadata *, 16> Elts;
1327344a3780SDimitry Andric if (parseMDNodeVector(Elts))
1328344a3780SDimitry Andric return true;
1329344a3780SDimitry Andric MD = (IsDistinct ? MDTuple::getDistinct
1330344a3780SDimitry Andric : MDTuple::get)(MF.getFunction().getContext(), Elts);
1331344a3780SDimitry Andric return false;
1332344a3780SDimitry Andric }
1333344a3780SDimitry Andric
parseMDNodeVector(SmallVectorImpl<Metadata * > & Elts)1334344a3780SDimitry Andric bool MIParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
1335344a3780SDimitry Andric if (Token.isNot(MIToken::lbrace))
1336344a3780SDimitry Andric return error("expected '{' here");
1337344a3780SDimitry Andric lex();
1338344a3780SDimitry Andric
1339344a3780SDimitry Andric if (Token.is(MIToken::rbrace)) {
1340344a3780SDimitry Andric lex();
1341344a3780SDimitry Andric return false;
1342344a3780SDimitry Andric }
1343344a3780SDimitry Andric
1344344a3780SDimitry Andric do {
1345344a3780SDimitry Andric Metadata *MD;
1346344a3780SDimitry Andric if (parseMetadata(MD))
1347344a3780SDimitry Andric return true;
1348344a3780SDimitry Andric
1349344a3780SDimitry Andric Elts.push_back(MD);
1350344a3780SDimitry Andric
1351344a3780SDimitry Andric if (Token.isNot(MIToken::comma))
1352344a3780SDimitry Andric break;
1353344a3780SDimitry Andric lex();
1354344a3780SDimitry Andric } while (true);
1355344a3780SDimitry Andric
1356344a3780SDimitry Andric if (Token.isNot(MIToken::rbrace))
1357344a3780SDimitry Andric return error("expected end of metadata node");
1358344a3780SDimitry Andric lex();
1359344a3780SDimitry Andric
1360344a3780SDimitry Andric return false;
1361344a3780SDimitry Andric }
1362344a3780SDimitry Andric
1363344a3780SDimitry Andric // ::= !42
1364344a3780SDimitry Andric // ::= !"string"
parseMetadata(Metadata * & MD)1365344a3780SDimitry Andric bool MIParser::parseMetadata(Metadata *&MD) {
1366344a3780SDimitry Andric if (Token.isNot(MIToken::exclaim))
1367344a3780SDimitry Andric return error("expected '!' here");
1368344a3780SDimitry Andric lex();
1369344a3780SDimitry Andric
1370344a3780SDimitry Andric if (Token.is(MIToken::StringConstant)) {
1371344a3780SDimitry Andric std::string Str;
1372344a3780SDimitry Andric if (parseStringConstant(Str))
1373344a3780SDimitry Andric return true;
1374344a3780SDimitry Andric MD = MDString::get(MF.getFunction().getContext(), Str);
1375344a3780SDimitry Andric return false;
1376344a3780SDimitry Andric }
1377344a3780SDimitry Andric
1378344a3780SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1379344a3780SDimitry Andric return error("expected metadata id after '!'");
1380344a3780SDimitry Andric
1381344a3780SDimitry Andric SMLoc Loc = mapSMLoc(Token.location());
1382344a3780SDimitry Andric
1383344a3780SDimitry Andric unsigned ID = 0;
1384344a3780SDimitry Andric if (getUnsigned(ID))
1385344a3780SDimitry Andric return true;
1386344a3780SDimitry Andric lex();
1387344a3780SDimitry Andric
1388344a3780SDimitry Andric auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
1389344a3780SDimitry Andric if (NodeInfo != PFS.IRSlots.MetadataNodes.end()) {
1390344a3780SDimitry Andric MD = NodeInfo->second.get();
1391344a3780SDimitry Andric return false;
1392344a3780SDimitry Andric }
1393344a3780SDimitry Andric // Check machine metadata.
1394344a3780SDimitry Andric NodeInfo = PFS.MachineMetadataNodes.find(ID);
1395344a3780SDimitry Andric if (NodeInfo != PFS.MachineMetadataNodes.end()) {
1396344a3780SDimitry Andric MD = NodeInfo->second.get();
1397344a3780SDimitry Andric return false;
1398344a3780SDimitry Andric }
1399344a3780SDimitry Andric // Forward reference.
1400344a3780SDimitry Andric auto &FwdRef = PFS.MachineForwardRefMDNodes[ID];
1401344a3780SDimitry Andric FwdRef = std::make_pair(
1402e3b55780SDimitry Andric MDTuple::getTemporary(MF.getFunction().getContext(), std::nullopt), Loc);
1403344a3780SDimitry Andric PFS.MachineMetadataNodes[ID].reset(FwdRef.first.get());
1404344a3780SDimitry Andric MD = FwdRef.first.get();
1405344a3780SDimitry Andric
1406344a3780SDimitry Andric return false;
1407344a3780SDimitry Andric }
1408344a3780SDimitry Andric
printImplicitRegisterFlag(const MachineOperand & MO)1409ee8648bdSDimitry Andric static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
1410ee8648bdSDimitry Andric assert(MO.isImplicit());
1411ee8648bdSDimitry Andric return MO.isDef() ? "implicit-def" : "implicit";
1412ee8648bdSDimitry Andric }
1413ee8648bdSDimitry Andric
getRegisterName(const TargetRegisterInfo * TRI,Register Reg)1414ee8648bdSDimitry Andric static std::string getRegisterName(const TargetRegisterInfo *TRI,
1415cfca06d7SDimitry Andric Register Reg) {
1416e3b55780SDimitry Andric assert(Reg.isPhysical() && "expected phys reg");
1417ee8648bdSDimitry Andric return StringRef(TRI->getName(Reg)).lower();
1418ee8648bdSDimitry Andric }
1419ee8648bdSDimitry Andric
1420dd58ef01SDimitry Andric /// Return true if the parsed machine operands contain a given machine operand.
isImplicitOperandIn(const MachineOperand & ImplicitOperand,ArrayRef<ParsedMachineOperand> Operands)1421dd58ef01SDimitry Andric static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand,
1422dd58ef01SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) {
1423dd58ef01SDimitry Andric for (const auto &I : Operands) {
1424dd58ef01SDimitry Andric if (ImplicitOperand.isIdenticalTo(I.Operand))
1425dd58ef01SDimitry Andric return true;
1426dd58ef01SDimitry Andric }
1427dd58ef01SDimitry Andric return false;
1428dd58ef01SDimitry Andric }
1429dd58ef01SDimitry Andric
verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,const MCInstrDesc & MCID)1430dd58ef01SDimitry Andric bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
1431dd58ef01SDimitry Andric const MCInstrDesc &MCID) {
1432ee8648bdSDimitry Andric if (MCID.isCall())
1433ee8648bdSDimitry Andric // We can't verify call instructions as they can contain arbitrary implicit
1434ee8648bdSDimitry Andric // register and register mask operands.
1435ee8648bdSDimitry Andric return false;
1436ee8648bdSDimitry Andric
1437ee8648bdSDimitry Andric // Gather all the expected implicit operands.
1438ee8648bdSDimitry Andric SmallVector<MachineOperand, 4> ImplicitOperands;
1439e3b55780SDimitry Andric for (MCPhysReg ImpDef : MCID.implicit_defs())
1440e3b55780SDimitry Andric ImplicitOperands.push_back(MachineOperand::CreateReg(ImpDef, true, true));
1441e3b55780SDimitry Andric for (MCPhysReg ImpUse : MCID.implicit_uses())
1442e3b55780SDimitry Andric ImplicitOperands.push_back(MachineOperand::CreateReg(ImpUse, false, true));
1443ee8648bdSDimitry Andric
1444ee8648bdSDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
1445ee8648bdSDimitry Andric assert(TRI && "Expected target register info");
1446dd58ef01SDimitry Andric for (const auto &I : ImplicitOperands) {
1447dd58ef01SDimitry Andric if (isImplicitOperandIn(I, Operands))
1448ee8648bdSDimitry Andric continue;
1449dd58ef01SDimitry Andric return error(Operands.empty() ? Token.location() : Operands.back().End,
1450ee8648bdSDimitry Andric Twine("missing implicit register operand '") +
1451eb11fae6SDimitry Andric printImplicitRegisterFlag(I) + " $" +
1452dd58ef01SDimitry Andric getRegisterName(TRI, I.getReg()) + "'");
1453ee8648bdSDimitry Andric }
1454ee8648bdSDimitry Andric return false;
1455ee8648bdSDimitry Andric }
1456ee8648bdSDimitry Andric
parseInstruction(unsigned & OpCode,unsigned & Flags)1457dd58ef01SDimitry Andric bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
1458eb11fae6SDimitry Andric // Allow frame and fast math flags for OPCODE
1459b1c73532SDimitry Andric // clang-format off
1460eb11fae6SDimitry Andric while (Token.is(MIToken::kw_frame_setup) ||
1461eb11fae6SDimitry Andric Token.is(MIToken::kw_frame_destroy) ||
1462eb11fae6SDimitry Andric Token.is(MIToken::kw_nnan) ||
1463eb11fae6SDimitry Andric Token.is(MIToken::kw_ninf) ||
1464eb11fae6SDimitry Andric Token.is(MIToken::kw_nsz) ||
1465eb11fae6SDimitry Andric Token.is(MIToken::kw_arcp) ||
1466eb11fae6SDimitry Andric Token.is(MIToken::kw_contract) ||
1467eb11fae6SDimitry Andric Token.is(MIToken::kw_afn) ||
1468d8e91e46SDimitry Andric Token.is(MIToken::kw_reassoc) ||
1469d8e91e46SDimitry Andric Token.is(MIToken::kw_nuw) ||
1470d8e91e46SDimitry Andric Token.is(MIToken::kw_nsw) ||
1471e6d15924SDimitry Andric Token.is(MIToken::kw_exact) ||
14727fa27ce4SDimitry Andric Token.is(MIToken::kw_nofpexcept) ||
1473b1c73532SDimitry Andric Token.is(MIToken::kw_noconvergent) ||
1474ac9a064cSDimitry Andric Token.is(MIToken::kw_unpredictable) ||
1475ac9a064cSDimitry Andric Token.is(MIToken::kw_nneg) ||
1476ac9a064cSDimitry Andric Token.is(MIToken::kw_disjoint)) {
1477b1c73532SDimitry Andric // clang-format on
1478eb11fae6SDimitry Andric // Mine frame and fast math flags
1479eb11fae6SDimitry Andric if (Token.is(MIToken::kw_frame_setup))
1480dd58ef01SDimitry Andric Flags |= MachineInstr::FrameSetup;
1481eb11fae6SDimitry Andric if (Token.is(MIToken::kw_frame_destroy))
1482eb11fae6SDimitry Andric Flags |= MachineInstr::FrameDestroy;
1483eb11fae6SDimitry Andric if (Token.is(MIToken::kw_nnan))
1484eb11fae6SDimitry Andric Flags |= MachineInstr::FmNoNans;
1485eb11fae6SDimitry Andric if (Token.is(MIToken::kw_ninf))
1486eb11fae6SDimitry Andric Flags |= MachineInstr::FmNoInfs;
1487eb11fae6SDimitry Andric if (Token.is(MIToken::kw_nsz))
1488eb11fae6SDimitry Andric Flags |= MachineInstr::FmNsz;
1489eb11fae6SDimitry Andric if (Token.is(MIToken::kw_arcp))
1490eb11fae6SDimitry Andric Flags |= MachineInstr::FmArcp;
1491eb11fae6SDimitry Andric if (Token.is(MIToken::kw_contract))
1492eb11fae6SDimitry Andric Flags |= MachineInstr::FmContract;
1493eb11fae6SDimitry Andric if (Token.is(MIToken::kw_afn))
1494eb11fae6SDimitry Andric Flags |= MachineInstr::FmAfn;
1495eb11fae6SDimitry Andric if (Token.is(MIToken::kw_reassoc))
1496eb11fae6SDimitry Andric Flags |= MachineInstr::FmReassoc;
1497d8e91e46SDimitry Andric if (Token.is(MIToken::kw_nuw))
1498d8e91e46SDimitry Andric Flags |= MachineInstr::NoUWrap;
1499d8e91e46SDimitry Andric if (Token.is(MIToken::kw_nsw))
1500d8e91e46SDimitry Andric Flags |= MachineInstr::NoSWrap;
1501d8e91e46SDimitry Andric if (Token.is(MIToken::kw_exact))
1502d8e91e46SDimitry Andric Flags |= MachineInstr::IsExact;
1503706b4fc4SDimitry Andric if (Token.is(MIToken::kw_nofpexcept))
1504706b4fc4SDimitry Andric Flags |= MachineInstr::NoFPExcept;
15057fa27ce4SDimitry Andric if (Token.is(MIToken::kw_unpredictable))
15067fa27ce4SDimitry Andric Flags |= MachineInstr::Unpredictable;
1507b1c73532SDimitry Andric if (Token.is(MIToken::kw_noconvergent))
1508b1c73532SDimitry Andric Flags |= MachineInstr::NoConvergent;
1509ac9a064cSDimitry Andric if (Token.is(MIToken::kw_nneg))
1510ac9a064cSDimitry Andric Flags |= MachineInstr::NonNeg;
1511ac9a064cSDimitry Andric if (Token.is(MIToken::kw_disjoint))
1512ac9a064cSDimitry Andric Flags |= MachineInstr::Disjoint;
1513eb11fae6SDimitry Andric
1514dd58ef01SDimitry Andric lex();
1515dd58ef01SDimitry Andric }
15161a82d4c0SDimitry Andric if (Token.isNot(MIToken::Identifier))
15171a82d4c0SDimitry Andric return error("expected a machine instruction");
15181a82d4c0SDimitry Andric StringRef InstrName = Token.stringValue();
1519e6d15924SDimitry Andric if (PFS.Target.parseInstrName(InstrName, OpCode))
15201a82d4c0SDimitry Andric return error(Twine("unknown machine instruction name '") + InstrName + "'");
15211a82d4c0SDimitry Andric lex();
15221a82d4c0SDimitry Andric return false;
15231a82d4c0SDimitry Andric }
15241a82d4c0SDimitry Andric
parseNamedRegister(Register & Reg)1525cfca06d7SDimitry Andric bool MIParser::parseNamedRegister(Register &Reg) {
1526b915e9e0SDimitry Andric assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token");
15271a82d4c0SDimitry Andric StringRef Name = Token.stringValue();
1528e6d15924SDimitry Andric if (PFS.Target.getRegisterByName(Name, Reg))
15291a82d4c0SDimitry Andric return error(Twine("unknown register name '") + Name + "'");
1530b915e9e0SDimitry Andric return false;
15311a82d4c0SDimitry Andric }
1532b915e9e0SDimitry Andric
parseNamedVirtualRegister(VRegInfo * & Info)1533eb11fae6SDimitry Andric bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) {
1534eb11fae6SDimitry Andric assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token");
1535eb11fae6SDimitry Andric StringRef Name = Token.stringValue();
1536eb11fae6SDimitry Andric // TODO: Check that the VReg name is not the same as a physical register name.
1537eb11fae6SDimitry Andric // If it is, then print a warning (when warnings are implemented).
1538eb11fae6SDimitry Andric Info = &PFS.getVRegInfoNamed(Name);
1539eb11fae6SDimitry Andric return false;
1540eb11fae6SDimitry Andric }
1541eb11fae6SDimitry Andric
parseVirtualRegister(VRegInfo * & Info)1542b915e9e0SDimitry Andric bool MIParser::parseVirtualRegister(VRegInfo *&Info) {
1543eb11fae6SDimitry Andric if (Token.is(MIToken::NamedVirtualRegister))
1544eb11fae6SDimitry Andric return parseNamedVirtualRegister(Info);
1545b915e9e0SDimitry Andric assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token");
1546ee8648bdSDimitry Andric unsigned ID;
1547ee8648bdSDimitry Andric if (getUnsigned(ID))
1548ee8648bdSDimitry Andric return true;
1549b915e9e0SDimitry Andric Info = &PFS.getVRegInfo(ID);
1550b915e9e0SDimitry Andric return false;
1551ee8648bdSDimitry Andric }
1552b915e9e0SDimitry Andric
parseRegister(Register & Reg,VRegInfo * & Info)1553cfca06d7SDimitry Andric bool MIParser::parseRegister(Register &Reg, VRegInfo *&Info) {
1554b915e9e0SDimitry Andric switch (Token.kind()) {
1555b915e9e0SDimitry Andric case MIToken::underscore:
1556b915e9e0SDimitry Andric Reg = 0;
1557b915e9e0SDimitry Andric return false;
1558b915e9e0SDimitry Andric case MIToken::NamedRegister:
1559b915e9e0SDimitry Andric return parseNamedRegister(Reg);
1560eb11fae6SDimitry Andric case MIToken::NamedVirtualRegister:
1561b915e9e0SDimitry Andric case MIToken::VirtualRegister:
1562b915e9e0SDimitry Andric if (parseVirtualRegister(Info))
1563b915e9e0SDimitry Andric return true;
1564b915e9e0SDimitry Andric Reg = Info->VReg;
1565b915e9e0SDimitry Andric return false;
15661a82d4c0SDimitry Andric // TODO: Parse other register kinds.
15671a82d4c0SDimitry Andric default:
15681a82d4c0SDimitry Andric llvm_unreachable("The current token should be a register");
15691a82d4c0SDimitry Andric }
15701a82d4c0SDimitry Andric }
15711a82d4c0SDimitry Andric
parseRegisterClassOrBank(VRegInfo & RegInfo)157271d5a254SDimitry Andric bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
157371d5a254SDimitry Andric if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore))
157471d5a254SDimitry Andric return error("expected '_', register class, or register bank name");
157571d5a254SDimitry Andric StringRef::iterator Loc = Token.location();
157671d5a254SDimitry Andric StringRef Name = Token.stringValue();
157771d5a254SDimitry Andric
157871d5a254SDimitry Andric // Was it a register class?
1579e6d15924SDimitry Andric const TargetRegisterClass *RC = PFS.Target.getRegClass(Name);
1580e6d15924SDimitry Andric if (RC) {
158171d5a254SDimitry Andric lex();
158271d5a254SDimitry Andric
158371d5a254SDimitry Andric switch (RegInfo.Kind) {
158471d5a254SDimitry Andric case VRegInfo::UNKNOWN:
158571d5a254SDimitry Andric case VRegInfo::NORMAL:
158671d5a254SDimitry Andric RegInfo.Kind = VRegInfo::NORMAL;
1587e6d15924SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RC != RC) {
158871d5a254SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
158971d5a254SDimitry Andric return error(Loc, Twine("conflicting register classes, previously: ") +
159071d5a254SDimitry Andric Twine(TRI.getRegClassName(RegInfo.D.RC)));
159171d5a254SDimitry Andric }
1592e6d15924SDimitry Andric RegInfo.D.RC = RC;
159371d5a254SDimitry Andric RegInfo.Explicit = true;
159471d5a254SDimitry Andric return false;
159571d5a254SDimitry Andric
159671d5a254SDimitry Andric case VRegInfo::GENERIC:
159771d5a254SDimitry Andric case VRegInfo::REGBANK:
159871d5a254SDimitry Andric return error(Loc, "register class specification on generic register");
159971d5a254SDimitry Andric }
160071d5a254SDimitry Andric llvm_unreachable("Unexpected register kind");
160171d5a254SDimitry Andric }
160271d5a254SDimitry Andric
160371d5a254SDimitry Andric // Should be a register bank or a generic register.
160471d5a254SDimitry Andric const RegisterBank *RegBank = nullptr;
160571d5a254SDimitry Andric if (Name != "_") {
1606e6d15924SDimitry Andric RegBank = PFS.Target.getRegBank(Name);
1607e6d15924SDimitry Andric if (!RegBank)
160871d5a254SDimitry Andric return error(Loc, "expected '_', register class, or register bank name");
160971d5a254SDimitry Andric }
161071d5a254SDimitry Andric
161171d5a254SDimitry Andric lex();
161271d5a254SDimitry Andric
161371d5a254SDimitry Andric switch (RegInfo.Kind) {
161471d5a254SDimitry Andric case VRegInfo::UNKNOWN:
161571d5a254SDimitry Andric case VRegInfo::GENERIC:
161671d5a254SDimitry Andric case VRegInfo::REGBANK:
161771d5a254SDimitry Andric RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC;
161871d5a254SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank)
161971d5a254SDimitry Andric return error(Loc, "conflicting generic register banks");
162071d5a254SDimitry Andric RegInfo.D.RegBank = RegBank;
162171d5a254SDimitry Andric RegInfo.Explicit = true;
162271d5a254SDimitry Andric return false;
162371d5a254SDimitry Andric
162471d5a254SDimitry Andric case VRegInfo::NORMAL:
162571d5a254SDimitry Andric return error(Loc, "register bank specification on normal register");
162671d5a254SDimitry Andric }
162771d5a254SDimitry Andric llvm_unreachable("Unexpected register kind");
162871d5a254SDimitry Andric }
162971d5a254SDimitry Andric
parseRegisterFlag(unsigned & Flags)1630ee8648bdSDimitry Andric bool MIParser::parseRegisterFlag(unsigned &Flags) {
1631dd58ef01SDimitry Andric const unsigned OldFlags = Flags;
1632ee8648bdSDimitry Andric switch (Token.kind()) {
1633ee8648bdSDimitry Andric case MIToken::kw_implicit:
1634ee8648bdSDimitry Andric Flags |= RegState::Implicit;
1635ee8648bdSDimitry Andric break;
1636ee8648bdSDimitry Andric case MIToken::kw_implicit_define:
1637ee8648bdSDimitry Andric Flags |= RegState::ImplicitDefine;
1638ee8648bdSDimitry Andric break;
1639dd58ef01SDimitry Andric case MIToken::kw_def:
1640dd58ef01SDimitry Andric Flags |= RegState::Define;
1641dd58ef01SDimitry Andric break;
1642ee8648bdSDimitry Andric case MIToken::kw_dead:
1643ee8648bdSDimitry Andric Flags |= RegState::Dead;
1644ee8648bdSDimitry Andric break;
1645ee8648bdSDimitry Andric case MIToken::kw_killed:
1646ee8648bdSDimitry Andric Flags |= RegState::Kill;
1647ee8648bdSDimitry Andric break;
1648ee8648bdSDimitry Andric case MIToken::kw_undef:
1649ee8648bdSDimitry Andric Flags |= RegState::Undef;
1650ee8648bdSDimitry Andric break;
1651dd58ef01SDimitry Andric case MIToken::kw_internal:
1652dd58ef01SDimitry Andric Flags |= RegState::InternalRead;
1653dd58ef01SDimitry Andric break;
1654dd58ef01SDimitry Andric case MIToken::kw_early_clobber:
1655dd58ef01SDimitry Andric Flags |= RegState::EarlyClobber;
1656dd58ef01SDimitry Andric break;
1657dd58ef01SDimitry Andric case MIToken::kw_debug_use:
1658dd58ef01SDimitry Andric Flags |= RegState::Debug;
1659dd58ef01SDimitry Andric break;
1660044eb2f6SDimitry Andric case MIToken::kw_renamable:
1661044eb2f6SDimitry Andric Flags |= RegState::Renamable;
1662044eb2f6SDimitry Andric break;
1663ee8648bdSDimitry Andric default:
1664ee8648bdSDimitry Andric llvm_unreachable("The current token should be a register flag");
1665ee8648bdSDimitry Andric }
1666dd58ef01SDimitry Andric if (OldFlags == Flags)
1667dd58ef01SDimitry Andric // We know that the same flag is specified more than once when the flags
1668dd58ef01SDimitry Andric // weren't modified.
1669dd58ef01SDimitry Andric return error("duplicate '" + Token.stringValue() + "' register flag");
1670ee8648bdSDimitry Andric lex();
1671ee8648bdSDimitry Andric return false;
1672ee8648bdSDimitry Andric }
1673ee8648bdSDimitry Andric
parseSubRegisterIndex(unsigned & SubReg)1674ee8648bdSDimitry Andric bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
1675b915e9e0SDimitry Andric assert(Token.is(MIToken::dot));
1676ee8648bdSDimitry Andric lex();
1677ee8648bdSDimitry Andric if (Token.isNot(MIToken::Identifier))
1678b915e9e0SDimitry Andric return error("expected a subregister index after '.'");
1679ee8648bdSDimitry Andric auto Name = Token.stringValue();
1680e6d15924SDimitry Andric SubReg = PFS.Target.getSubRegIndex(Name);
1681ee8648bdSDimitry Andric if (!SubReg)
1682ee8648bdSDimitry Andric return error(Twine("use of unknown subregister index '") + Name + "'");
1683ee8648bdSDimitry Andric lex();
1684ee8648bdSDimitry Andric return false;
1685ee8648bdSDimitry Andric }
1686ee8648bdSDimitry Andric
parseRegisterTiedDefIndex(unsigned & TiedDefIdx)1687dd58ef01SDimitry Andric bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
1688dd58ef01SDimitry Andric if (!consumeIfPresent(MIToken::kw_tied_def))
1689b915e9e0SDimitry Andric return true;
1690dd58ef01SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
1691dd58ef01SDimitry Andric return error("expected an integer literal after 'tied-def'");
1692dd58ef01SDimitry Andric if (getUnsigned(TiedDefIdx))
1693dd58ef01SDimitry Andric return true;
1694dd58ef01SDimitry Andric lex();
1695dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
1696dd58ef01SDimitry Andric return true;
1697dd58ef01SDimitry Andric return false;
1698dd58ef01SDimitry Andric }
1699dd58ef01SDimitry Andric
assignRegisterTies(MachineInstr & MI,ArrayRef<ParsedMachineOperand> Operands)1700dd58ef01SDimitry Andric bool MIParser::assignRegisterTies(MachineInstr &MI,
1701dd58ef01SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) {
1702dd58ef01SDimitry Andric SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs;
1703dd58ef01SDimitry Andric for (unsigned I = 0, E = Operands.size(); I != E; ++I) {
1704dd58ef01SDimitry Andric if (!Operands[I].TiedDefIdx)
1705dd58ef01SDimitry Andric continue;
1706dd58ef01SDimitry Andric // The parser ensures that this operand is a register use, so we just have
1707dd58ef01SDimitry Andric // to check the tied-def operand.
1708145449b1SDimitry Andric unsigned DefIdx = *Operands[I].TiedDefIdx;
1709dd58ef01SDimitry Andric if (DefIdx >= E)
1710dd58ef01SDimitry Andric return error(Operands[I].Begin,
1711dd58ef01SDimitry Andric Twine("use of invalid tied-def operand index '" +
1712dd58ef01SDimitry Andric Twine(DefIdx) + "'; instruction has only ") +
1713dd58ef01SDimitry Andric Twine(E) + " operands");
1714dd58ef01SDimitry Andric const auto &DefOperand = Operands[DefIdx].Operand;
1715dd58ef01SDimitry Andric if (!DefOperand.isReg() || !DefOperand.isDef())
1716dd58ef01SDimitry Andric // FIXME: add note with the def operand.
1717dd58ef01SDimitry Andric return error(Operands[I].Begin,
1718dd58ef01SDimitry Andric Twine("use of invalid tied-def operand index '") +
1719dd58ef01SDimitry Andric Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) +
1720dd58ef01SDimitry Andric " isn't a defined register");
1721dd58ef01SDimitry Andric // Check that the tied-def operand wasn't tied elsewhere.
1722dd58ef01SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs) {
1723dd58ef01SDimitry Andric if (TiedPair.first == DefIdx)
1724dd58ef01SDimitry Andric return error(Operands[I].Begin,
1725dd58ef01SDimitry Andric Twine("the tied-def operand #") + Twine(DefIdx) +
1726dd58ef01SDimitry Andric " is already tied with another register operand");
1727dd58ef01SDimitry Andric }
1728dd58ef01SDimitry Andric TiedRegisterPairs.push_back(std::make_pair(DefIdx, I));
1729dd58ef01SDimitry Andric }
1730dd58ef01SDimitry Andric // FIXME: Verify that for non INLINEASM instructions, the def and use tied
1731dd58ef01SDimitry Andric // indices must be less than tied max.
1732dd58ef01SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs)
1733dd58ef01SDimitry Andric MI.tieOperands(TiedPair.first, TiedPair.second);
1734dd58ef01SDimitry Andric return false;
1735dd58ef01SDimitry Andric }
1736dd58ef01SDimitry Andric
parseRegisterOperand(MachineOperand & Dest,std::optional<unsigned> & TiedDefIdx,bool IsDef)1737dd58ef01SDimitry Andric bool MIParser::parseRegisterOperand(MachineOperand &Dest,
1738e3b55780SDimitry Andric std::optional<unsigned> &TiedDefIdx,
1739dd58ef01SDimitry Andric bool IsDef) {
1740ee8648bdSDimitry Andric unsigned Flags = IsDef ? RegState::Define : 0;
1741ee8648bdSDimitry Andric while (Token.isRegisterFlag()) {
1742ee8648bdSDimitry Andric if (parseRegisterFlag(Flags))
1743ee8648bdSDimitry Andric return true;
1744ee8648bdSDimitry Andric }
1745ee8648bdSDimitry Andric if (!Token.isRegister())
1746ee8648bdSDimitry Andric return error("expected a register after register flags");
1747cfca06d7SDimitry Andric Register Reg;
1748b915e9e0SDimitry Andric VRegInfo *RegInfo;
1749b915e9e0SDimitry Andric if (parseRegister(Reg, RegInfo))
17501a82d4c0SDimitry Andric return true;
17511a82d4c0SDimitry Andric lex();
1752ee8648bdSDimitry Andric unsigned SubReg = 0;
1753b915e9e0SDimitry Andric if (Token.is(MIToken::dot)) {
1754ee8648bdSDimitry Andric if (parseSubRegisterIndex(SubReg))
1755ee8648bdSDimitry Andric return true;
1756e3b55780SDimitry Andric if (!Reg.isVirtual())
175701095a5dSDimitry Andric return error("subregister index expects a virtual register");
1758ee8648bdSDimitry Andric }
175971d5a254SDimitry Andric if (Token.is(MIToken::colon)) {
1760e3b55780SDimitry Andric if (!Reg.isVirtual())
176171d5a254SDimitry Andric return error("register class specification expects a virtual register");
176271d5a254SDimitry Andric lex();
176371d5a254SDimitry Andric if (parseRegisterClassOrBank(*RegInfo))
176471d5a254SDimitry Andric return true;
176571d5a254SDimitry Andric }
1766b915e9e0SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
176701095a5dSDimitry Andric if ((Flags & RegState::Define) == 0) {
176801095a5dSDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
1769dd58ef01SDimitry Andric unsigned Idx;
1770b915e9e0SDimitry Andric if (!parseRegisterTiedDefIndex(Idx))
1771dd58ef01SDimitry Andric TiedDefIdx = Idx;
1772b915e9e0SDimitry Andric else {
1773b915e9e0SDimitry Andric // Try a redundant low-level type.
1774b915e9e0SDimitry Andric LLT Ty;
1775b915e9e0SDimitry Andric if (parseLowLevelType(Token.location(), Ty))
1776b915e9e0SDimitry Andric return error("expected tied-def or low-level type after '('");
1777b915e9e0SDimitry Andric
1778b915e9e0SDimitry Andric if (expectAndConsume(MIToken::rparen))
177901095a5dSDimitry Andric return true;
178001095a5dSDimitry Andric
1781b915e9e0SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
1782b915e9e0SDimitry Andric return error("inconsistent type for generic virtual register");
1783b915e9e0SDimitry Andric
17841d5ae102SDimitry Andric MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
1785b915e9e0SDimitry Andric MRI.setType(Reg, Ty);
1786b915e9e0SDimitry Andric }
1787b915e9e0SDimitry Andric }
1788b915e9e0SDimitry Andric } else if (consumeIfPresent(MIToken::lparen)) {
1789b915e9e0SDimitry Andric // Virtual registers may have a tpe with GlobalISel.
1790e3b55780SDimitry Andric if (!Reg.isVirtual())
1791b915e9e0SDimitry Andric return error("unexpected type on physical register");
1792b915e9e0SDimitry Andric
1793b915e9e0SDimitry Andric LLT Ty;
1794b915e9e0SDimitry Andric if (parseLowLevelType(Token.location(), Ty))
1795b915e9e0SDimitry Andric return true;
1796b915e9e0SDimitry Andric
1797b915e9e0SDimitry Andric if (expectAndConsume(MIToken::rparen))
1798b915e9e0SDimitry Andric return true;
1799b915e9e0SDimitry Andric
1800b915e9e0SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
1801b915e9e0SDimitry Andric return error("inconsistent type for generic virtual register");
1802b915e9e0SDimitry Andric
18031d5ae102SDimitry Andric MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
1804b915e9e0SDimitry Andric MRI.setType(Reg, Ty);
1805e3b55780SDimitry Andric } else if (Reg.isVirtual()) {
1806b915e9e0SDimitry Andric // Generic virtual registers must have a type.
1807b915e9e0SDimitry Andric // If we end up here this means the type hasn't been specified and
180801095a5dSDimitry Andric // this is bad!
1809b915e9e0SDimitry Andric if (RegInfo->Kind == VRegInfo::GENERIC ||
1810b915e9e0SDimitry Andric RegInfo->Kind == VRegInfo::REGBANK)
1811b915e9e0SDimitry Andric return error("generic virtual registers must have a type");
181201095a5dSDimitry Andric }
1813145449b1SDimitry Andric
1814145449b1SDimitry Andric if (Flags & RegState::Define) {
1815145449b1SDimitry Andric if (Flags & RegState::Kill)
1816145449b1SDimitry Andric return error("cannot have a killed def operand");
1817145449b1SDimitry Andric } else {
1818145449b1SDimitry Andric if (Flags & RegState::Dead)
1819145449b1SDimitry Andric return error("cannot have a dead use operand");
1820145449b1SDimitry Andric }
1821145449b1SDimitry Andric
1822ee8648bdSDimitry Andric Dest = MachineOperand::CreateReg(
1823ee8648bdSDimitry Andric Reg, Flags & RegState::Define, Flags & RegState::Implicit,
1824ee8648bdSDimitry Andric Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef,
1825dd58ef01SDimitry Andric Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug,
1826044eb2f6SDimitry Andric Flags & RegState::InternalRead, Flags & RegState::Renamable);
1827044eb2f6SDimitry Andric
18281a82d4c0SDimitry Andric return false;
18291a82d4c0SDimitry Andric }
18301a82d4c0SDimitry Andric
parseImmediateOperand(MachineOperand & Dest)18311a82d4c0SDimitry Andric bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
18321a82d4c0SDimitry Andric assert(Token.is(MIToken::IntegerLiteral));
18331a82d4c0SDimitry Andric const APSInt &Int = Token.integerValue();
1834e3b55780SDimitry Andric if (auto SImm = Int.trySExtValue(); Int.isSigned() && SImm.has_value())
1835e3b55780SDimitry Andric Dest = MachineOperand::CreateImm(*SImm);
1836e3b55780SDimitry Andric else if (auto UImm = Int.tryZExtValue(); !Int.isSigned() && UImm.has_value())
1837e3b55780SDimitry Andric Dest = MachineOperand::CreateImm(*UImm);
1838e3b55780SDimitry Andric else
1839dd58ef01SDimitry Andric return error("integer literal is too large to be an immediate operand");
18401a82d4c0SDimitry Andric lex();
18411a82d4c0SDimitry Andric return false;
18421a82d4c0SDimitry Andric }
18431a82d4c0SDimitry Andric
parseTargetImmMnemonic(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,const MIRFormatter & MF)1844706b4fc4SDimitry Andric bool MIParser::parseTargetImmMnemonic(const unsigned OpCode,
1845706b4fc4SDimitry Andric const unsigned OpIdx,
1846706b4fc4SDimitry Andric MachineOperand &Dest,
1847706b4fc4SDimitry Andric const MIRFormatter &MF) {
1848706b4fc4SDimitry Andric assert(Token.is(MIToken::dot));
1849706b4fc4SDimitry Andric auto Loc = Token.location(); // record start position
1850706b4fc4SDimitry Andric size_t Len = 1; // for "."
1851706b4fc4SDimitry Andric lex();
1852706b4fc4SDimitry Andric
1853706b4fc4SDimitry Andric // Handle the case that mnemonic starts with number.
1854706b4fc4SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
1855706b4fc4SDimitry Andric Len += Token.range().size();
1856706b4fc4SDimitry Andric lex();
1857706b4fc4SDimitry Andric }
1858706b4fc4SDimitry Andric
1859706b4fc4SDimitry Andric StringRef Src;
1860706b4fc4SDimitry Andric if (Token.is(MIToken::comma))
1861706b4fc4SDimitry Andric Src = StringRef(Loc, Len);
1862706b4fc4SDimitry Andric else {
1863706b4fc4SDimitry Andric assert(Token.is(MIToken::Identifier));
1864706b4fc4SDimitry Andric Src = StringRef(Loc, Len + Token.stringValue().size());
1865706b4fc4SDimitry Andric }
1866706b4fc4SDimitry Andric int64_t Val;
1867706b4fc4SDimitry Andric if (MF.parseImmMnemonic(OpCode, OpIdx, Src, Val,
1868706b4fc4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg)
1869706b4fc4SDimitry Andric -> bool { return error(Loc, Msg); }))
1870706b4fc4SDimitry Andric return true;
1871706b4fc4SDimitry Andric
1872706b4fc4SDimitry Andric Dest = MachineOperand::CreateImm(Val);
1873706b4fc4SDimitry Andric if (!Token.is(MIToken::comma))
1874706b4fc4SDimitry Andric lex();
1875706b4fc4SDimitry Andric return false;
1876706b4fc4SDimitry Andric }
1877706b4fc4SDimitry Andric
parseIRConstant(StringRef::iterator Loc,StringRef StringValue,PerFunctionMIParsingState & PFS,const Constant * & C,ErrorCallbackType ErrCB)1878706b4fc4SDimitry Andric static bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1879706b4fc4SDimitry Andric PerFunctionMIParsingState &PFS, const Constant *&C,
1880706b4fc4SDimitry Andric ErrorCallbackType ErrCB) {
1881dd58ef01SDimitry Andric auto Source = StringValue.str(); // The source has to be null terminated.
1882dd58ef01SDimitry Andric SMDiagnostic Err;
1883706b4fc4SDimitry Andric C = parseConstantValue(Source, Err, *PFS.MF.getFunction().getParent(),
188401095a5dSDimitry Andric &PFS.IRSlots);
1885dd58ef01SDimitry Andric if (!C)
1886706b4fc4SDimitry Andric return ErrCB(Loc + Err.getColumnNo(), Err.getMessage());
1887dd58ef01SDimitry Andric return false;
1888dd58ef01SDimitry Andric }
1889dd58ef01SDimitry Andric
parseIRConstant(StringRef::iterator Loc,StringRef StringValue,const Constant * & C)1890706b4fc4SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1891706b4fc4SDimitry Andric const Constant *&C) {
1892706b4fc4SDimitry Andric return ::parseIRConstant(
1893706b4fc4SDimitry Andric Loc, StringValue, PFS, C,
1894706b4fc4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
1895706b4fc4SDimitry Andric return error(Loc, Msg);
1896706b4fc4SDimitry Andric });
1897706b4fc4SDimitry Andric }
1898706b4fc4SDimitry Andric
parseIRConstant(StringRef::iterator Loc,const Constant * & C)1899dd58ef01SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
1900dd58ef01SDimitry Andric if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C))
1901dd58ef01SDimitry Andric return true;
1902dd58ef01SDimitry Andric lex();
1903dd58ef01SDimitry Andric return false;
1904dd58ef01SDimitry Andric }
1905dd58ef01SDimitry Andric
1906e3b55780SDimitry Andric // See LLT implementation for bit size limits.
verifyScalarSize(uint64_t Size)1907e6d15924SDimitry Andric static bool verifyScalarSize(uint64_t Size) {
1908e6d15924SDimitry Andric return Size != 0 && isUInt<16>(Size);
1909e6d15924SDimitry Andric }
1910e6d15924SDimitry Andric
verifyVectorElementCount(uint64_t NumElts)1911e6d15924SDimitry Andric static bool verifyVectorElementCount(uint64_t NumElts) {
1912e6d15924SDimitry Andric return NumElts != 0 && isUInt<16>(NumElts);
1913e6d15924SDimitry Andric }
1914e6d15924SDimitry Andric
verifyAddrSpace(uint64_t AddrSpace)1915e6d15924SDimitry Andric static bool verifyAddrSpace(uint64_t AddrSpace) {
1916e6d15924SDimitry Andric return isUInt<24>(AddrSpace);
1917e6d15924SDimitry Andric }
1918e6d15924SDimitry Andric
parseLowLevelType(StringRef::iterator Loc,LLT & Ty)1919b915e9e0SDimitry Andric bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
1920eb11fae6SDimitry Andric if (Token.range().front() == 's' || Token.range().front() == 'p') {
1921eb11fae6SDimitry Andric StringRef SizeStr = Token.range().drop_front();
1922eb11fae6SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
1923eb11fae6SDimitry Andric return error("expected integers after 's'/'p' type character");
1924eb11fae6SDimitry Andric }
1925eb11fae6SDimitry Andric
1926eb11fae6SDimitry Andric if (Token.range().front() == 's') {
1927e6d15924SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
1928ac9a064cSDimitry Andric if (ScalarSize) {
1929e6d15924SDimitry Andric if (!verifyScalarSize(ScalarSize))
1930e6d15924SDimitry Andric return error("invalid size for scalar type");
1931e6d15924SDimitry Andric Ty = LLT::scalar(ScalarSize);
1932ac9a064cSDimitry Andric } else {
1933ac9a064cSDimitry Andric Ty = LLT::token();
1934ac9a064cSDimitry Andric }
1935b915e9e0SDimitry Andric lex();
1936b915e9e0SDimitry Andric return false;
1937eb11fae6SDimitry Andric } else if (Token.range().front() == 'p') {
1938044eb2f6SDimitry Andric const DataLayout &DL = MF.getDataLayout();
1939e6d15924SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
1940e6d15924SDimitry Andric if (!verifyAddrSpace(AS))
1941e6d15924SDimitry Andric return error("invalid address space number");
1942e6d15924SDimitry Andric
1943b915e9e0SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
1944b915e9e0SDimitry Andric lex();
194501095a5dSDimitry Andric return false;
194601095a5dSDimitry Andric }
194701095a5dSDimitry Andric
1948b915e9e0SDimitry Andric // Now we're looking for a vector.
1949b915e9e0SDimitry Andric if (Token.isNot(MIToken::less))
1950b1c73532SDimitry Andric return error(Loc, "expected sN, pA, <M x sN>, <M x pA>, <vscale x M x sN>, "
1951b1c73532SDimitry Andric "or <vscale x M x pA> for GlobalISel type");
1952b915e9e0SDimitry Andric lex();
1953b915e9e0SDimitry Andric
1954b1c73532SDimitry Andric bool HasVScale =
1955b1c73532SDimitry Andric Token.is(MIToken::Identifier) && Token.stringValue() == "vscale";
1956b1c73532SDimitry Andric if (HasVScale) {
1957b1c73532SDimitry Andric lex();
1958b1c73532SDimitry Andric if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
1959b1c73532SDimitry Andric return error("expected <vscale x M x sN> or <vscale x M x pA>");
1960b1c73532SDimitry Andric lex();
1961b1c73532SDimitry Andric }
1962b1c73532SDimitry Andric
1963b1c73532SDimitry Andric auto GetError = [this, &HasVScale, Loc]() {
1964b1c73532SDimitry Andric if (HasVScale)
1965b1c73532SDimitry Andric return error(
1966b1c73532SDimitry Andric Loc, "expected <vscale x M x sN> or <vscale M x pA> for vector type");
1967eb11fae6SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
1968b1c73532SDimitry Andric };
1969b1c73532SDimitry Andric
1970b1c73532SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
1971b1c73532SDimitry Andric return GetError();
1972b915e9e0SDimitry Andric uint64_t NumElements = Token.integerValue().getZExtValue();
1973e6d15924SDimitry Andric if (!verifyVectorElementCount(NumElements))
1974e6d15924SDimitry Andric return error("invalid number of vector elements");
1975e6d15924SDimitry Andric
1976b915e9e0SDimitry Andric lex();
1977b915e9e0SDimitry Andric
1978b915e9e0SDimitry Andric if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
1979b1c73532SDimitry Andric return GetError();
1980b915e9e0SDimitry Andric lex();
1981b915e9e0SDimitry Andric
1982eb11fae6SDimitry Andric if (Token.range().front() != 's' && Token.range().front() != 'p')
1983b1c73532SDimitry Andric return GetError();
1984b1c73532SDimitry Andric
1985eb11fae6SDimitry Andric StringRef SizeStr = Token.range().drop_front();
1986eb11fae6SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
1987eb11fae6SDimitry Andric return error("expected integers after 's'/'p' type character");
1988eb11fae6SDimitry Andric
1989e6d15924SDimitry Andric if (Token.range().front() == 's') {
1990e6d15924SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
1991e6d15924SDimitry Andric if (!verifyScalarSize(ScalarSize))
1992ac9a064cSDimitry Andric return error("invalid size for scalar element in vector");
1993e6d15924SDimitry Andric Ty = LLT::scalar(ScalarSize);
1994e6d15924SDimitry Andric } else if (Token.range().front() == 'p') {
1995eb11fae6SDimitry Andric const DataLayout &DL = MF.getDataLayout();
1996e6d15924SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
1997e6d15924SDimitry Andric if (!verifyAddrSpace(AS))
1998e6d15924SDimitry Andric return error("invalid address space number");
1999e6d15924SDimitry Andric
2000eb11fae6SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
2001eb11fae6SDimitry Andric } else
2002b1c73532SDimitry Andric return GetError();
2003b915e9e0SDimitry Andric lex();
2004b915e9e0SDimitry Andric
2005b915e9e0SDimitry Andric if (Token.isNot(MIToken::greater))
2006b1c73532SDimitry Andric return GetError();
2007b1c73532SDimitry Andric
2008b915e9e0SDimitry Andric lex();
2009b915e9e0SDimitry Andric
2010b1c73532SDimitry Andric Ty = LLT::vector(ElementCount::get(NumElements, HasVScale), Ty);
201101095a5dSDimitry Andric return false;
201201095a5dSDimitry Andric }
201301095a5dSDimitry Andric
parseTypedImmediateOperand(MachineOperand & Dest)2014dd58ef01SDimitry Andric bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) {
2015eb11fae6SDimitry Andric assert(Token.is(MIToken::Identifier));
2016eb11fae6SDimitry Andric StringRef TypeStr = Token.range();
2017eb11fae6SDimitry Andric if (TypeStr.front() != 'i' && TypeStr.front() != 's' &&
2018eb11fae6SDimitry Andric TypeStr.front() != 'p')
2019eb11fae6SDimitry Andric return error(
2020eb11fae6SDimitry Andric "a typed immediate operand should start with one of 'i', 's', or 'p'");
2021eb11fae6SDimitry Andric StringRef SizeStr = Token.range().drop_front();
2022eb11fae6SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
2023eb11fae6SDimitry Andric return error("expected integers after 'i'/'s'/'p' type character");
2024eb11fae6SDimitry Andric
2025dd58ef01SDimitry Andric auto Loc = Token.location();
2026dd58ef01SDimitry Andric lex();
2027eb11fae6SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) {
2028eb11fae6SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
2029eb11fae6SDimitry Andric !(Token.range() == "true" || Token.range() == "false"))
2030dd58ef01SDimitry Andric return error("expected an integer literal");
2031eb11fae6SDimitry Andric }
2032dd58ef01SDimitry Andric const Constant *C = nullptr;
2033dd58ef01SDimitry Andric if (parseIRConstant(Loc, C))
2034dd58ef01SDimitry Andric return true;
2035dd58ef01SDimitry Andric Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C));
2036dd58ef01SDimitry Andric return false;
2037dd58ef01SDimitry Andric }
2038dd58ef01SDimitry Andric
parseFPImmediateOperand(MachineOperand & Dest)2039dd58ef01SDimitry Andric bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
2040dd58ef01SDimitry Andric auto Loc = Token.location();
2041dd58ef01SDimitry Andric lex();
2042b915e9e0SDimitry Andric if (Token.isNot(MIToken::FloatingPointLiteral) &&
2043b915e9e0SDimitry Andric Token.isNot(MIToken::HexLiteral))
2044dd58ef01SDimitry Andric return error("expected a floating point literal");
2045dd58ef01SDimitry Andric const Constant *C = nullptr;
2046dd58ef01SDimitry Andric if (parseIRConstant(Loc, C))
2047dd58ef01SDimitry Andric return true;
2048dd58ef01SDimitry Andric Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C));
2049dd58ef01SDimitry Andric return false;
2050dd58ef01SDimitry Andric }
2051dd58ef01SDimitry Andric
getHexUint(const MIToken & Token,APInt & Result)2052706b4fc4SDimitry Andric static bool getHexUint(const MIToken &Token, APInt &Result) {
2053706b4fc4SDimitry Andric assert(Token.is(MIToken::HexLiteral));
2054706b4fc4SDimitry Andric StringRef S = Token.range();
2055706b4fc4SDimitry Andric assert(S[0] == '0' && tolower(S[1]) == 'x');
2056706b4fc4SDimitry Andric // This could be a floating point literal with a special prefix.
2057706b4fc4SDimitry Andric if (!isxdigit(S[2]))
2058706b4fc4SDimitry Andric return true;
2059706b4fc4SDimitry Andric StringRef V = S.substr(2);
2060706b4fc4SDimitry Andric APInt A(V.size()*4, V, 16);
2061706b4fc4SDimitry Andric
2062706b4fc4SDimitry Andric // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make
2063706b4fc4SDimitry Andric // sure it isn't the case before constructing result.
2064706b4fc4SDimitry Andric unsigned NumBits = (A == 0) ? 32 : A.getActiveBits();
2065706b4fc4SDimitry Andric Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
2066706b4fc4SDimitry Andric return false;
2067706b4fc4SDimitry Andric }
2068706b4fc4SDimitry Andric
getUnsigned(const MIToken & Token,unsigned & Result,ErrorCallbackType ErrCB)2069706b4fc4SDimitry Andric static bool getUnsigned(const MIToken &Token, unsigned &Result,
2070706b4fc4SDimitry Andric ErrorCallbackType ErrCB) {
2071b915e9e0SDimitry Andric if (Token.hasIntegerValue()) {
20721a82d4c0SDimitry Andric const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
20731a82d4c0SDimitry Andric uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
20741a82d4c0SDimitry Andric if (Val64 == Limit)
2075706b4fc4SDimitry Andric return ErrCB(Token.location(), "expected 32-bit integer (too large)");
20761a82d4c0SDimitry Andric Result = Val64;
20771a82d4c0SDimitry Andric return false;
20781a82d4c0SDimitry Andric }
2079b915e9e0SDimitry Andric if (Token.is(MIToken::HexLiteral)) {
2080b915e9e0SDimitry Andric APInt A;
2081706b4fc4SDimitry Andric if (getHexUint(Token, A))
2082b915e9e0SDimitry Andric return true;
2083b915e9e0SDimitry Andric if (A.getBitWidth() > 32)
2084706b4fc4SDimitry Andric return ErrCB(Token.location(), "expected 32-bit integer (too large)");
2085b915e9e0SDimitry Andric Result = A.getZExtValue();
2086b915e9e0SDimitry Andric return false;
2087b915e9e0SDimitry Andric }
2088b915e9e0SDimitry Andric return true;
2089b915e9e0SDimitry Andric }
20901a82d4c0SDimitry Andric
getUnsigned(unsigned & Result)2091706b4fc4SDimitry Andric bool MIParser::getUnsigned(unsigned &Result) {
2092706b4fc4SDimitry Andric return ::getUnsigned(
2093706b4fc4SDimitry Andric Token, Result, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2094706b4fc4SDimitry Andric return error(Loc, Msg);
2095706b4fc4SDimitry Andric });
2096706b4fc4SDimitry Andric }
2097706b4fc4SDimitry Andric
parseMBBReference(MachineBasicBlock * & MBB)20981a82d4c0SDimitry Andric bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
2099dd58ef01SDimitry Andric assert(Token.is(MIToken::MachineBasicBlock) ||
2100dd58ef01SDimitry Andric Token.is(MIToken::MachineBasicBlockLabel));
21011a82d4c0SDimitry Andric unsigned Number;
21021a82d4c0SDimitry Andric if (getUnsigned(Number))
21031a82d4c0SDimitry Andric return true;
2104ee8648bdSDimitry Andric auto MBBInfo = PFS.MBBSlots.find(Number);
2105ee8648bdSDimitry Andric if (MBBInfo == PFS.MBBSlots.end())
21061a82d4c0SDimitry Andric return error(Twine("use of undefined machine basic block #") +
21071a82d4c0SDimitry Andric Twine(Number));
21081a82d4c0SDimitry Andric MBB = MBBInfo->second;
2109044eb2f6SDimitry Andric // TODO: Only parse the name if it's a MachineBasicBlockLabel. Deprecate once
2110044eb2f6SDimitry Andric // we drop the <irname> from the bb.<id>.<irname> format.
21111a82d4c0SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
21121a82d4c0SDimitry Andric return error(Twine("the name of machine basic block #") + Twine(Number) +
21131a82d4c0SDimitry Andric " isn't '" + Token.stringValue() + "'");
21141a82d4c0SDimitry Andric return false;
21151a82d4c0SDimitry Andric }
21161a82d4c0SDimitry Andric
parseMBBOperand(MachineOperand & Dest)21171a82d4c0SDimitry Andric bool MIParser::parseMBBOperand(MachineOperand &Dest) {
21181a82d4c0SDimitry Andric MachineBasicBlock *MBB;
21191a82d4c0SDimitry Andric if (parseMBBReference(MBB))
21201a82d4c0SDimitry Andric return true;
21211a82d4c0SDimitry Andric Dest = MachineOperand::CreateMBB(MBB);
21221a82d4c0SDimitry Andric lex();
21231a82d4c0SDimitry Andric return false;
21241a82d4c0SDimitry Andric }
21251a82d4c0SDimitry Andric
parseStackFrameIndex(int & FI)2126dd58ef01SDimitry Andric bool MIParser::parseStackFrameIndex(int &FI) {
2127dd58ef01SDimitry Andric assert(Token.is(MIToken::StackObject));
2128dd58ef01SDimitry Andric unsigned ID;
2129dd58ef01SDimitry Andric if (getUnsigned(ID))
2130dd58ef01SDimitry Andric return true;
2131dd58ef01SDimitry Andric auto ObjectInfo = PFS.StackObjectSlots.find(ID);
2132dd58ef01SDimitry Andric if (ObjectInfo == PFS.StackObjectSlots.end())
2133dd58ef01SDimitry Andric return error(Twine("use of undefined stack object '%stack.") + Twine(ID) +
2134dd58ef01SDimitry Andric "'");
2135dd58ef01SDimitry Andric StringRef Name;
2136dd58ef01SDimitry Andric if (const auto *Alloca =
2137b915e9e0SDimitry Andric MF.getFrameInfo().getObjectAllocation(ObjectInfo->second))
2138dd58ef01SDimitry Andric Name = Alloca->getName();
2139dd58ef01SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != Name)
2140dd58ef01SDimitry Andric return error(Twine("the name of the stack object '%stack.") + Twine(ID) +
2141dd58ef01SDimitry Andric "' isn't '" + Token.stringValue() + "'");
2142dd58ef01SDimitry Andric lex();
2143dd58ef01SDimitry Andric FI = ObjectInfo->second;
2144dd58ef01SDimitry Andric return false;
2145dd58ef01SDimitry Andric }
2146dd58ef01SDimitry Andric
parseStackObjectOperand(MachineOperand & Dest)2147dd58ef01SDimitry Andric bool MIParser::parseStackObjectOperand(MachineOperand &Dest) {
2148dd58ef01SDimitry Andric int FI;
2149dd58ef01SDimitry Andric if (parseStackFrameIndex(FI))
2150dd58ef01SDimitry Andric return true;
2151dd58ef01SDimitry Andric Dest = MachineOperand::CreateFI(FI);
2152dd58ef01SDimitry Andric return false;
2153dd58ef01SDimitry Andric }
2154dd58ef01SDimitry Andric
parseFixedStackFrameIndex(int & FI)2155dd58ef01SDimitry Andric bool MIParser::parseFixedStackFrameIndex(int &FI) {
2156dd58ef01SDimitry Andric assert(Token.is(MIToken::FixedStackObject));
2157dd58ef01SDimitry Andric unsigned ID;
2158dd58ef01SDimitry Andric if (getUnsigned(ID))
2159dd58ef01SDimitry Andric return true;
2160dd58ef01SDimitry Andric auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID);
2161dd58ef01SDimitry Andric if (ObjectInfo == PFS.FixedStackObjectSlots.end())
2162dd58ef01SDimitry Andric return error(Twine("use of undefined fixed stack object '%fixed-stack.") +
2163dd58ef01SDimitry Andric Twine(ID) + "'");
2164dd58ef01SDimitry Andric lex();
2165dd58ef01SDimitry Andric FI = ObjectInfo->second;
2166dd58ef01SDimitry Andric return false;
2167dd58ef01SDimitry Andric }
2168dd58ef01SDimitry Andric
parseFixedStackObjectOperand(MachineOperand & Dest)2169dd58ef01SDimitry Andric bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
2170dd58ef01SDimitry Andric int FI;
2171dd58ef01SDimitry Andric if (parseFixedStackFrameIndex(FI))
2172dd58ef01SDimitry Andric return true;
2173dd58ef01SDimitry Andric Dest = MachineOperand::CreateFI(FI);
2174dd58ef01SDimitry Andric return false;
2175dd58ef01SDimitry Andric }
2176dd58ef01SDimitry Andric
parseGlobalValue(const MIToken & Token,PerFunctionMIParsingState & PFS,GlobalValue * & GV,ErrorCallbackType ErrCB)2177706b4fc4SDimitry Andric static bool parseGlobalValue(const MIToken &Token,
2178706b4fc4SDimitry Andric PerFunctionMIParsingState &PFS, GlobalValue *&GV,
2179706b4fc4SDimitry Andric ErrorCallbackType ErrCB) {
21801a82d4c0SDimitry Andric switch (Token.kind()) {
21811a82d4c0SDimitry Andric case MIToken::NamedGlobalValue: {
2182706b4fc4SDimitry Andric const Module *M = PFS.MF.getFunction().getParent();
2183dd58ef01SDimitry Andric GV = M->getNamedValue(Token.stringValue());
2184dd58ef01SDimitry Andric if (!GV)
2185706b4fc4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined global value '") +
2186706b4fc4SDimitry Andric Token.range() + "'");
21871a82d4c0SDimitry Andric break;
21881a82d4c0SDimitry Andric }
21891a82d4c0SDimitry Andric case MIToken::GlobalValue: {
21901a82d4c0SDimitry Andric unsigned GVIdx;
2191706b4fc4SDimitry Andric if (getUnsigned(Token, GVIdx, ErrCB))
21921a82d4c0SDimitry Andric return true;
2193ac9a064cSDimitry Andric GV = PFS.IRSlots.GlobalValues.get(GVIdx);
2194ac9a064cSDimitry Andric if (!GV)
2195706b4fc4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined global value '@") +
2196706b4fc4SDimitry Andric Twine(GVIdx) + "'");
21971a82d4c0SDimitry Andric break;
21981a82d4c0SDimitry Andric }
21991a82d4c0SDimitry Andric default:
22001a82d4c0SDimitry Andric llvm_unreachable("The current token should be a global value");
22011a82d4c0SDimitry Andric }
2202dd58ef01SDimitry Andric return false;
2203dd58ef01SDimitry Andric }
2204dd58ef01SDimitry Andric
parseGlobalValue(GlobalValue * & GV)2205706b4fc4SDimitry Andric bool MIParser::parseGlobalValue(GlobalValue *&GV) {
2206706b4fc4SDimitry Andric return ::parseGlobalValue(
2207706b4fc4SDimitry Andric Token, PFS, GV,
2208706b4fc4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2209706b4fc4SDimitry Andric return error(Loc, Msg);
2210706b4fc4SDimitry Andric });
2211706b4fc4SDimitry Andric }
2212706b4fc4SDimitry Andric
parseGlobalAddressOperand(MachineOperand & Dest)2213dd58ef01SDimitry Andric bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
2214dd58ef01SDimitry Andric GlobalValue *GV = nullptr;
2215dd58ef01SDimitry Andric if (parseGlobalValue(GV))
2216dd58ef01SDimitry Andric return true;
2217dd58ef01SDimitry Andric lex();
2218dd58ef01SDimitry Andric Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
2219dd58ef01SDimitry Andric if (parseOperandsOffset(Dest))
2220dd58ef01SDimitry Andric return true;
2221dd58ef01SDimitry Andric return false;
2222dd58ef01SDimitry Andric }
2223dd58ef01SDimitry Andric
parseConstantPoolIndexOperand(MachineOperand & Dest)2224dd58ef01SDimitry Andric bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) {
2225dd58ef01SDimitry Andric assert(Token.is(MIToken::ConstantPoolItem));
2226dd58ef01SDimitry Andric unsigned ID;
2227dd58ef01SDimitry Andric if (getUnsigned(ID))
2228dd58ef01SDimitry Andric return true;
2229dd58ef01SDimitry Andric auto ConstantInfo = PFS.ConstantPoolSlots.find(ID);
2230dd58ef01SDimitry Andric if (ConstantInfo == PFS.ConstantPoolSlots.end())
2231dd58ef01SDimitry Andric return error("use of undefined constant '%const." + Twine(ID) + "'");
2232dd58ef01SDimitry Andric lex();
2233dd58ef01SDimitry Andric Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0);
2234dd58ef01SDimitry Andric if (parseOperandsOffset(Dest))
2235dd58ef01SDimitry Andric return true;
2236dd58ef01SDimitry Andric return false;
2237dd58ef01SDimitry Andric }
2238dd58ef01SDimitry Andric
parseJumpTableIndexOperand(MachineOperand & Dest)2239dd58ef01SDimitry Andric bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
2240dd58ef01SDimitry Andric assert(Token.is(MIToken::JumpTableIndex));
2241dd58ef01SDimitry Andric unsigned ID;
2242dd58ef01SDimitry Andric if (getUnsigned(ID))
2243dd58ef01SDimitry Andric return true;
2244dd58ef01SDimitry Andric auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID);
2245dd58ef01SDimitry Andric if (JumpTableEntryInfo == PFS.JumpTableSlots.end())
2246dd58ef01SDimitry Andric return error("use of undefined jump table '%jump-table." + Twine(ID) + "'");
2247dd58ef01SDimitry Andric lex();
2248dd58ef01SDimitry Andric Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second);
2249dd58ef01SDimitry Andric return false;
2250dd58ef01SDimitry Andric }
2251dd58ef01SDimitry Andric
parseExternalSymbolOperand(MachineOperand & Dest)2252dd58ef01SDimitry Andric bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
2253dd58ef01SDimitry Andric assert(Token.is(MIToken::ExternalSymbol));
2254dd58ef01SDimitry Andric const char *Symbol = MF.createExternalSymbolName(Token.stringValue());
2255dd58ef01SDimitry Andric lex();
2256dd58ef01SDimitry Andric Dest = MachineOperand::CreateES(Symbol);
2257dd58ef01SDimitry Andric if (parseOperandsOffset(Dest))
2258dd58ef01SDimitry Andric return true;
2259dd58ef01SDimitry Andric return false;
2260dd58ef01SDimitry Andric }
2261dd58ef01SDimitry Andric
parseMCSymbolOperand(MachineOperand & Dest)2262d8e91e46SDimitry Andric bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) {
2263d8e91e46SDimitry Andric assert(Token.is(MIToken::MCSymbol));
2264d8e91e46SDimitry Andric MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue());
2265d8e91e46SDimitry Andric lex();
2266d8e91e46SDimitry Andric Dest = MachineOperand::CreateMCSymbol(Symbol);
2267d8e91e46SDimitry Andric if (parseOperandsOffset(Dest))
2268d8e91e46SDimitry Andric return true;
2269d8e91e46SDimitry Andric return false;
2270d8e91e46SDimitry Andric }
2271d8e91e46SDimitry Andric
parseSubRegisterIndexOperand(MachineOperand & Dest)227201095a5dSDimitry Andric bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) {
227301095a5dSDimitry Andric assert(Token.is(MIToken::SubRegisterIndex));
227401095a5dSDimitry Andric StringRef Name = Token.stringValue();
2275e6d15924SDimitry Andric unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue());
227601095a5dSDimitry Andric if (SubRegIndex == 0)
227701095a5dSDimitry Andric return error(Twine("unknown subregister index '") + Name + "'");
227801095a5dSDimitry Andric lex();
227901095a5dSDimitry Andric Dest = MachineOperand::CreateImm(SubRegIndex);
228001095a5dSDimitry Andric return false;
228101095a5dSDimitry Andric }
228201095a5dSDimitry Andric
parseMDNode(MDNode * & Node)2283dd58ef01SDimitry Andric bool MIParser::parseMDNode(MDNode *&Node) {
2284dd58ef01SDimitry Andric assert(Token.is(MIToken::exclaim));
2285044eb2f6SDimitry Andric
2286dd58ef01SDimitry Andric auto Loc = Token.location();
2287dd58ef01SDimitry Andric lex();
2288dd58ef01SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
2289dd58ef01SDimitry Andric return error("expected metadata id after '!'");
2290dd58ef01SDimitry Andric unsigned ID;
2291dd58ef01SDimitry Andric if (getUnsigned(ID))
2292dd58ef01SDimitry Andric return true;
229301095a5dSDimitry Andric auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
2294344a3780SDimitry Andric if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) {
2295344a3780SDimitry Andric NodeInfo = PFS.MachineMetadataNodes.find(ID);
2296344a3780SDimitry Andric if (NodeInfo == PFS.MachineMetadataNodes.end())
2297dd58ef01SDimitry Andric return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
2298344a3780SDimitry Andric }
2299dd58ef01SDimitry Andric lex();
2300dd58ef01SDimitry Andric Node = NodeInfo->second.get();
2301dd58ef01SDimitry Andric return false;
2302dd58ef01SDimitry Andric }
2303dd58ef01SDimitry Andric
parseDIExpression(MDNode * & Expr)2304044eb2f6SDimitry Andric bool MIParser::parseDIExpression(MDNode *&Expr) {
2305ac9a064cSDimitry Andric unsigned Read;
2306ac9a064cSDimitry Andric Expr = llvm::parseDIExpressionBodyAtBeginning(
2307ac9a064cSDimitry Andric CurrentSource, Read, Error, *PFS.MF.getFunction().getParent(),
2308ac9a064cSDimitry Andric &PFS.IRSlots);
2309ac9a064cSDimitry Andric CurrentSource = CurrentSource.slice(Read, StringRef::npos);
2310044eb2f6SDimitry Andric lex();
2311ac9a064cSDimitry Andric if (!Expr)
2312ac9a064cSDimitry Andric return error(Error.getMessage());
2313044eb2f6SDimitry Andric return false;
2314044eb2f6SDimitry Andric }
2315044eb2f6SDimitry Andric
parseDILocation(MDNode * & Loc)2316d8e91e46SDimitry Andric bool MIParser::parseDILocation(MDNode *&Loc) {
2317d8e91e46SDimitry Andric assert(Token.is(MIToken::md_dilocation));
2318d8e91e46SDimitry Andric lex();
2319d8e91e46SDimitry Andric
2320d8e91e46SDimitry Andric bool HaveLine = false;
2321d8e91e46SDimitry Andric unsigned Line = 0;
2322d8e91e46SDimitry Andric unsigned Column = 0;
2323d8e91e46SDimitry Andric MDNode *Scope = nullptr;
2324d8e91e46SDimitry Andric MDNode *InlinedAt = nullptr;
2325d8e91e46SDimitry Andric bool ImplicitCode = false;
2326d8e91e46SDimitry Andric
2327d8e91e46SDimitry Andric if (expectAndConsume(MIToken::lparen))
2328d8e91e46SDimitry Andric return true;
2329d8e91e46SDimitry Andric
2330d8e91e46SDimitry Andric if (Token.isNot(MIToken::rparen)) {
2331d8e91e46SDimitry Andric do {
2332d8e91e46SDimitry Andric if (Token.is(MIToken::Identifier)) {
2333d8e91e46SDimitry Andric if (Token.stringValue() == "line") {
2334d8e91e46SDimitry Andric lex();
2335d8e91e46SDimitry Andric if (expectAndConsume(MIToken::colon))
2336d8e91e46SDimitry Andric return true;
2337d8e91e46SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
2338d8e91e46SDimitry Andric Token.integerValue().isSigned())
2339d8e91e46SDimitry Andric return error("expected unsigned integer");
2340d8e91e46SDimitry Andric Line = Token.integerValue().getZExtValue();
2341d8e91e46SDimitry Andric HaveLine = true;
2342d8e91e46SDimitry Andric lex();
2343d8e91e46SDimitry Andric continue;
2344d8e91e46SDimitry Andric }
2345d8e91e46SDimitry Andric if (Token.stringValue() == "column") {
2346d8e91e46SDimitry Andric lex();
2347d8e91e46SDimitry Andric if (expectAndConsume(MIToken::colon))
2348d8e91e46SDimitry Andric return true;
2349d8e91e46SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
2350d8e91e46SDimitry Andric Token.integerValue().isSigned())
2351d8e91e46SDimitry Andric return error("expected unsigned integer");
2352d8e91e46SDimitry Andric Column = Token.integerValue().getZExtValue();
2353d8e91e46SDimitry Andric lex();
2354d8e91e46SDimitry Andric continue;
2355d8e91e46SDimitry Andric }
2356d8e91e46SDimitry Andric if (Token.stringValue() == "scope") {
2357d8e91e46SDimitry Andric lex();
2358d8e91e46SDimitry Andric if (expectAndConsume(MIToken::colon))
2359d8e91e46SDimitry Andric return true;
2360d8e91e46SDimitry Andric if (parseMDNode(Scope))
2361d8e91e46SDimitry Andric return error("expected metadata node");
2362d8e91e46SDimitry Andric if (!isa<DIScope>(Scope))
2363d8e91e46SDimitry Andric return error("expected DIScope node");
2364d8e91e46SDimitry Andric continue;
2365d8e91e46SDimitry Andric }
2366d8e91e46SDimitry Andric if (Token.stringValue() == "inlinedAt") {
2367d8e91e46SDimitry Andric lex();
2368d8e91e46SDimitry Andric if (expectAndConsume(MIToken::colon))
2369d8e91e46SDimitry Andric return true;
2370d8e91e46SDimitry Andric if (Token.is(MIToken::exclaim)) {
2371d8e91e46SDimitry Andric if (parseMDNode(InlinedAt))
2372d8e91e46SDimitry Andric return true;
2373d8e91e46SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
2374d8e91e46SDimitry Andric if (parseDILocation(InlinedAt))
2375d8e91e46SDimitry Andric return true;
2376d8e91e46SDimitry Andric } else
2377d8e91e46SDimitry Andric return error("expected metadata node");
2378d8e91e46SDimitry Andric if (!isa<DILocation>(InlinedAt))
2379d8e91e46SDimitry Andric return error("expected DILocation node");
2380d8e91e46SDimitry Andric continue;
2381d8e91e46SDimitry Andric }
2382d8e91e46SDimitry Andric if (Token.stringValue() == "isImplicitCode") {
2383d8e91e46SDimitry Andric lex();
2384d8e91e46SDimitry Andric if (expectAndConsume(MIToken::colon))
2385d8e91e46SDimitry Andric return true;
2386d8e91e46SDimitry Andric if (!Token.is(MIToken::Identifier))
2387d8e91e46SDimitry Andric return error("expected true/false");
2388d8e91e46SDimitry Andric // As far as I can see, we don't have any existing need for parsing
2389d8e91e46SDimitry Andric // true/false in MIR yet. Do it ad-hoc until there's something else
2390d8e91e46SDimitry Andric // that needs it.
2391d8e91e46SDimitry Andric if (Token.stringValue() == "true")
2392d8e91e46SDimitry Andric ImplicitCode = true;
2393d8e91e46SDimitry Andric else if (Token.stringValue() == "false")
2394d8e91e46SDimitry Andric ImplicitCode = false;
2395d8e91e46SDimitry Andric else
2396d8e91e46SDimitry Andric return error("expected true/false");
2397d8e91e46SDimitry Andric lex();
2398d8e91e46SDimitry Andric continue;
2399d8e91e46SDimitry Andric }
2400d8e91e46SDimitry Andric }
2401d8e91e46SDimitry Andric return error(Twine("invalid DILocation argument '") +
2402d8e91e46SDimitry Andric Token.stringValue() + "'");
2403d8e91e46SDimitry Andric } while (consumeIfPresent(MIToken::comma));
2404d8e91e46SDimitry Andric }
2405d8e91e46SDimitry Andric
2406d8e91e46SDimitry Andric if (expectAndConsume(MIToken::rparen))
2407d8e91e46SDimitry Andric return true;
2408d8e91e46SDimitry Andric
2409d8e91e46SDimitry Andric if (!HaveLine)
2410d8e91e46SDimitry Andric return error("DILocation requires line number");
2411d8e91e46SDimitry Andric if (!Scope)
2412d8e91e46SDimitry Andric return error("DILocation requires a scope");
2413d8e91e46SDimitry Andric
2414d8e91e46SDimitry Andric Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope,
2415d8e91e46SDimitry Andric InlinedAt, ImplicitCode);
2416d8e91e46SDimitry Andric return false;
2417d8e91e46SDimitry Andric }
2418d8e91e46SDimitry Andric
parseMetadataOperand(MachineOperand & Dest)2419dd58ef01SDimitry Andric bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
2420dd58ef01SDimitry Andric MDNode *Node = nullptr;
2421044eb2f6SDimitry Andric if (Token.is(MIToken::exclaim)) {
2422dd58ef01SDimitry Andric if (parseMDNode(Node))
2423dd58ef01SDimitry Andric return true;
2424044eb2f6SDimitry Andric } else if (Token.is(MIToken::md_diexpr)) {
2425044eb2f6SDimitry Andric if (parseDIExpression(Node))
2426044eb2f6SDimitry Andric return true;
2427044eb2f6SDimitry Andric }
2428dd58ef01SDimitry Andric Dest = MachineOperand::CreateMetadata(Node);
2429dd58ef01SDimitry Andric return false;
2430dd58ef01SDimitry Andric }
2431dd58ef01SDimitry Andric
parseCFIOffset(int & Offset)2432dd58ef01SDimitry Andric bool MIParser::parseCFIOffset(int &Offset) {
2433dd58ef01SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
2434dd58ef01SDimitry Andric return error("expected a cfi offset");
24357fa27ce4SDimitry Andric if (Token.integerValue().getSignificantBits() > 32)
2436dd58ef01SDimitry Andric return error("expected a 32 bit integer (the cfi offset is too large)");
2437dd58ef01SDimitry Andric Offset = (int)Token.integerValue().getExtValue();
24381a82d4c0SDimitry Andric lex();
24391a82d4c0SDimitry Andric return false;
24401a82d4c0SDimitry Andric }
24411a82d4c0SDimitry Andric
parseCFIRegister(Register & Reg)2442cfca06d7SDimitry Andric bool MIParser::parseCFIRegister(Register &Reg) {
2443dd58ef01SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
2444dd58ef01SDimitry Andric return error("expected a cfi register");
2445cfca06d7SDimitry Andric Register LLVMReg;
2446b915e9e0SDimitry Andric if (parseNamedRegister(LLVMReg))
2447dd58ef01SDimitry Andric return true;
2448dd58ef01SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
2449dd58ef01SDimitry Andric assert(TRI && "Expected target register info");
2450dd58ef01SDimitry Andric int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true);
2451dd58ef01SDimitry Andric if (DwarfReg < 0)
2452dd58ef01SDimitry Andric return error("invalid DWARF register");
2453dd58ef01SDimitry Andric Reg = (unsigned)DwarfReg;
2454dd58ef01SDimitry Andric lex();
2455dd58ef01SDimitry Andric return false;
2456dd58ef01SDimitry Andric }
2457dd58ef01SDimitry Andric
parseCFIAddressSpace(unsigned & AddressSpace)2458344a3780SDimitry Andric bool MIParser::parseCFIAddressSpace(unsigned &AddressSpace) {
2459344a3780SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
2460344a3780SDimitry Andric return error("expected a cfi address space literal");
2461344a3780SDimitry Andric if (Token.integerValue().isSigned())
2462344a3780SDimitry Andric return error("expected an unsigned integer (cfi address space)");
2463344a3780SDimitry Andric AddressSpace = Token.integerValue().getZExtValue();
2464344a3780SDimitry Andric lex();
2465344a3780SDimitry Andric return false;
2466344a3780SDimitry Andric }
2467344a3780SDimitry Andric
parseCFIEscapeValues(std::string & Values)2468044eb2f6SDimitry Andric bool MIParser::parseCFIEscapeValues(std::string &Values) {
2469044eb2f6SDimitry Andric do {
2470044eb2f6SDimitry Andric if (Token.isNot(MIToken::HexLiteral))
2471044eb2f6SDimitry Andric return error("expected a hexadecimal literal");
2472044eb2f6SDimitry Andric unsigned Value;
2473044eb2f6SDimitry Andric if (getUnsigned(Value))
2474044eb2f6SDimitry Andric return true;
2475044eb2f6SDimitry Andric if (Value > UINT8_MAX)
2476044eb2f6SDimitry Andric return error("expected a 8-bit integer (too large)");
2477044eb2f6SDimitry Andric Values.push_back(static_cast<uint8_t>(Value));
2478044eb2f6SDimitry Andric lex();
2479044eb2f6SDimitry Andric } while (consumeIfPresent(MIToken::comma));
2480044eb2f6SDimitry Andric return false;
2481044eb2f6SDimitry Andric }
2482044eb2f6SDimitry Andric
parseCFIOperand(MachineOperand & Dest)2483dd58ef01SDimitry Andric bool MIParser::parseCFIOperand(MachineOperand &Dest) {
2484dd58ef01SDimitry Andric auto Kind = Token.kind();
2485dd58ef01SDimitry Andric lex();
2486dd58ef01SDimitry Andric int Offset;
2487cfca06d7SDimitry Andric Register Reg;
2488344a3780SDimitry Andric unsigned AddressSpace;
2489dd58ef01SDimitry Andric unsigned CFIIndex;
2490dd58ef01SDimitry Andric switch (Kind) {
2491dd58ef01SDimitry Andric case MIToken::kw_cfi_same_value:
2492dd58ef01SDimitry Andric if (parseCFIRegister(Reg))
2493dd58ef01SDimitry Andric return true;
2494b915e9e0SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg));
2495dd58ef01SDimitry Andric break;
2496dd58ef01SDimitry Andric case MIToken::kw_cfi_offset:
2497dd58ef01SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2498dd58ef01SDimitry Andric parseCFIOffset(Offset))
2499dd58ef01SDimitry Andric return true;
2500dd58ef01SDimitry Andric CFIIndex =
2501b915e9e0SDimitry Andric MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
2502dd58ef01SDimitry Andric break;
2503044eb2f6SDimitry Andric case MIToken::kw_cfi_rel_offset:
2504044eb2f6SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2505044eb2f6SDimitry Andric parseCFIOffset(Offset))
2506044eb2f6SDimitry Andric return true;
2507044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(
2508044eb2f6SDimitry Andric MCCFIInstruction::createRelOffset(nullptr, Reg, Offset));
2509044eb2f6SDimitry Andric break;
2510dd58ef01SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
2511dd58ef01SDimitry Andric if (parseCFIRegister(Reg))
2512dd58ef01SDimitry Andric return true;
2513dd58ef01SDimitry Andric CFIIndex =
2514b915e9e0SDimitry Andric MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
2515dd58ef01SDimitry Andric break;
2516dd58ef01SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
2517dd58ef01SDimitry Andric if (parseCFIOffset(Offset))
2518dd58ef01SDimitry Andric return true;
2519cfca06d7SDimitry Andric CFIIndex =
2520cfca06d7SDimitry Andric MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset));
2521dd58ef01SDimitry Andric break;
2522044eb2f6SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
2523044eb2f6SDimitry Andric if (parseCFIOffset(Offset))
2524044eb2f6SDimitry Andric return true;
2525044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(
2526044eb2f6SDimitry Andric MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset));
2527044eb2f6SDimitry Andric break;
2528dd58ef01SDimitry Andric case MIToken::kw_cfi_def_cfa:
2529dd58ef01SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2530dd58ef01SDimitry Andric parseCFIOffset(Offset))
2531dd58ef01SDimitry Andric return true;
2532dd58ef01SDimitry Andric CFIIndex =
2533cfca06d7SDimitry Andric MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, Offset));
2534dd58ef01SDimitry Andric break;
2535344a3780SDimitry Andric case MIToken::kw_cfi_llvm_def_aspace_cfa:
2536344a3780SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2537344a3780SDimitry Andric parseCFIOffset(Offset) || expectAndConsume(MIToken::comma) ||
2538344a3780SDimitry Andric parseCFIAddressSpace(AddressSpace))
2539344a3780SDimitry Andric return true;
2540344a3780SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMDefAspaceCfa(
25417fa27ce4SDimitry Andric nullptr, Reg, Offset, AddressSpace, SMLoc()));
2542344a3780SDimitry Andric break;
2543044eb2f6SDimitry Andric case MIToken::kw_cfi_remember_state:
2544044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
2545044eb2f6SDimitry Andric break;
2546044eb2f6SDimitry Andric case MIToken::kw_cfi_restore:
2547044eb2f6SDimitry Andric if (parseCFIRegister(Reg))
2548044eb2f6SDimitry Andric return true;
2549044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
2550044eb2f6SDimitry Andric break;
2551044eb2f6SDimitry Andric case MIToken::kw_cfi_restore_state:
2552044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr));
2553044eb2f6SDimitry Andric break;
2554044eb2f6SDimitry Andric case MIToken::kw_cfi_undefined:
2555044eb2f6SDimitry Andric if (parseCFIRegister(Reg))
2556044eb2f6SDimitry Andric return true;
2557044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg));
2558044eb2f6SDimitry Andric break;
2559044eb2f6SDimitry Andric case MIToken::kw_cfi_register: {
2560cfca06d7SDimitry Andric Register Reg2;
2561044eb2f6SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2562044eb2f6SDimitry Andric parseCFIRegister(Reg2))
2563044eb2f6SDimitry Andric return true;
2564044eb2f6SDimitry Andric
2565044eb2f6SDimitry Andric CFIIndex =
2566044eb2f6SDimitry Andric MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2));
2567044eb2f6SDimitry Andric break;
2568044eb2f6SDimitry Andric }
2569044eb2f6SDimitry Andric case MIToken::kw_cfi_window_save:
2570044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
2571044eb2f6SDimitry Andric break;
2572d8e91e46SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
2573d8e91e46SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
2574d8e91e46SDimitry Andric break;
2575044eb2f6SDimitry Andric case MIToken::kw_cfi_escape: {
2576044eb2f6SDimitry Andric std::string Values;
2577044eb2f6SDimitry Andric if (parseCFIEscapeValues(Values))
2578044eb2f6SDimitry Andric return true;
2579044eb2f6SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values));
2580044eb2f6SDimitry Andric break;
2581044eb2f6SDimitry Andric }
2582dd58ef01SDimitry Andric default:
2583dd58ef01SDimitry Andric // TODO: Parse the other CFI operands.
2584dd58ef01SDimitry Andric llvm_unreachable("The current token should be a cfi operand");
2585dd58ef01SDimitry Andric }
2586dd58ef01SDimitry Andric Dest = MachineOperand::CreateCFIIndex(CFIIndex);
2587dd58ef01SDimitry Andric return false;
2588dd58ef01SDimitry Andric }
2589dd58ef01SDimitry Andric
parseIRBlock(BasicBlock * & BB,const Function & F)2590dd58ef01SDimitry Andric bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
2591dd58ef01SDimitry Andric switch (Token.kind()) {
2592dd58ef01SDimitry Andric case MIToken::NamedIRBlock: {
2593dd58ef01SDimitry Andric BB = dyn_cast_or_null<BasicBlock>(
2594b915e9e0SDimitry Andric F.getValueSymbolTable()->lookup(Token.stringValue()));
2595dd58ef01SDimitry Andric if (!BB)
2596dd58ef01SDimitry Andric return error(Twine("use of undefined IR block '") + Token.range() + "'");
2597dd58ef01SDimitry Andric break;
2598dd58ef01SDimitry Andric }
2599dd58ef01SDimitry Andric case MIToken::IRBlock: {
2600dd58ef01SDimitry Andric unsigned SlotNumber = 0;
2601dd58ef01SDimitry Andric if (getUnsigned(SlotNumber))
2602dd58ef01SDimitry Andric return true;
2603dd58ef01SDimitry Andric BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F));
2604dd58ef01SDimitry Andric if (!BB)
2605dd58ef01SDimitry Andric return error(Twine("use of undefined IR block '%ir-block.") +
2606dd58ef01SDimitry Andric Twine(SlotNumber) + "'");
2607dd58ef01SDimitry Andric break;
2608dd58ef01SDimitry Andric }
2609dd58ef01SDimitry Andric default:
2610dd58ef01SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
2611dd58ef01SDimitry Andric }
2612dd58ef01SDimitry Andric return false;
2613dd58ef01SDimitry Andric }
2614dd58ef01SDimitry Andric
parseBlockAddressOperand(MachineOperand & Dest)2615dd58ef01SDimitry Andric bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
2616dd58ef01SDimitry Andric assert(Token.is(MIToken::kw_blockaddress));
2617dd58ef01SDimitry Andric lex();
2618dd58ef01SDimitry Andric if (expectAndConsume(MIToken::lparen))
2619dd58ef01SDimitry Andric return true;
2620dd58ef01SDimitry Andric if (Token.isNot(MIToken::GlobalValue) &&
2621dd58ef01SDimitry Andric Token.isNot(MIToken::NamedGlobalValue))
2622dd58ef01SDimitry Andric return error("expected a global value");
2623dd58ef01SDimitry Andric GlobalValue *GV = nullptr;
2624dd58ef01SDimitry Andric if (parseGlobalValue(GV))
2625dd58ef01SDimitry Andric return true;
2626dd58ef01SDimitry Andric auto *F = dyn_cast<Function>(GV);
2627dd58ef01SDimitry Andric if (!F)
2628dd58ef01SDimitry Andric return error("expected an IR function reference");
2629dd58ef01SDimitry Andric lex();
2630dd58ef01SDimitry Andric if (expectAndConsume(MIToken::comma))
2631dd58ef01SDimitry Andric return true;
2632dd58ef01SDimitry Andric BasicBlock *BB = nullptr;
2633dd58ef01SDimitry Andric if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
2634dd58ef01SDimitry Andric return error("expected an IR block reference");
2635dd58ef01SDimitry Andric if (parseIRBlock(BB, *F))
2636dd58ef01SDimitry Andric return true;
2637dd58ef01SDimitry Andric lex();
2638dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
2639dd58ef01SDimitry Andric return true;
2640dd58ef01SDimitry Andric Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
2641dd58ef01SDimitry Andric if (parseOperandsOffset(Dest))
2642dd58ef01SDimitry Andric return true;
2643dd58ef01SDimitry Andric return false;
2644dd58ef01SDimitry Andric }
2645dd58ef01SDimitry Andric
parseIntrinsicOperand(MachineOperand & Dest)2646b915e9e0SDimitry Andric bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) {
2647b915e9e0SDimitry Andric assert(Token.is(MIToken::kw_intrinsic));
2648b915e9e0SDimitry Andric lex();
2649b915e9e0SDimitry Andric if (expectAndConsume(MIToken::lparen))
2650b915e9e0SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
2651b915e9e0SDimitry Andric
2652b915e9e0SDimitry Andric if (Token.isNot(MIToken::NamedGlobalValue))
2653b915e9e0SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
2654b915e9e0SDimitry Andric
2655cfca06d7SDimitry Andric std::string Name = std::string(Token.stringValue());
2656b915e9e0SDimitry Andric lex();
2657b915e9e0SDimitry Andric
2658b915e9e0SDimitry Andric if (expectAndConsume(MIToken::rparen))
2659b915e9e0SDimitry Andric return error("expected ')' to terminate intrinsic name");
2660b915e9e0SDimitry Andric
2661b915e9e0SDimitry Andric // Find out what intrinsic we're dealing with, first try the global namespace
2662b915e9e0SDimitry Andric // and then the target's private intrinsics if that fails.
2663b915e9e0SDimitry Andric const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo();
2664b915e9e0SDimitry Andric Intrinsic::ID ID = Function::lookupIntrinsicID(Name);
2665b915e9e0SDimitry Andric if (ID == Intrinsic::not_intrinsic && TII)
2666b915e9e0SDimitry Andric ID = static_cast<Intrinsic::ID>(TII->lookupName(Name));
2667b915e9e0SDimitry Andric
2668b915e9e0SDimitry Andric if (ID == Intrinsic::not_intrinsic)
2669b915e9e0SDimitry Andric return error("unknown intrinsic name");
2670b915e9e0SDimitry Andric Dest = MachineOperand::CreateIntrinsicID(ID);
2671b915e9e0SDimitry Andric
2672b915e9e0SDimitry Andric return false;
2673b915e9e0SDimitry Andric }
2674b915e9e0SDimitry Andric
parsePredicateOperand(MachineOperand & Dest)2675b915e9e0SDimitry Andric bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
2676b915e9e0SDimitry Andric assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred));
2677b915e9e0SDimitry Andric bool IsFloat = Token.is(MIToken::kw_floatpred);
2678b915e9e0SDimitry Andric lex();
2679b915e9e0SDimitry Andric
2680b915e9e0SDimitry Andric if (expectAndConsume(MIToken::lparen))
2681b915e9e0SDimitry Andric return error("expected syntax intpred(whatever) or floatpred(whatever");
2682b915e9e0SDimitry Andric
2683b915e9e0SDimitry Andric if (Token.isNot(MIToken::Identifier))
2684b915e9e0SDimitry Andric return error("whatever");
2685b915e9e0SDimitry Andric
2686b915e9e0SDimitry Andric CmpInst::Predicate Pred;
2687b915e9e0SDimitry Andric if (IsFloat) {
2688b915e9e0SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
2689b915e9e0SDimitry Andric .Case("false", CmpInst::FCMP_FALSE)
2690b915e9e0SDimitry Andric .Case("oeq", CmpInst::FCMP_OEQ)
2691b915e9e0SDimitry Andric .Case("ogt", CmpInst::FCMP_OGT)
2692b915e9e0SDimitry Andric .Case("oge", CmpInst::FCMP_OGE)
2693b915e9e0SDimitry Andric .Case("olt", CmpInst::FCMP_OLT)
2694b915e9e0SDimitry Andric .Case("ole", CmpInst::FCMP_OLE)
2695b915e9e0SDimitry Andric .Case("one", CmpInst::FCMP_ONE)
2696b915e9e0SDimitry Andric .Case("ord", CmpInst::FCMP_ORD)
2697b915e9e0SDimitry Andric .Case("uno", CmpInst::FCMP_UNO)
2698b915e9e0SDimitry Andric .Case("ueq", CmpInst::FCMP_UEQ)
2699b915e9e0SDimitry Andric .Case("ugt", CmpInst::FCMP_UGT)
2700b915e9e0SDimitry Andric .Case("uge", CmpInst::FCMP_UGE)
2701b915e9e0SDimitry Andric .Case("ult", CmpInst::FCMP_ULT)
2702b915e9e0SDimitry Andric .Case("ule", CmpInst::FCMP_ULE)
2703b915e9e0SDimitry Andric .Case("une", CmpInst::FCMP_UNE)
2704b915e9e0SDimitry Andric .Case("true", CmpInst::FCMP_TRUE)
2705b915e9e0SDimitry Andric .Default(CmpInst::BAD_FCMP_PREDICATE);
2706b915e9e0SDimitry Andric if (!CmpInst::isFPPredicate(Pred))
2707b915e9e0SDimitry Andric return error("invalid floating-point predicate");
2708b915e9e0SDimitry Andric } else {
2709b915e9e0SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
2710b915e9e0SDimitry Andric .Case("eq", CmpInst::ICMP_EQ)
2711b915e9e0SDimitry Andric .Case("ne", CmpInst::ICMP_NE)
2712b915e9e0SDimitry Andric .Case("sgt", CmpInst::ICMP_SGT)
2713b915e9e0SDimitry Andric .Case("sge", CmpInst::ICMP_SGE)
2714b915e9e0SDimitry Andric .Case("slt", CmpInst::ICMP_SLT)
2715b915e9e0SDimitry Andric .Case("sle", CmpInst::ICMP_SLE)
2716b915e9e0SDimitry Andric .Case("ugt", CmpInst::ICMP_UGT)
2717b915e9e0SDimitry Andric .Case("uge", CmpInst::ICMP_UGE)
2718b915e9e0SDimitry Andric .Case("ult", CmpInst::ICMP_ULT)
2719b915e9e0SDimitry Andric .Case("ule", CmpInst::ICMP_ULE)
2720b915e9e0SDimitry Andric .Default(CmpInst::BAD_ICMP_PREDICATE);
2721b915e9e0SDimitry Andric if (!CmpInst::isIntPredicate(Pred))
2722b915e9e0SDimitry Andric return error("invalid integer predicate");
2723b915e9e0SDimitry Andric }
2724b915e9e0SDimitry Andric
2725b915e9e0SDimitry Andric lex();
2726b915e9e0SDimitry Andric Dest = MachineOperand::CreatePredicate(Pred);
2727b915e9e0SDimitry Andric if (expectAndConsume(MIToken::rparen))
2728b915e9e0SDimitry Andric return error("predicate should be terminated by ')'.");
2729b915e9e0SDimitry Andric
2730b915e9e0SDimitry Andric return false;
2731b915e9e0SDimitry Andric }
2732b915e9e0SDimitry Andric
parseShuffleMaskOperand(MachineOperand & Dest)27331d5ae102SDimitry Andric bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
27341d5ae102SDimitry Andric assert(Token.is(MIToken::kw_shufflemask));
27351d5ae102SDimitry Andric
27361d5ae102SDimitry Andric lex();
27371d5ae102SDimitry Andric if (expectAndConsume(MIToken::lparen))
27381d5ae102SDimitry Andric return error("expected syntax shufflemask(<integer or undef>, ...)");
27391d5ae102SDimitry Andric
2740706b4fc4SDimitry Andric SmallVector<int, 32> ShufMask;
27411d5ae102SDimitry Andric do {
27421d5ae102SDimitry Andric if (Token.is(MIToken::kw_undef)) {
2743706b4fc4SDimitry Andric ShufMask.push_back(-1);
27441d5ae102SDimitry Andric } else if (Token.is(MIToken::IntegerLiteral)) {
27451d5ae102SDimitry Andric const APSInt &Int = Token.integerValue();
2746706b4fc4SDimitry Andric ShufMask.push_back(Int.getExtValue());
27471d5ae102SDimitry Andric } else
27481d5ae102SDimitry Andric return error("expected integer constant");
27491d5ae102SDimitry Andric
27501d5ae102SDimitry Andric lex();
27511d5ae102SDimitry Andric } while (consumeIfPresent(MIToken::comma));
27521d5ae102SDimitry Andric
27531d5ae102SDimitry Andric if (expectAndConsume(MIToken::rparen))
27541d5ae102SDimitry Andric return error("shufflemask should be terminated by ')'.");
27551d5ae102SDimitry Andric
2756706b4fc4SDimitry Andric ArrayRef<int> MaskAlloc = MF.allocateShuffleMask(ShufMask);
2757706b4fc4SDimitry Andric Dest = MachineOperand::CreateShuffleMask(MaskAlloc);
27581d5ae102SDimitry Andric return false;
27591d5ae102SDimitry Andric }
27601d5ae102SDimitry Andric
parseDbgInstrRefOperand(MachineOperand & Dest)2761e3b55780SDimitry Andric bool MIParser::parseDbgInstrRefOperand(MachineOperand &Dest) {
2762e3b55780SDimitry Andric assert(Token.is(MIToken::kw_dbg_instr_ref));
2763e3b55780SDimitry Andric
2764e3b55780SDimitry Andric lex();
2765e3b55780SDimitry Andric if (expectAndConsume(MIToken::lparen))
2766e3b55780SDimitry Andric return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2767e3b55780SDimitry Andric
2768e3b55780SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
2769e3b55780SDimitry Andric return error("expected unsigned integer for instruction index");
2770e3b55780SDimitry Andric uint64_t InstrIdx = Token.integerValue().getZExtValue();
2771e3b55780SDimitry Andric assert(InstrIdx <= std::numeric_limits<unsigned>::max() &&
2772e3b55780SDimitry Andric "Instruction reference's instruction index is too large");
2773e3b55780SDimitry Andric lex();
2774e3b55780SDimitry Andric
2775e3b55780SDimitry Andric if (expectAndConsume(MIToken::comma))
2776e3b55780SDimitry Andric return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2777e3b55780SDimitry Andric
2778e3b55780SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
2779e3b55780SDimitry Andric return error("expected unsigned integer for operand index");
2780e3b55780SDimitry Andric uint64_t OpIdx = Token.integerValue().getZExtValue();
2781e3b55780SDimitry Andric assert(OpIdx <= std::numeric_limits<unsigned>::max() &&
2782e3b55780SDimitry Andric "Instruction reference's operand index is too large");
2783e3b55780SDimitry Andric lex();
2784e3b55780SDimitry Andric
2785e3b55780SDimitry Andric if (expectAndConsume(MIToken::rparen))
2786e3b55780SDimitry Andric return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2787e3b55780SDimitry Andric
2788e3b55780SDimitry Andric Dest = MachineOperand::CreateDbgInstrRef(InstrIdx, OpIdx);
2789e3b55780SDimitry Andric return false;
2790e3b55780SDimitry Andric }
2791e3b55780SDimitry Andric
parseTargetIndexOperand(MachineOperand & Dest)2792dd58ef01SDimitry Andric bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
2793dd58ef01SDimitry Andric assert(Token.is(MIToken::kw_target_index));
2794dd58ef01SDimitry Andric lex();
2795dd58ef01SDimitry Andric if (expectAndConsume(MIToken::lparen))
2796dd58ef01SDimitry Andric return true;
2797dd58ef01SDimitry Andric if (Token.isNot(MIToken::Identifier))
2798dd58ef01SDimitry Andric return error("expected the name of the target index");
2799dd58ef01SDimitry Andric int Index = 0;
2800e6d15924SDimitry Andric if (PFS.Target.getTargetIndex(Token.stringValue(), Index))
2801dd58ef01SDimitry Andric return error("use of undefined target index '" + Token.stringValue() + "'");
2802dd58ef01SDimitry Andric lex();
2803dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
2804dd58ef01SDimitry Andric return true;
2805dd58ef01SDimitry Andric Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0);
2806dd58ef01SDimitry Andric if (parseOperandsOffset(Dest))
2807dd58ef01SDimitry Andric return true;
2808dd58ef01SDimitry Andric return false;
2809dd58ef01SDimitry Andric }
2810dd58ef01SDimitry Andric
parseCustomRegisterMaskOperand(MachineOperand & Dest)281171d5a254SDimitry Andric bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) {
281271d5a254SDimitry Andric assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask");
281371d5a254SDimitry Andric lex();
281471d5a254SDimitry Andric if (expectAndConsume(MIToken::lparen))
281571d5a254SDimitry Andric return true;
281671d5a254SDimitry Andric
2817eb11fae6SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
2818145449b1SDimitry Andric do {
2819145449b1SDimitry Andric if (Token.isNot(MIToken::rparen)) {
282071d5a254SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
282171d5a254SDimitry Andric return error("expected a named register");
2822cfca06d7SDimitry Andric Register Reg;
282371d5a254SDimitry Andric if (parseNamedRegister(Reg))
282471d5a254SDimitry Andric return true;
282571d5a254SDimitry Andric lex();
282671d5a254SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32);
282771d5a254SDimitry Andric }
282871d5a254SDimitry Andric
2829145449b1SDimitry Andric // TODO: Report an error if the same register is used more than once.
2830145449b1SDimitry Andric } while (consumeIfPresent(MIToken::comma));
2831145449b1SDimitry Andric
283271d5a254SDimitry Andric if (expectAndConsume(MIToken::rparen))
283371d5a254SDimitry Andric return true;
283471d5a254SDimitry Andric Dest = MachineOperand::CreateRegMask(Mask);
283571d5a254SDimitry Andric return false;
283671d5a254SDimitry Andric }
283771d5a254SDimitry Andric
parseLiveoutRegisterMaskOperand(MachineOperand & Dest)2838dd58ef01SDimitry Andric bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) {
2839dd58ef01SDimitry Andric assert(Token.is(MIToken::kw_liveout));
2840eb11fae6SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
2841dd58ef01SDimitry Andric lex();
2842dd58ef01SDimitry Andric if (expectAndConsume(MIToken::lparen))
2843dd58ef01SDimitry Andric return true;
2844dd58ef01SDimitry Andric while (true) {
2845dd58ef01SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
2846dd58ef01SDimitry Andric return error("expected a named register");
2847cfca06d7SDimitry Andric Register Reg;
2848b915e9e0SDimitry Andric if (parseNamedRegister(Reg))
2849dd58ef01SDimitry Andric return true;
2850dd58ef01SDimitry Andric lex();
2851dd58ef01SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32);
2852dd58ef01SDimitry Andric // TODO: Report an error if the same register is used more than once.
2853dd58ef01SDimitry Andric if (Token.isNot(MIToken::comma))
2854dd58ef01SDimitry Andric break;
2855dd58ef01SDimitry Andric lex();
2856dd58ef01SDimitry Andric }
2857dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
2858dd58ef01SDimitry Andric return true;
2859dd58ef01SDimitry Andric Dest = MachineOperand::CreateRegLiveOut(Mask);
2860dd58ef01SDimitry Andric return false;
2861dd58ef01SDimitry Andric }
2862dd58ef01SDimitry Andric
parseMachineOperand(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,std::optional<unsigned> & TiedDefIdx)2863706b4fc4SDimitry Andric bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
2864706b4fc4SDimitry Andric MachineOperand &Dest,
2865e3b55780SDimitry Andric std::optional<unsigned> &TiedDefIdx) {
28661a82d4c0SDimitry Andric switch (Token.kind()) {
2867ee8648bdSDimitry Andric case MIToken::kw_implicit:
2868ee8648bdSDimitry Andric case MIToken::kw_implicit_define:
2869dd58ef01SDimitry Andric case MIToken::kw_def:
2870ee8648bdSDimitry Andric case MIToken::kw_dead:
2871ee8648bdSDimitry Andric case MIToken::kw_killed:
2872ee8648bdSDimitry Andric case MIToken::kw_undef:
2873dd58ef01SDimitry Andric case MIToken::kw_internal:
2874dd58ef01SDimitry Andric case MIToken::kw_early_clobber:
2875dd58ef01SDimitry Andric case MIToken::kw_debug_use:
2876044eb2f6SDimitry Andric case MIToken::kw_renamable:
28771a82d4c0SDimitry Andric case MIToken::underscore:
28781a82d4c0SDimitry Andric case MIToken::NamedRegister:
2879ee8648bdSDimitry Andric case MIToken::VirtualRegister:
2880eb11fae6SDimitry Andric case MIToken::NamedVirtualRegister:
2881dd58ef01SDimitry Andric return parseRegisterOperand(Dest, TiedDefIdx);
28821a82d4c0SDimitry Andric case MIToken::IntegerLiteral:
28831a82d4c0SDimitry Andric return parseImmediateOperand(Dest);
2884dd58ef01SDimitry Andric case MIToken::kw_half:
2885ac9a064cSDimitry Andric case MIToken::kw_bfloat:
2886dd58ef01SDimitry Andric case MIToken::kw_float:
2887dd58ef01SDimitry Andric case MIToken::kw_double:
2888dd58ef01SDimitry Andric case MIToken::kw_x86_fp80:
2889dd58ef01SDimitry Andric case MIToken::kw_fp128:
2890dd58ef01SDimitry Andric case MIToken::kw_ppc_fp128:
2891dd58ef01SDimitry Andric return parseFPImmediateOperand(Dest);
28921a82d4c0SDimitry Andric case MIToken::MachineBasicBlock:
28931a82d4c0SDimitry Andric return parseMBBOperand(Dest);
2894dd58ef01SDimitry Andric case MIToken::StackObject:
2895dd58ef01SDimitry Andric return parseStackObjectOperand(Dest);
2896dd58ef01SDimitry Andric case MIToken::FixedStackObject:
2897dd58ef01SDimitry Andric return parseFixedStackObjectOperand(Dest);
28981a82d4c0SDimitry Andric case MIToken::GlobalValue:
28991a82d4c0SDimitry Andric case MIToken::NamedGlobalValue:
29001a82d4c0SDimitry Andric return parseGlobalAddressOperand(Dest);
2901dd58ef01SDimitry Andric case MIToken::ConstantPoolItem:
2902dd58ef01SDimitry Andric return parseConstantPoolIndexOperand(Dest);
2903dd58ef01SDimitry Andric case MIToken::JumpTableIndex:
2904dd58ef01SDimitry Andric return parseJumpTableIndexOperand(Dest);
2905dd58ef01SDimitry Andric case MIToken::ExternalSymbol:
2906dd58ef01SDimitry Andric return parseExternalSymbolOperand(Dest);
2907d8e91e46SDimitry Andric case MIToken::MCSymbol:
2908d8e91e46SDimitry Andric return parseMCSymbolOperand(Dest);
290901095a5dSDimitry Andric case MIToken::SubRegisterIndex:
291001095a5dSDimitry Andric return parseSubRegisterIndexOperand(Dest);
2911044eb2f6SDimitry Andric case MIToken::md_diexpr:
2912dd58ef01SDimitry Andric case MIToken::exclaim:
2913dd58ef01SDimitry Andric return parseMetadataOperand(Dest);
2914dd58ef01SDimitry Andric case MIToken::kw_cfi_same_value:
2915dd58ef01SDimitry Andric case MIToken::kw_cfi_offset:
2916044eb2f6SDimitry Andric case MIToken::kw_cfi_rel_offset:
2917dd58ef01SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
2918dd58ef01SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
2919044eb2f6SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
2920044eb2f6SDimitry Andric case MIToken::kw_cfi_escape:
2921dd58ef01SDimitry Andric case MIToken::kw_cfi_def_cfa:
2922344a3780SDimitry Andric case MIToken::kw_cfi_llvm_def_aspace_cfa:
2923044eb2f6SDimitry Andric case MIToken::kw_cfi_register:
2924044eb2f6SDimitry Andric case MIToken::kw_cfi_remember_state:
2925044eb2f6SDimitry Andric case MIToken::kw_cfi_restore:
2926044eb2f6SDimitry Andric case MIToken::kw_cfi_restore_state:
2927044eb2f6SDimitry Andric case MIToken::kw_cfi_undefined:
2928044eb2f6SDimitry Andric case MIToken::kw_cfi_window_save:
2929d8e91e46SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
2930dd58ef01SDimitry Andric return parseCFIOperand(Dest);
2931dd58ef01SDimitry Andric case MIToken::kw_blockaddress:
2932dd58ef01SDimitry Andric return parseBlockAddressOperand(Dest);
2933b915e9e0SDimitry Andric case MIToken::kw_intrinsic:
2934b915e9e0SDimitry Andric return parseIntrinsicOperand(Dest);
2935dd58ef01SDimitry Andric case MIToken::kw_target_index:
2936dd58ef01SDimitry Andric return parseTargetIndexOperand(Dest);
2937dd58ef01SDimitry Andric case MIToken::kw_liveout:
2938dd58ef01SDimitry Andric return parseLiveoutRegisterMaskOperand(Dest);
2939b915e9e0SDimitry Andric case MIToken::kw_floatpred:
2940b915e9e0SDimitry Andric case MIToken::kw_intpred:
2941b915e9e0SDimitry Andric return parsePredicateOperand(Dest);
29421d5ae102SDimitry Andric case MIToken::kw_shufflemask:
29431d5ae102SDimitry Andric return parseShuffleMaskOperand(Dest);
2944e3b55780SDimitry Andric case MIToken::kw_dbg_instr_ref:
2945e3b55780SDimitry Andric return parseDbgInstrRefOperand(Dest);
29461a82d4c0SDimitry Andric case MIToken::Error:
29471a82d4c0SDimitry Andric return true;
29481a82d4c0SDimitry Andric case MIToken::Identifier:
2949e6d15924SDimitry Andric if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) {
29501a82d4c0SDimitry Andric Dest = MachineOperand::CreateRegMask(RegMask);
29511a82d4c0SDimitry Andric lex();
29521a82d4c0SDimitry Andric break;
2953eb11fae6SDimitry Andric } else if (Token.stringValue() == "CustomRegMask") {
295471d5a254SDimitry Andric return parseCustomRegisterMaskOperand(Dest);
2955eb11fae6SDimitry Andric } else
2956eb11fae6SDimitry Andric return parseTypedImmediateOperand(Dest);
2957706b4fc4SDimitry Andric case MIToken::dot: {
2958706b4fc4SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
2959706b4fc4SDimitry Andric if (const auto *Formatter = TII->getMIRFormatter()) {
2960706b4fc4SDimitry Andric return parseTargetImmMnemonic(OpCode, OpIdx, Dest, *Formatter);
2961706b4fc4SDimitry Andric }
2962e3b55780SDimitry Andric [[fallthrough]];
2963706b4fc4SDimitry Andric }
29641a82d4c0SDimitry Andric default:
2965dd58ef01SDimitry Andric // FIXME: Parse the MCSymbol machine operand.
29661a82d4c0SDimitry Andric return error("expected a machine operand");
29671a82d4c0SDimitry Andric }
29681a82d4c0SDimitry Andric return false;
29691a82d4c0SDimitry Andric }
29701a82d4c0SDimitry Andric
parseMachineOperandAndTargetFlags(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,std::optional<unsigned> & TiedDefIdx)2971dd58ef01SDimitry Andric bool MIParser::parseMachineOperandAndTargetFlags(
2972706b4fc4SDimitry Andric const unsigned OpCode, const unsigned OpIdx, MachineOperand &Dest,
2973e3b55780SDimitry Andric std::optional<unsigned> &TiedDefIdx) {
2974dd58ef01SDimitry Andric unsigned TF = 0;
2975dd58ef01SDimitry Andric bool HasTargetFlags = false;
2976dd58ef01SDimitry Andric if (Token.is(MIToken::kw_target_flags)) {
2977dd58ef01SDimitry Andric HasTargetFlags = true;
2978dd58ef01SDimitry Andric lex();
2979dd58ef01SDimitry Andric if (expectAndConsume(MIToken::lparen))
2980dd58ef01SDimitry Andric return true;
2981dd58ef01SDimitry Andric if (Token.isNot(MIToken::Identifier))
2982dd58ef01SDimitry Andric return error("expected the name of the target flag");
2983e6d15924SDimitry Andric if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) {
2984e6d15924SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF))
2985dd58ef01SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
2986dd58ef01SDimitry Andric "'");
2987dd58ef01SDimitry Andric }
2988dd58ef01SDimitry Andric lex();
2989dd58ef01SDimitry Andric while (Token.is(MIToken::comma)) {
2990dd58ef01SDimitry Andric lex();
2991dd58ef01SDimitry Andric if (Token.isNot(MIToken::Identifier))
2992dd58ef01SDimitry Andric return error("expected the name of the target flag");
2993dd58ef01SDimitry Andric unsigned BitFlag = 0;
2994e6d15924SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag))
2995dd58ef01SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
2996dd58ef01SDimitry Andric "'");
2997dd58ef01SDimitry Andric // TODO: Report an error when using a duplicate bit target flag.
2998dd58ef01SDimitry Andric TF |= BitFlag;
2999dd58ef01SDimitry Andric lex();
3000dd58ef01SDimitry Andric }
3001dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
3002dd58ef01SDimitry Andric return true;
3003dd58ef01SDimitry Andric }
3004dd58ef01SDimitry Andric auto Loc = Token.location();
3005706b4fc4SDimitry Andric if (parseMachineOperand(OpCode, OpIdx, Dest, TiedDefIdx))
3006dd58ef01SDimitry Andric return true;
3007dd58ef01SDimitry Andric if (!HasTargetFlags)
3008dd58ef01SDimitry Andric return false;
3009dd58ef01SDimitry Andric if (Dest.isReg())
3010dd58ef01SDimitry Andric return error(Loc, "register operands can't have target flags");
3011dd58ef01SDimitry Andric Dest.setTargetFlags(TF);
3012dd58ef01SDimitry Andric return false;
3013dd58ef01SDimitry Andric }
3014dd58ef01SDimitry Andric
parseOffset(int64_t & Offset)3015dd58ef01SDimitry Andric bool MIParser::parseOffset(int64_t &Offset) {
3016dd58ef01SDimitry Andric if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus))
3017dd58ef01SDimitry Andric return false;
3018dd58ef01SDimitry Andric StringRef Sign = Token.range();
3019dd58ef01SDimitry Andric bool IsNegative = Token.is(MIToken::minus);
3020dd58ef01SDimitry Andric lex();
3021dd58ef01SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
3022dd58ef01SDimitry Andric return error("expected an integer literal after '" + Sign + "'");
30237fa27ce4SDimitry Andric if (Token.integerValue().getSignificantBits() > 64)
3024dd58ef01SDimitry Andric return error("expected 64-bit integer (too large)");
3025dd58ef01SDimitry Andric Offset = Token.integerValue().getExtValue();
3026dd58ef01SDimitry Andric if (IsNegative)
3027dd58ef01SDimitry Andric Offset = -Offset;
3028dd58ef01SDimitry Andric lex();
3029dd58ef01SDimitry Andric return false;
3030dd58ef01SDimitry Andric }
3031dd58ef01SDimitry Andric
parseIRBlockAddressTaken(BasicBlock * & BB)3032e3b55780SDimitry Andric bool MIParser::parseIRBlockAddressTaken(BasicBlock *&BB) {
3033e3b55780SDimitry Andric assert(Token.is(MIToken::kw_ir_block_address_taken));
3034e3b55780SDimitry Andric lex();
3035e3b55780SDimitry Andric if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
3036e3b55780SDimitry Andric return error("expected basic block after 'ir_block_address_taken'");
3037e3b55780SDimitry Andric
3038e3b55780SDimitry Andric if (parseIRBlock(BB, MF.getFunction()))
3039e3b55780SDimitry Andric return true;
3040e3b55780SDimitry Andric
3041e3b55780SDimitry Andric lex();
3042e3b55780SDimitry Andric return false;
3043e3b55780SDimitry Andric }
3044e3b55780SDimitry Andric
parseAlignment(uint64_t & Alignment)3045c0981da4SDimitry Andric bool MIParser::parseAlignment(uint64_t &Alignment) {
3046b60736ecSDimitry Andric assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
3047dd58ef01SDimitry Andric lex();
3048dd58ef01SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
3049dd58ef01SDimitry Andric return error("expected an integer literal after 'align'");
3050c0981da4SDimitry Andric if (getUint64(Alignment))
3051dd58ef01SDimitry Andric return true;
3052dd58ef01SDimitry Andric lex();
3053e6d15924SDimitry Andric
3054c0981da4SDimitry Andric if (!isPowerOf2_64(Alignment))
3055e6d15924SDimitry Andric return error("expected a power-of-2 literal after 'align'");
3056e6d15924SDimitry Andric
3057dd58ef01SDimitry Andric return false;
3058dd58ef01SDimitry Andric }
3059dd58ef01SDimitry Andric
parseAddrspace(unsigned & Addrspace)3060eb11fae6SDimitry Andric bool MIParser::parseAddrspace(unsigned &Addrspace) {
3061eb11fae6SDimitry Andric assert(Token.is(MIToken::kw_addrspace));
3062eb11fae6SDimitry Andric lex();
3063eb11fae6SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
3064eb11fae6SDimitry Andric return error("expected an integer literal after 'addrspace'");
3065eb11fae6SDimitry Andric if (getUnsigned(Addrspace))
3066eb11fae6SDimitry Andric return true;
3067eb11fae6SDimitry Andric lex();
3068eb11fae6SDimitry Andric return false;
3069eb11fae6SDimitry Andric }
3070eb11fae6SDimitry Andric
parseOperandsOffset(MachineOperand & Op)3071dd58ef01SDimitry Andric bool MIParser::parseOperandsOffset(MachineOperand &Op) {
3072dd58ef01SDimitry Andric int64_t Offset = 0;
3073dd58ef01SDimitry Andric if (parseOffset(Offset))
3074dd58ef01SDimitry Andric return true;
3075dd58ef01SDimitry Andric Op.setOffset(Offset);
3076dd58ef01SDimitry Andric return false;
3077dd58ef01SDimitry Andric }
3078dd58ef01SDimitry Andric
parseIRValue(const MIToken & Token,PerFunctionMIParsingState & PFS,const Value * & V,ErrorCallbackType ErrCB)3079706b4fc4SDimitry Andric static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS,
3080706b4fc4SDimitry Andric const Value *&V, ErrorCallbackType ErrCB) {
3081dd58ef01SDimitry Andric switch (Token.kind()) {
3082dd58ef01SDimitry Andric case MIToken::NamedIRValue: {
3083706b4fc4SDimitry Andric V = PFS.MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue());
3084dd58ef01SDimitry Andric break;
3085dd58ef01SDimitry Andric }
3086dd58ef01SDimitry Andric case MIToken::IRValue: {
3087dd58ef01SDimitry Andric unsigned SlotNumber = 0;
3088706b4fc4SDimitry Andric if (getUnsigned(Token, SlotNumber, ErrCB))
3089dd58ef01SDimitry Andric return true;
3090706b4fc4SDimitry Andric V = PFS.getIRValue(SlotNumber);
3091dd58ef01SDimitry Andric break;
3092dd58ef01SDimitry Andric }
3093dd58ef01SDimitry Andric case MIToken::NamedGlobalValue:
3094dd58ef01SDimitry Andric case MIToken::GlobalValue: {
3095dd58ef01SDimitry Andric GlobalValue *GV = nullptr;
3096706b4fc4SDimitry Andric if (parseGlobalValue(Token, PFS, GV, ErrCB))
3097dd58ef01SDimitry Andric return true;
3098dd58ef01SDimitry Andric V = GV;
3099dd58ef01SDimitry Andric break;
3100dd58ef01SDimitry Andric }
3101dd58ef01SDimitry Andric case MIToken::QuotedIRValue: {
3102dd58ef01SDimitry Andric const Constant *C = nullptr;
3103706b4fc4SDimitry Andric if (parseIRConstant(Token.location(), Token.stringValue(), PFS, C, ErrCB))
3104dd58ef01SDimitry Andric return true;
3105dd58ef01SDimitry Andric V = C;
3106dd58ef01SDimitry Andric break;
3107dd58ef01SDimitry Andric }
3108344a3780SDimitry Andric case MIToken::kw_unknown_address:
3109344a3780SDimitry Andric V = nullptr;
3110344a3780SDimitry Andric return false;
3111dd58ef01SDimitry Andric default:
3112dd58ef01SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
3113dd58ef01SDimitry Andric }
3114dd58ef01SDimitry Andric if (!V)
3115706b4fc4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined IR value '") + Token.range() + "'");
3116dd58ef01SDimitry Andric return false;
3117dd58ef01SDimitry Andric }
3118dd58ef01SDimitry Andric
parseIRValue(const Value * & V)3119706b4fc4SDimitry Andric bool MIParser::parseIRValue(const Value *&V) {
3120706b4fc4SDimitry Andric return ::parseIRValue(
3121706b4fc4SDimitry Andric Token, PFS, V, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
3122706b4fc4SDimitry Andric return error(Loc, Msg);
3123706b4fc4SDimitry Andric });
3124706b4fc4SDimitry Andric }
3125706b4fc4SDimitry Andric
getUint64(uint64_t & Result)3126dd58ef01SDimitry Andric bool MIParser::getUint64(uint64_t &Result) {
3127b915e9e0SDimitry Andric if (Token.hasIntegerValue()) {
3128dd58ef01SDimitry Andric if (Token.integerValue().getActiveBits() > 64)
3129dd58ef01SDimitry Andric return error("expected 64-bit integer (too large)");
3130dd58ef01SDimitry Andric Result = Token.integerValue().getZExtValue();
3131dd58ef01SDimitry Andric return false;
3132dd58ef01SDimitry Andric }
3133b915e9e0SDimitry Andric if (Token.is(MIToken::HexLiteral)) {
3134b915e9e0SDimitry Andric APInt A;
3135b915e9e0SDimitry Andric if (getHexUint(A))
3136b915e9e0SDimitry Andric return true;
3137b915e9e0SDimitry Andric if (A.getBitWidth() > 64)
3138b915e9e0SDimitry Andric return error("expected 64-bit integer (too large)");
3139b915e9e0SDimitry Andric Result = A.getZExtValue();
3140b915e9e0SDimitry Andric return false;
3141b915e9e0SDimitry Andric }
3142b915e9e0SDimitry Andric return true;
3143b915e9e0SDimitry Andric }
3144b915e9e0SDimitry Andric
getHexUint(APInt & Result)3145b915e9e0SDimitry Andric bool MIParser::getHexUint(APInt &Result) {
3146706b4fc4SDimitry Andric return ::getHexUint(Token, Result);
3147b915e9e0SDimitry Andric }
3148dd58ef01SDimitry Andric
parseMemoryOperandFlag(MachineMemOperand::Flags & Flags)314901095a5dSDimitry Andric bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
315001095a5dSDimitry Andric const auto OldFlags = Flags;
3151dd58ef01SDimitry Andric switch (Token.kind()) {
3152dd58ef01SDimitry Andric case MIToken::kw_volatile:
3153dd58ef01SDimitry Andric Flags |= MachineMemOperand::MOVolatile;
3154dd58ef01SDimitry Andric break;
3155dd58ef01SDimitry Andric case MIToken::kw_non_temporal:
3156dd58ef01SDimitry Andric Flags |= MachineMemOperand::MONonTemporal;
3157dd58ef01SDimitry Andric break;
3158b915e9e0SDimitry Andric case MIToken::kw_dereferenceable:
3159b915e9e0SDimitry Andric Flags |= MachineMemOperand::MODereferenceable;
3160b915e9e0SDimitry Andric break;
3161dd58ef01SDimitry Andric case MIToken::kw_invariant:
3162dd58ef01SDimitry Andric Flags |= MachineMemOperand::MOInvariant;
3163dd58ef01SDimitry Andric break;
3164ca089b24SDimitry Andric case MIToken::StringConstant: {
3165ca089b24SDimitry Andric MachineMemOperand::Flags TF;
3166e6d15924SDimitry Andric if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF))
3167ca089b24SDimitry Andric return error("use of undefined target MMO flag '" + Token.stringValue() +
3168ca089b24SDimitry Andric "'");
3169ca089b24SDimitry Andric Flags |= TF;
3170ca089b24SDimitry Andric break;
3171ca089b24SDimitry Andric }
3172dd58ef01SDimitry Andric default:
3173dd58ef01SDimitry Andric llvm_unreachable("The current token should be a memory operand flag");
3174dd58ef01SDimitry Andric }
3175dd58ef01SDimitry Andric if (OldFlags == Flags)
3176dd58ef01SDimitry Andric // We know that the same flag is specified more than once when the flags
3177dd58ef01SDimitry Andric // weren't modified.
3178dd58ef01SDimitry Andric return error("duplicate '" + Token.stringValue() + "' memory operand flag");
3179dd58ef01SDimitry Andric lex();
3180dd58ef01SDimitry Andric return false;
3181dd58ef01SDimitry Andric }
3182dd58ef01SDimitry Andric
parseMemoryPseudoSourceValue(const PseudoSourceValue * & PSV)3183dd58ef01SDimitry Andric bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) {
3184dd58ef01SDimitry Andric switch (Token.kind()) {
3185dd58ef01SDimitry Andric case MIToken::kw_stack:
3186dd58ef01SDimitry Andric PSV = MF.getPSVManager().getStack();
3187dd58ef01SDimitry Andric break;
3188dd58ef01SDimitry Andric case MIToken::kw_got:
3189dd58ef01SDimitry Andric PSV = MF.getPSVManager().getGOT();
3190dd58ef01SDimitry Andric break;
3191dd58ef01SDimitry Andric case MIToken::kw_jump_table:
3192dd58ef01SDimitry Andric PSV = MF.getPSVManager().getJumpTable();
3193dd58ef01SDimitry Andric break;
3194dd58ef01SDimitry Andric case MIToken::kw_constant_pool:
3195dd58ef01SDimitry Andric PSV = MF.getPSVManager().getConstantPool();
3196dd58ef01SDimitry Andric break;
3197dd58ef01SDimitry Andric case MIToken::FixedStackObject: {
3198dd58ef01SDimitry Andric int FI;
3199dd58ef01SDimitry Andric if (parseFixedStackFrameIndex(FI))
3200dd58ef01SDimitry Andric return true;
3201dd58ef01SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
3202dd58ef01SDimitry Andric // The token was already consumed, so use return here instead of break.
3203dd58ef01SDimitry Andric return false;
3204dd58ef01SDimitry Andric }
320501095a5dSDimitry Andric case MIToken::StackObject: {
320601095a5dSDimitry Andric int FI;
320701095a5dSDimitry Andric if (parseStackFrameIndex(FI))
320801095a5dSDimitry Andric return true;
320901095a5dSDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
321001095a5dSDimitry Andric // The token was already consumed, so use return here instead of break.
321101095a5dSDimitry Andric return false;
321201095a5dSDimitry Andric }
32137ab83427SDimitry Andric case MIToken::kw_call_entry:
3214dd58ef01SDimitry Andric lex();
3215dd58ef01SDimitry Andric switch (Token.kind()) {
3216dd58ef01SDimitry Andric case MIToken::GlobalValue:
3217dd58ef01SDimitry Andric case MIToken::NamedGlobalValue: {
3218dd58ef01SDimitry Andric GlobalValue *GV = nullptr;
3219dd58ef01SDimitry Andric if (parseGlobalValue(GV))
3220dd58ef01SDimitry Andric return true;
3221dd58ef01SDimitry Andric PSV = MF.getPSVManager().getGlobalValueCallEntry(GV);
3222dd58ef01SDimitry Andric break;
3223dd58ef01SDimitry Andric }
3224dd58ef01SDimitry Andric case MIToken::ExternalSymbol:
3225dd58ef01SDimitry Andric PSV = MF.getPSVManager().getExternalSymbolCallEntry(
3226dd58ef01SDimitry Andric MF.createExternalSymbolName(Token.stringValue()));
3227dd58ef01SDimitry Andric break;
3228dd58ef01SDimitry Andric default:
3229dd58ef01SDimitry Andric return error(
3230dd58ef01SDimitry Andric "expected a global value or an external symbol after 'call-entry'");
3231dd58ef01SDimitry Andric }
3232dd58ef01SDimitry Andric break;
3233706b4fc4SDimitry Andric case MIToken::kw_custom: {
3234706b4fc4SDimitry Andric lex();
3235706b4fc4SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
3236706b4fc4SDimitry Andric if (const auto *Formatter = TII->getMIRFormatter()) {
3237706b4fc4SDimitry Andric if (Formatter->parseCustomPseudoSourceValue(
3238706b4fc4SDimitry Andric Token.stringValue(), MF, PFS, PSV,
3239706b4fc4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
3240706b4fc4SDimitry Andric return error(Loc, Msg);
3241706b4fc4SDimitry Andric }))
3242706b4fc4SDimitry Andric return true;
3243706b4fc4SDimitry Andric } else
3244706b4fc4SDimitry Andric return error("unable to parse target custom pseudo source value");
3245706b4fc4SDimitry Andric break;
3246706b4fc4SDimitry Andric }
3247dd58ef01SDimitry Andric default:
3248dd58ef01SDimitry Andric llvm_unreachable("The current token should be pseudo source value");
3249dd58ef01SDimitry Andric }
3250dd58ef01SDimitry Andric lex();
3251dd58ef01SDimitry Andric return false;
3252dd58ef01SDimitry Andric }
3253dd58ef01SDimitry Andric
parseMachinePointerInfo(MachinePointerInfo & Dest)3254dd58ef01SDimitry Andric bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
3255dd58ef01SDimitry Andric if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) ||
3256dd58ef01SDimitry Andric Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) ||
325701095a5dSDimitry Andric Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) ||
3258706b4fc4SDimitry Andric Token.is(MIToken::kw_call_entry) || Token.is(MIToken::kw_custom)) {
3259dd58ef01SDimitry Andric const PseudoSourceValue *PSV = nullptr;
3260dd58ef01SDimitry Andric if (parseMemoryPseudoSourceValue(PSV))
3261dd58ef01SDimitry Andric return true;
3262dd58ef01SDimitry Andric int64_t Offset = 0;
3263dd58ef01SDimitry Andric if (parseOffset(Offset))
3264dd58ef01SDimitry Andric return true;
3265dd58ef01SDimitry Andric Dest = MachinePointerInfo(PSV, Offset);
3266dd58ef01SDimitry Andric return false;
3267dd58ef01SDimitry Andric }
3268dd58ef01SDimitry Andric if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) &&
3269dd58ef01SDimitry Andric Token.isNot(MIToken::GlobalValue) &&
3270dd58ef01SDimitry Andric Token.isNot(MIToken::NamedGlobalValue) &&
3271344a3780SDimitry Andric Token.isNot(MIToken::QuotedIRValue) &&
3272344a3780SDimitry Andric Token.isNot(MIToken::kw_unknown_address))
3273dd58ef01SDimitry Andric return error("expected an IR value reference");
3274dd58ef01SDimitry Andric const Value *V = nullptr;
3275dd58ef01SDimitry Andric if (parseIRValue(V))
3276dd58ef01SDimitry Andric return true;
3277344a3780SDimitry Andric if (V && !V->getType()->isPointerTy())
3278dd58ef01SDimitry Andric return error("expected a pointer IR value");
3279dd58ef01SDimitry Andric lex();
3280dd58ef01SDimitry Andric int64_t Offset = 0;
3281dd58ef01SDimitry Andric if (parseOffset(Offset))
3282dd58ef01SDimitry Andric return true;
3283dd58ef01SDimitry Andric Dest = MachinePointerInfo(V, Offset);
3284dd58ef01SDimitry Andric return false;
3285dd58ef01SDimitry Andric }
3286dd58ef01SDimitry Andric
parseOptionalScope(LLVMContext & Context,SyncScope::ID & SSID)3287ca089b24SDimitry Andric bool MIParser::parseOptionalScope(LLVMContext &Context,
3288ca089b24SDimitry Andric SyncScope::ID &SSID) {
3289ca089b24SDimitry Andric SSID = SyncScope::System;
3290ca089b24SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") {
3291ca089b24SDimitry Andric lex();
3292ca089b24SDimitry Andric if (expectAndConsume(MIToken::lparen))
3293ca089b24SDimitry Andric return error("expected '(' in syncscope");
3294ca089b24SDimitry Andric
3295ca089b24SDimitry Andric std::string SSN;
3296ca089b24SDimitry Andric if (parseStringConstant(SSN))
3297ca089b24SDimitry Andric return true;
3298ca089b24SDimitry Andric
3299ca089b24SDimitry Andric SSID = Context.getOrInsertSyncScopeID(SSN);
3300ca089b24SDimitry Andric if (expectAndConsume(MIToken::rparen))
3301ca089b24SDimitry Andric return error("expected ')' in syncscope");
3302ca089b24SDimitry Andric }
3303ca089b24SDimitry Andric
3304ca089b24SDimitry Andric return false;
3305ca089b24SDimitry Andric }
3306ca089b24SDimitry Andric
parseOptionalAtomicOrdering(AtomicOrdering & Order)330771d5a254SDimitry Andric bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) {
330871d5a254SDimitry Andric Order = AtomicOrdering::NotAtomic;
330971d5a254SDimitry Andric if (Token.isNot(MIToken::Identifier))
331071d5a254SDimitry Andric return false;
331171d5a254SDimitry Andric
331271d5a254SDimitry Andric Order = StringSwitch<AtomicOrdering>(Token.stringValue())
331371d5a254SDimitry Andric .Case("unordered", AtomicOrdering::Unordered)
331471d5a254SDimitry Andric .Case("monotonic", AtomicOrdering::Monotonic)
331571d5a254SDimitry Andric .Case("acquire", AtomicOrdering::Acquire)
331671d5a254SDimitry Andric .Case("release", AtomicOrdering::Release)
331771d5a254SDimitry Andric .Case("acq_rel", AtomicOrdering::AcquireRelease)
331871d5a254SDimitry Andric .Case("seq_cst", AtomicOrdering::SequentiallyConsistent)
331971d5a254SDimitry Andric .Default(AtomicOrdering::NotAtomic);
332071d5a254SDimitry Andric
332171d5a254SDimitry Andric if (Order != AtomicOrdering::NotAtomic) {
332271d5a254SDimitry Andric lex();
332371d5a254SDimitry Andric return false;
332471d5a254SDimitry Andric }
332571d5a254SDimitry Andric
3326d8e91e46SDimitry Andric return error("expected an atomic scope, ordering or a size specification");
332771d5a254SDimitry Andric }
332871d5a254SDimitry Andric
parseMachineMemoryOperand(MachineMemOperand * & Dest)3329dd58ef01SDimitry Andric bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
3330dd58ef01SDimitry Andric if (expectAndConsume(MIToken::lparen))
3331dd58ef01SDimitry Andric return true;
333201095a5dSDimitry Andric MachineMemOperand::Flags Flags = MachineMemOperand::MONone;
3333dd58ef01SDimitry Andric while (Token.isMemoryOperandFlag()) {
3334dd58ef01SDimitry Andric if (parseMemoryOperandFlag(Flags))
3335dd58ef01SDimitry Andric return true;
3336dd58ef01SDimitry Andric }
3337dd58ef01SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
3338dd58ef01SDimitry Andric (Token.stringValue() != "load" && Token.stringValue() != "store"))
3339dd58ef01SDimitry Andric return error("expected 'load' or 'store' memory operation");
3340dd58ef01SDimitry Andric if (Token.stringValue() == "load")
3341dd58ef01SDimitry Andric Flags |= MachineMemOperand::MOLoad;
3342dd58ef01SDimitry Andric else
3343dd58ef01SDimitry Andric Flags |= MachineMemOperand::MOStore;
3344dd58ef01SDimitry Andric lex();
3345dd58ef01SDimitry Andric
3346044eb2f6SDimitry Andric // Optional 'store' for operands that both load and store.
3347044eb2f6SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") {
3348044eb2f6SDimitry Andric Flags |= MachineMemOperand::MOStore;
3349044eb2f6SDimitry Andric lex();
3350044eb2f6SDimitry Andric }
3351044eb2f6SDimitry Andric
3352ca089b24SDimitry Andric // Optional synchronization scope.
3353ca089b24SDimitry Andric SyncScope::ID SSID;
3354044eb2f6SDimitry Andric if (parseOptionalScope(MF.getFunction().getContext(), SSID))
3355ca089b24SDimitry Andric return true;
335671d5a254SDimitry Andric
335771d5a254SDimitry Andric // Up to two atomic orderings (cmpxchg provides guarantees on failure).
335871d5a254SDimitry Andric AtomicOrdering Order, FailureOrder;
335971d5a254SDimitry Andric if (parseOptionalAtomicOrdering(Order))
336071d5a254SDimitry Andric return true;
336171d5a254SDimitry Andric
336271d5a254SDimitry Andric if (parseOptionalAtomicOrdering(FailureOrder))
336371d5a254SDimitry Andric return true;
336471d5a254SDimitry Andric
3365344a3780SDimitry Andric LLT MemoryType;
3366d8e91e46SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
3367344a3780SDimitry Andric Token.isNot(MIToken::kw_unknown_size) &&
3368344a3780SDimitry Andric Token.isNot(MIToken::lparen))
3369344a3780SDimitry Andric return error("expected memory LLT, the size integer literal or 'unknown-size' after "
3370d8e91e46SDimitry Andric "memory operation");
3371344a3780SDimitry Andric
3372344a3780SDimitry Andric uint64_t Size = MemoryLocation::UnknownSize;
3373d8e91e46SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
3374dd58ef01SDimitry Andric if (getUint64(Size))
3375dd58ef01SDimitry Andric return true;
3376344a3780SDimitry Andric
3377344a3780SDimitry Andric // Convert from bytes to bits for storage.
3378344a3780SDimitry Andric MemoryType = LLT::scalar(8 * Size);
3379344a3780SDimitry Andric lex();
3380d8e91e46SDimitry Andric } else if (Token.is(MIToken::kw_unknown_size)) {
3381d8e91e46SDimitry Andric Size = MemoryLocation::UnknownSize;
3382dd58ef01SDimitry Andric lex();
3383344a3780SDimitry Andric } else {
3384344a3780SDimitry Andric if (expectAndConsume(MIToken::lparen))
3385344a3780SDimitry Andric return true;
3386344a3780SDimitry Andric if (parseLowLevelType(Token.location(), MemoryType))
3387344a3780SDimitry Andric return true;
3388344a3780SDimitry Andric if (expectAndConsume(MIToken::rparen))
3389344a3780SDimitry Andric return true;
3390344a3780SDimitry Andric
3391344a3780SDimitry Andric Size = MemoryType.getSizeInBytes();
3392344a3780SDimitry Andric }
3393dd58ef01SDimitry Andric
339401095a5dSDimitry Andric MachinePointerInfo Ptr = MachinePointerInfo();
339501095a5dSDimitry Andric if (Token.is(MIToken::Identifier)) {
3396044eb2f6SDimitry Andric const char *Word =
3397044eb2f6SDimitry Andric ((Flags & MachineMemOperand::MOLoad) &&
3398044eb2f6SDimitry Andric (Flags & MachineMemOperand::MOStore))
3399044eb2f6SDimitry Andric ? "on"
3400044eb2f6SDimitry Andric : Flags & MachineMemOperand::MOLoad ? "from" : "into";
340101095a5dSDimitry Andric if (Token.stringValue() != Word)
3402dd58ef01SDimitry Andric return error(Twine("expected '") + Word + "'");
3403dd58ef01SDimitry Andric lex();
3404dd58ef01SDimitry Andric
3405dd58ef01SDimitry Andric if (parseMachinePointerInfo(Ptr))
3406dd58ef01SDimitry Andric return true;
340701095a5dSDimitry Andric }
3408c0981da4SDimitry Andric uint64_t BaseAlignment =
3409344a3780SDimitry Andric (Size != MemoryLocation::UnknownSize ? PowerOf2Ceil(Size) : 1);
3410dd58ef01SDimitry Andric AAMDNodes AAInfo;
3411dd58ef01SDimitry Andric MDNode *Range = nullptr;
3412dd58ef01SDimitry Andric while (consumeIfPresent(MIToken::comma)) {
3413dd58ef01SDimitry Andric switch (Token.kind()) {
3414145449b1SDimitry Andric case MIToken::kw_align: {
3415b60736ecSDimitry Andric // align is printed if it is different than size.
3416145449b1SDimitry Andric uint64_t Alignment;
3417145449b1SDimitry Andric if (parseAlignment(Alignment))
3418b60736ecSDimitry Andric return true;
3419145449b1SDimitry Andric if (Ptr.Offset & (Alignment - 1)) {
3420145449b1SDimitry Andric // MachineMemOperand::getAlign never returns a value greater than the
3421145449b1SDimitry Andric // alignment of offset, so this just guards against hand-written MIR
3422145449b1SDimitry Andric // that specifies a large "align" value when it should probably use
3423145449b1SDimitry Andric // "basealign" instead.
3424145449b1SDimitry Andric return error("specified alignment is more aligned than offset");
3425145449b1SDimitry Andric }
3426145449b1SDimitry Andric BaseAlignment = Alignment;
3427b60736ecSDimitry Andric break;
3428145449b1SDimitry Andric }
3429b60736ecSDimitry Andric case MIToken::kw_basealign:
3430b60736ecSDimitry Andric // basealign is printed if it is different than align.
3431dd58ef01SDimitry Andric if (parseAlignment(BaseAlignment))
3432dd58ef01SDimitry Andric return true;
3433dd58ef01SDimitry Andric break;
3434eb11fae6SDimitry Andric case MIToken::kw_addrspace:
3435eb11fae6SDimitry Andric if (parseAddrspace(Ptr.AddrSpace))
3436eb11fae6SDimitry Andric return true;
3437eb11fae6SDimitry Andric break;
3438dd58ef01SDimitry Andric case MIToken::md_tbaa:
3439dd58ef01SDimitry Andric lex();
3440dd58ef01SDimitry Andric if (parseMDNode(AAInfo.TBAA))
3441dd58ef01SDimitry Andric return true;
3442dd58ef01SDimitry Andric break;
3443dd58ef01SDimitry Andric case MIToken::md_alias_scope:
3444dd58ef01SDimitry Andric lex();
3445dd58ef01SDimitry Andric if (parseMDNode(AAInfo.Scope))
3446dd58ef01SDimitry Andric return true;
3447dd58ef01SDimitry Andric break;
3448dd58ef01SDimitry Andric case MIToken::md_noalias:
3449dd58ef01SDimitry Andric lex();
3450dd58ef01SDimitry Andric if (parseMDNode(AAInfo.NoAlias))
3451dd58ef01SDimitry Andric return true;
3452dd58ef01SDimitry Andric break;
3453dd58ef01SDimitry Andric case MIToken::md_range:
3454dd58ef01SDimitry Andric lex();
3455dd58ef01SDimitry Andric if (parseMDNode(Range))
3456dd58ef01SDimitry Andric return true;
3457dd58ef01SDimitry Andric break;
3458dd58ef01SDimitry Andric // TODO: Report an error on duplicate metadata nodes.
3459dd58ef01SDimitry Andric default:
3460dd58ef01SDimitry Andric return error("expected 'align' or '!tbaa' or '!alias.scope' or "
3461dd58ef01SDimitry Andric "'!noalias' or '!range'");
3462dd58ef01SDimitry Andric }
3463dd58ef01SDimitry Andric }
3464dd58ef01SDimitry Andric if (expectAndConsume(MIToken::rparen))
3465dd58ef01SDimitry Andric return true;
3466344a3780SDimitry Andric Dest = MF.getMachineMemOperand(Ptr, Flags, MemoryType, Align(BaseAlignment),
3467344a3780SDimitry Andric AAInfo, Range, SSID, Order, FailureOrder);
3468dd58ef01SDimitry Andric return false;
3469dd58ef01SDimitry Andric }
3470dd58ef01SDimitry Andric
parsePreOrPostInstrSymbol(MCSymbol * & Symbol)3471d8e91e46SDimitry Andric bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
3472d8e91e46SDimitry Andric assert((Token.is(MIToken::kw_pre_instr_symbol) ||
3473d8e91e46SDimitry Andric Token.is(MIToken::kw_post_instr_symbol)) &&
3474d8e91e46SDimitry Andric "Invalid token for a pre- post-instruction symbol!");
3475d8e91e46SDimitry Andric lex();
3476d8e91e46SDimitry Andric if (Token.isNot(MIToken::MCSymbol))
3477d8e91e46SDimitry Andric return error("expected a symbol after 'pre-instr-symbol'");
3478d8e91e46SDimitry Andric Symbol = getOrCreateMCSymbol(Token.stringValue());
3479d8e91e46SDimitry Andric lex();
3480d8e91e46SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3481d8e91e46SDimitry Andric Token.is(MIToken::lbrace))
3482d8e91e46SDimitry Andric return false;
3483d8e91e46SDimitry Andric if (Token.isNot(MIToken::comma))
3484d8e91e46SDimitry Andric return error("expected ',' before the next machine operand");
3485d8e91e46SDimitry Andric lex();
3486d8e91e46SDimitry Andric return false;
3487d8e91e46SDimitry Andric }
3488d8e91e46SDimitry Andric
parseHeapAllocMarker(MDNode * & Node)3489706b4fc4SDimitry Andric bool MIParser::parseHeapAllocMarker(MDNode *&Node) {
3490706b4fc4SDimitry Andric assert(Token.is(MIToken::kw_heap_alloc_marker) &&
3491706b4fc4SDimitry Andric "Invalid token for a heap alloc marker!");
3492706b4fc4SDimitry Andric lex();
34937fa27ce4SDimitry Andric if (parseMDNode(Node))
34947fa27ce4SDimitry Andric return true;
3495706b4fc4SDimitry Andric if (!Node)
3496706b4fc4SDimitry Andric return error("expected a MDNode after 'heap-alloc-marker'");
3497706b4fc4SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3498706b4fc4SDimitry Andric Token.is(MIToken::lbrace))
3499706b4fc4SDimitry Andric return false;
3500706b4fc4SDimitry Andric if (Token.isNot(MIToken::comma))
3501706b4fc4SDimitry Andric return error("expected ',' before the next machine operand");
3502706b4fc4SDimitry Andric lex();
3503706b4fc4SDimitry Andric return false;
3504706b4fc4SDimitry Andric }
3505706b4fc4SDimitry Andric
parsePCSections(MDNode * & Node)3506e3b55780SDimitry Andric bool MIParser::parsePCSections(MDNode *&Node) {
3507e3b55780SDimitry Andric assert(Token.is(MIToken::kw_pcsections) &&
3508e3b55780SDimitry Andric "Invalid token for a PC sections!");
3509e3b55780SDimitry Andric lex();
35107fa27ce4SDimitry Andric if (parseMDNode(Node))
35117fa27ce4SDimitry Andric return true;
3512e3b55780SDimitry Andric if (!Node)
3513e3b55780SDimitry Andric return error("expected a MDNode after 'pcsections'");
3514e3b55780SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3515e3b55780SDimitry Andric Token.is(MIToken::lbrace))
3516e3b55780SDimitry Andric return false;
3517e3b55780SDimitry Andric if (Token.isNot(MIToken::comma))
3518e3b55780SDimitry Andric return error("expected ',' before the next machine operand");
3519e3b55780SDimitry Andric lex();
3520e3b55780SDimitry Andric return false;
3521e3b55780SDimitry Andric }
3522e3b55780SDimitry Andric
initSlots2BasicBlocks(const Function & F,DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)3523dd58ef01SDimitry Andric static void initSlots2BasicBlocks(
3524dd58ef01SDimitry Andric const Function &F,
3525dd58ef01SDimitry Andric DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
3526dd58ef01SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
3527dd58ef01SDimitry Andric MST.incorporateFunction(F);
35284b4fe385SDimitry Andric for (const auto &BB : F) {
3529dd58ef01SDimitry Andric if (BB.hasName())
3530dd58ef01SDimitry Andric continue;
3531dd58ef01SDimitry Andric int Slot = MST.getLocalSlot(&BB);
3532dd58ef01SDimitry Andric if (Slot == -1)
3533dd58ef01SDimitry Andric continue;
3534dd58ef01SDimitry Andric Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB));
3535dd58ef01SDimitry Andric }
3536dd58ef01SDimitry Andric }
3537dd58ef01SDimitry Andric
getIRBlockFromSlot(unsigned Slot,const DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)3538dd58ef01SDimitry Andric static const BasicBlock *getIRBlockFromSlot(
3539dd58ef01SDimitry Andric unsigned Slot,
3540dd58ef01SDimitry Andric const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
3541b60736ecSDimitry Andric return Slots2BasicBlocks.lookup(Slot);
3542dd58ef01SDimitry Andric }
3543dd58ef01SDimitry Andric
getIRBlock(unsigned Slot)3544dd58ef01SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot) {
3545dd58ef01SDimitry Andric if (Slots2BasicBlocks.empty())
3546044eb2f6SDimitry Andric initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks);
3547dd58ef01SDimitry Andric return getIRBlockFromSlot(Slot, Slots2BasicBlocks);
3548dd58ef01SDimitry Andric }
3549dd58ef01SDimitry Andric
getIRBlock(unsigned Slot,const Function & F)3550dd58ef01SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) {
3551044eb2f6SDimitry Andric if (&F == &MF.getFunction())
3552dd58ef01SDimitry Andric return getIRBlock(Slot);
3553dd58ef01SDimitry Andric DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks;
3554dd58ef01SDimitry Andric initSlots2BasicBlocks(F, CustomSlots2BasicBlocks);
3555dd58ef01SDimitry Andric return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks);
3556dd58ef01SDimitry Andric }
3557dd58ef01SDimitry Andric
getOrCreateMCSymbol(StringRef Name)3558d8e91e46SDimitry Andric MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) {
3559d8e91e46SDimitry Andric // FIXME: Currently we can't recognize temporary or local symbols and call all
3560d8e91e46SDimitry Andric // of the appropriate forms to create them. However, this handles basic cases
3561d8e91e46SDimitry Andric // well as most of the special aspects are recognized by a prefix on their
3562d8e91e46SDimitry Andric // name, and the input names should already be unique. For test cases, keeping
3563d8e91e46SDimitry Andric // the symbol name out of the symbol table isn't terribly important.
3564d8e91e46SDimitry Andric return MF.getContext().getOrCreateSymbol(Name);
3565d8e91e46SDimitry Andric }
3566d8e91e46SDimitry Andric
parseStringConstant(std::string & Result)3567ca089b24SDimitry Andric bool MIParser::parseStringConstant(std::string &Result) {
3568ca089b24SDimitry Andric if (Token.isNot(MIToken::StringConstant))
3569ca089b24SDimitry Andric return error("expected string constant");
3570cfca06d7SDimitry Andric Result = std::string(Token.stringValue());
3571ca089b24SDimitry Andric lex();
3572ca089b24SDimitry Andric return false;
3573ca089b24SDimitry Andric }
3574ca089b24SDimitry Andric
parseMachineBasicBlockDefinitions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)357501095a5dSDimitry Andric bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
357601095a5dSDimitry Andric StringRef Src,
3577dd58ef01SDimitry Andric SMDiagnostic &Error) {
357801095a5dSDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots);
3579dd58ef01SDimitry Andric }
3580dd58ef01SDimitry Andric
parseMachineInstructions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)3581b915e9e0SDimitry Andric bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS,
358201095a5dSDimitry Andric StringRef Src, SMDiagnostic &Error) {
358301095a5dSDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlocks();
358401095a5dSDimitry Andric }
358501095a5dSDimitry Andric
parseMBBReference(PerFunctionMIParsingState & PFS,MachineBasicBlock * & MBB,StringRef Src,SMDiagnostic & Error)3586b915e9e0SDimitry Andric bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS,
358701095a5dSDimitry Andric MachineBasicBlock *&MBB, StringRef Src,
3588dd58ef01SDimitry Andric SMDiagnostic &Error) {
358901095a5dSDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB);
3590ee8648bdSDimitry Andric }
3591ee8648bdSDimitry Andric
parseRegisterReference(PerFunctionMIParsingState & PFS,Register & Reg,StringRef Src,SMDiagnostic & Error)3592b915e9e0SDimitry Andric bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS,
3593cfca06d7SDimitry Andric Register &Reg, StringRef Src,
3594b915e9e0SDimitry Andric SMDiagnostic &Error) {
3595b915e9e0SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg);
3596b915e9e0SDimitry Andric }
3597b915e9e0SDimitry Andric
parseNamedRegisterReference(PerFunctionMIParsingState & PFS,Register & Reg,StringRef Src,SMDiagnostic & Error)3598b915e9e0SDimitry Andric bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS,
3599cfca06d7SDimitry Andric Register &Reg, StringRef Src,
3600ee8648bdSDimitry Andric SMDiagnostic &Error) {
360101095a5dSDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg);
3602dd58ef01SDimitry Andric }
3603dd58ef01SDimitry Andric
parseVirtualRegisterReference(PerFunctionMIParsingState & PFS,VRegInfo * & Info,StringRef Src,SMDiagnostic & Error)3604b915e9e0SDimitry Andric bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
3605b915e9e0SDimitry Andric VRegInfo *&Info, StringRef Src,
3606dd58ef01SDimitry Andric SMDiagnostic &Error) {
3607b915e9e0SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info);
3608dd58ef01SDimitry Andric }
3609dd58ef01SDimitry Andric
parseStackObjectReference(PerFunctionMIParsingState & PFS,int & FI,StringRef Src,SMDiagnostic & Error)3610b915e9e0SDimitry Andric bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS,
361101095a5dSDimitry Andric int &FI, StringRef Src,
3612dd58ef01SDimitry Andric SMDiagnostic &Error) {
361301095a5dSDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI);
3614dd58ef01SDimitry Andric }
3615dd58ef01SDimitry Andric
parseMDNode(PerFunctionMIParsingState & PFS,MDNode * & Node,StringRef Src,SMDiagnostic & Error)3616b915e9e0SDimitry Andric bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
361701095a5dSDimitry Andric MDNode *&Node, StringRef Src, SMDiagnostic &Error) {
361801095a5dSDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
36191a82d4c0SDimitry Andric }
3620706b4fc4SDimitry Andric
parseMachineMetadata(PerFunctionMIParsingState & PFS,StringRef Src,SMRange SrcRange,SMDiagnostic & Error)3621344a3780SDimitry Andric bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src,
3622344a3780SDimitry Andric SMRange SrcRange, SMDiagnostic &Error) {
3623344a3780SDimitry Andric return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata();
3624344a3780SDimitry Andric }
3625344a3780SDimitry Andric
parseIRValue(StringRef Src,MachineFunction & MF,PerFunctionMIParsingState & PFS,const Value * & V,ErrorCallbackType ErrorCallback)3626706b4fc4SDimitry Andric bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF,
3627706b4fc4SDimitry Andric PerFunctionMIParsingState &PFS, const Value *&V,
3628706b4fc4SDimitry Andric ErrorCallbackType ErrorCallback) {
3629706b4fc4SDimitry Andric MIToken Token;
3630706b4fc4SDimitry Andric Src = lexMIToken(Src, Token, [&](StringRef::iterator Loc, const Twine &Msg) {
3631706b4fc4SDimitry Andric ErrorCallback(Loc, Msg);
3632706b4fc4SDimitry Andric });
3633706b4fc4SDimitry Andric V = nullptr;
3634706b4fc4SDimitry Andric
3635706b4fc4SDimitry Andric return ::parseIRValue(Token, PFS, V, ErrorCallback);
3636706b4fc4SDimitry Andric }
3637