xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/MIRParser/MIParser.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- MIParser.cpp - Machine instructions parser implementation ----------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the parsing of machine instructions.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/CodeGen/MIRParser/MIParser.h"
140b57cec5SDimitry Andric #include "MILexer.h"
150b57cec5SDimitry Andric #include "llvm/ADT/APInt.h"
160b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h"
170b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h"
180b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
190b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
200b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h"
210b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
220b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h"
230b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h"
250b57cec5SDimitry Andric #include "llvm/AsmParser/Parser.h"
260b57cec5SDimitry Andric #include "llvm/AsmParser/SlotMapping.h"
27480093f4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
375f757f3fSDimitry Andric #include "llvm/CodeGen/PseudoSourceValueManager.h"
3881ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
3981ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h"
400b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
43*0fca6ea1SDimitry Andric #include "llvm/CodeGenTypes/LowLevelType.h"
440b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h"
450b57cec5SDimitry Andric #include "llvm/IR/Constants.h"
460b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
470b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h"
480b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h"
490b57cec5SDimitry Andric #include "llvm/IR/Function.h"
500b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h"
510b57cec5SDimitry Andric #include "llvm/IR/Instructions.h"
520b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
530b57cec5SDimitry Andric #include "llvm/IR/Metadata.h"
540b57cec5SDimitry Andric #include "llvm/IR/Module.h"
550b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
560b57cec5SDimitry Andric #include "llvm/IR/Type.h"
570b57cec5SDimitry Andric #include "llvm/IR/Value.h"
580b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h"
590b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h"
600b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
610b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h"
620b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h"
630b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h"
640b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h"
650b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
660b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
670b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
680b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h"
690b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h"
700b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h"
710b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
720b57cec5SDimitry Andric #include <cassert>
730b57cec5SDimitry Andric #include <cctype>
740b57cec5SDimitry Andric #include <cstddef>
750b57cec5SDimitry Andric #include <cstdint>
760b57cec5SDimitry Andric #include <limits>
770b57cec5SDimitry Andric #include <string>
780b57cec5SDimitry Andric #include <utility>
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric using namespace llvm;
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric void PerTargetMIParsingState::setTarget(
830b57cec5SDimitry Andric   const TargetSubtargetInfo &NewSubtarget) {
840b57cec5SDimitry Andric 
850b57cec5SDimitry Andric   // If the subtarget changed, over conservatively assume everything is invalid.
860b57cec5SDimitry Andric   if (&Subtarget == &NewSubtarget)
870b57cec5SDimitry Andric     return;
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   Names2InstrOpCodes.clear();
900b57cec5SDimitry Andric   Names2Regs.clear();
910b57cec5SDimitry Andric   Names2RegMasks.clear();
920b57cec5SDimitry Andric   Names2SubRegIndices.clear();
930b57cec5SDimitry Andric   Names2TargetIndices.clear();
940b57cec5SDimitry Andric   Names2DirectTargetFlags.clear();
950b57cec5SDimitry Andric   Names2BitmaskTargetFlags.clear();
960b57cec5SDimitry Andric   Names2MMOTargetFlags.clear();
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric   initNames2RegClasses();
990b57cec5SDimitry Andric   initNames2RegBanks();
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2Regs() {
1030b57cec5SDimitry Andric   if (!Names2Regs.empty())
1040b57cec5SDimitry Andric     return;
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric   // The '%noreg' register is the register 0.
1070b57cec5SDimitry Andric   Names2Regs.insert(std::make_pair("noreg", 0));
1080b57cec5SDimitry Andric   const auto *TRI = Subtarget.getRegisterInfo();
1090b57cec5SDimitry Andric   assert(TRI && "Expected target register info");
1100b57cec5SDimitry Andric 
1110b57cec5SDimitry Andric   for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) {
1120b57cec5SDimitry Andric     bool WasInserted =
1130b57cec5SDimitry Andric         Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I))
1140b57cec5SDimitry Andric             .second;
1150b57cec5SDimitry Andric     (void)WasInserted;
1160b57cec5SDimitry Andric     assert(WasInserted && "Expected registers to be unique case-insensitively");
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric bool PerTargetMIParsingState::getRegisterByName(StringRef RegName,
1215ffd83dbSDimitry Andric                                                 Register &Reg) {
1220b57cec5SDimitry Andric   initNames2Regs();
1230b57cec5SDimitry Andric   auto RegInfo = Names2Regs.find(RegName);
1240b57cec5SDimitry Andric   if (RegInfo == Names2Regs.end())
1250b57cec5SDimitry Andric     return true;
1260b57cec5SDimitry Andric   Reg = RegInfo->getValue();
1270b57cec5SDimitry Andric   return false;
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
1300b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2InstrOpCodes() {
1310b57cec5SDimitry Andric   if (!Names2InstrOpCodes.empty())
1320b57cec5SDimitry Andric     return;
1330b57cec5SDimitry Andric   const auto *TII = Subtarget.getInstrInfo();
1340b57cec5SDimitry Andric   assert(TII && "Expected target instruction info");
1350b57cec5SDimitry Andric   for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I)
1360b57cec5SDimitry Andric     Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I));
1370b57cec5SDimitry Andric }
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric bool PerTargetMIParsingState::parseInstrName(StringRef InstrName,
1400b57cec5SDimitry Andric                                              unsigned &OpCode) {
1410b57cec5SDimitry Andric   initNames2InstrOpCodes();
1420b57cec5SDimitry Andric   auto InstrInfo = Names2InstrOpCodes.find(InstrName);
1430b57cec5SDimitry Andric   if (InstrInfo == Names2InstrOpCodes.end())
1440b57cec5SDimitry Andric     return true;
1450b57cec5SDimitry Andric   OpCode = InstrInfo->getValue();
1460b57cec5SDimitry Andric   return false;
1470b57cec5SDimitry Andric }
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegMasks() {
1500b57cec5SDimitry Andric   if (!Names2RegMasks.empty())
1510b57cec5SDimitry Andric     return;
1520b57cec5SDimitry Andric   const auto *TRI = Subtarget.getRegisterInfo();
1530b57cec5SDimitry Andric   assert(TRI && "Expected target register info");
1540b57cec5SDimitry Andric   ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks();
1550b57cec5SDimitry Andric   ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames();
1560b57cec5SDimitry Andric   assert(RegMasks.size() == RegMaskNames.size());
1570b57cec5SDimitry Andric   for (size_t I = 0, E = RegMasks.size(); I < E; ++I)
1580b57cec5SDimitry Andric     Names2RegMasks.insert(
1590b57cec5SDimitry Andric         std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I]));
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) {
1630b57cec5SDimitry Andric   initNames2RegMasks();
1640b57cec5SDimitry Andric   auto RegMaskInfo = Names2RegMasks.find(Identifier);
1650b57cec5SDimitry Andric   if (RegMaskInfo == Names2RegMasks.end())
1660b57cec5SDimitry Andric     return nullptr;
1670b57cec5SDimitry Andric   return RegMaskInfo->getValue();
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2SubRegIndices() {
1710b57cec5SDimitry Andric   if (!Names2SubRegIndices.empty())
1720b57cec5SDimitry Andric     return;
1730b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
1740b57cec5SDimitry Andric   for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I)
1750b57cec5SDimitry Andric     Names2SubRegIndices.insert(
1760b57cec5SDimitry Andric         std::make_pair(TRI->getSubRegIndexName(I), I));
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) {
1800b57cec5SDimitry Andric   initNames2SubRegIndices();
1810b57cec5SDimitry Andric   auto SubRegInfo = Names2SubRegIndices.find(Name);
1820b57cec5SDimitry Andric   if (SubRegInfo == Names2SubRegIndices.end())
1830b57cec5SDimitry Andric     return 0;
1840b57cec5SDimitry Andric   return SubRegInfo->getValue();
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2TargetIndices() {
1880b57cec5SDimitry Andric   if (!Names2TargetIndices.empty())
1890b57cec5SDimitry Andric     return;
1900b57cec5SDimitry Andric   const auto *TII = Subtarget.getInstrInfo();
1910b57cec5SDimitry Andric   assert(TII && "Expected target instruction info");
1920b57cec5SDimitry Andric   auto Indices = TII->getSerializableTargetIndices();
1930b57cec5SDimitry Andric   for (const auto &I : Indices)
1940b57cec5SDimitry Andric     Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first));
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) {
1980b57cec5SDimitry Andric   initNames2TargetIndices();
1990b57cec5SDimitry Andric   auto IndexInfo = Names2TargetIndices.find(Name);
2000b57cec5SDimitry Andric   if (IndexInfo == Names2TargetIndices.end())
2010b57cec5SDimitry Andric     return true;
2020b57cec5SDimitry Andric   Index = IndexInfo->second;
2030b57cec5SDimitry Andric   return false;
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2DirectTargetFlags() {
2070b57cec5SDimitry Andric   if (!Names2DirectTargetFlags.empty())
2080b57cec5SDimitry Andric     return;
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric   const auto *TII = Subtarget.getInstrInfo();
2110b57cec5SDimitry Andric   assert(TII && "Expected target instruction info");
2120b57cec5SDimitry Andric   auto Flags = TII->getSerializableDirectMachineOperandTargetFlags();
2130b57cec5SDimitry Andric   for (const auto &I : Flags)
2140b57cec5SDimitry Andric     Names2DirectTargetFlags.insert(
2150b57cec5SDimitry Andric         std::make_pair(StringRef(I.second), I.first));
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric 
2180b57cec5SDimitry Andric bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name,
2190b57cec5SDimitry Andric                                                   unsigned &Flag) {
2200b57cec5SDimitry Andric   initNames2DirectTargetFlags();
2210b57cec5SDimitry Andric   auto FlagInfo = Names2DirectTargetFlags.find(Name);
2220b57cec5SDimitry Andric   if (FlagInfo == Names2DirectTargetFlags.end())
2230b57cec5SDimitry Andric     return true;
2240b57cec5SDimitry Andric   Flag = FlagInfo->second;
2250b57cec5SDimitry Andric   return false;
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2BitmaskTargetFlags() {
2290b57cec5SDimitry Andric   if (!Names2BitmaskTargetFlags.empty())
2300b57cec5SDimitry Andric     return;
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric   const auto *TII = Subtarget.getInstrInfo();
2330b57cec5SDimitry Andric   assert(TII && "Expected target instruction info");
2340b57cec5SDimitry Andric   auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags();
2350b57cec5SDimitry Andric   for (const auto &I : Flags)
2360b57cec5SDimitry Andric     Names2BitmaskTargetFlags.insert(
2370b57cec5SDimitry Andric         std::make_pair(StringRef(I.second), I.first));
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name,
2410b57cec5SDimitry Andric                                                    unsigned &Flag) {
2420b57cec5SDimitry Andric   initNames2BitmaskTargetFlags();
2430b57cec5SDimitry Andric   auto FlagInfo = Names2BitmaskTargetFlags.find(Name);
2440b57cec5SDimitry Andric   if (FlagInfo == Names2BitmaskTargetFlags.end())
2450b57cec5SDimitry Andric     return true;
2460b57cec5SDimitry Andric   Flag = FlagInfo->second;
2470b57cec5SDimitry Andric   return false;
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2MMOTargetFlags() {
2510b57cec5SDimitry Andric   if (!Names2MMOTargetFlags.empty())
2520b57cec5SDimitry Andric     return;
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric   const auto *TII = Subtarget.getInstrInfo();
2550b57cec5SDimitry Andric   assert(TII && "Expected target instruction info");
2560b57cec5SDimitry Andric   auto Flags = TII->getSerializableMachineMemOperandTargetFlags();
2570b57cec5SDimitry Andric   for (const auto &I : Flags)
2580b57cec5SDimitry Andric     Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first));
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name,
2620b57cec5SDimitry Andric                                                MachineMemOperand::Flags &Flag) {
2630b57cec5SDimitry Andric   initNames2MMOTargetFlags();
2640b57cec5SDimitry Andric   auto FlagInfo = Names2MMOTargetFlags.find(Name);
2650b57cec5SDimitry Andric   if (FlagInfo == Names2MMOTargetFlags.end())
2660b57cec5SDimitry Andric     return true;
2670b57cec5SDimitry Andric   Flag = FlagInfo->second;
2680b57cec5SDimitry Andric   return false;
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric 
2710b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegClasses() {
2720b57cec5SDimitry Andric   if (!Names2RegClasses.empty())
2730b57cec5SDimitry Andric     return;
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
2760b57cec5SDimitry Andric   for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) {
2770b57cec5SDimitry Andric     const auto *RC = TRI->getRegClass(I);
2780b57cec5SDimitry Andric     Names2RegClasses.insert(
2790b57cec5SDimitry Andric         std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC));
2800b57cec5SDimitry Andric   }
2810b57cec5SDimitry Andric }
2820b57cec5SDimitry Andric 
2830b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegBanks() {
2840b57cec5SDimitry Andric   if (!Names2RegBanks.empty())
2850b57cec5SDimitry Andric     return;
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   const RegisterBankInfo *RBI = Subtarget.getRegBankInfo();
2880b57cec5SDimitry Andric   // If the target does not support GlobalISel, we may not have a
2890b57cec5SDimitry Andric   // register bank info.
2900b57cec5SDimitry Andric   if (!RBI)
2910b57cec5SDimitry Andric     return;
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) {
2940b57cec5SDimitry Andric     const auto &RegBank = RBI->getRegBank(I);
2950b57cec5SDimitry Andric     Names2RegBanks.insert(
2960b57cec5SDimitry Andric         std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank));
2970b57cec5SDimitry Andric   }
2980b57cec5SDimitry Andric }
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric const TargetRegisterClass *
3010b57cec5SDimitry Andric PerTargetMIParsingState::getRegClass(StringRef Name) {
3020b57cec5SDimitry Andric   auto RegClassInfo = Names2RegClasses.find(Name);
3030b57cec5SDimitry Andric   if (RegClassInfo == Names2RegClasses.end())
3040b57cec5SDimitry Andric     return nullptr;
3050b57cec5SDimitry Andric   return RegClassInfo->getValue();
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) {
3090b57cec5SDimitry Andric   auto RegBankInfo = Names2RegBanks.find(Name);
3100b57cec5SDimitry Andric   if (RegBankInfo == Names2RegBanks.end())
3110b57cec5SDimitry Andric     return nullptr;
3120b57cec5SDimitry Andric   return RegBankInfo->getValue();
3130b57cec5SDimitry Andric }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF,
3160b57cec5SDimitry Andric     SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T)
3170b57cec5SDimitry Andric   : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) {
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric 
3205ffd83dbSDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfo(Register Num) {
3210b57cec5SDimitry Andric   auto I = VRegInfos.insert(std::make_pair(Num, nullptr));
3220b57cec5SDimitry Andric   if (I.second) {
3230b57cec5SDimitry Andric     MachineRegisterInfo &MRI = MF.getRegInfo();
3240b57cec5SDimitry Andric     VRegInfo *Info = new (Allocator) VRegInfo;
3250b57cec5SDimitry Andric     Info->VReg = MRI.createIncompleteVirtualRegister();
3260b57cec5SDimitry Andric     I.first->second = Info;
3270b57cec5SDimitry Andric   }
3280b57cec5SDimitry Andric   return *I.first->second;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
3310b57cec5SDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) {
3320b57cec5SDimitry Andric   assert(RegName != "" && "Expected named reg.");
3330b57cec5SDimitry Andric 
3340b57cec5SDimitry Andric   auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr));
3350b57cec5SDimitry Andric   if (I.second) {
3360b57cec5SDimitry Andric     VRegInfo *Info = new (Allocator) VRegInfo;
3370b57cec5SDimitry Andric     Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName);
3380b57cec5SDimitry Andric     I.first->second = Info;
3390b57cec5SDimitry Andric   }
3400b57cec5SDimitry Andric   return *I.first->second;
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric 
343480093f4SDimitry Andric static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
344480093f4SDimitry Andric                            DenseMap<unsigned, const Value *> &Slots2Values) {
345480093f4SDimitry Andric   int Slot = MST.getLocalSlot(V);
346480093f4SDimitry Andric   if (Slot == -1)
347480093f4SDimitry Andric     return;
348480093f4SDimitry Andric   Slots2Values.insert(std::make_pair(unsigned(Slot), V));
349480093f4SDimitry Andric }
350480093f4SDimitry Andric 
351480093f4SDimitry Andric /// Creates the mapping from slot numbers to function's unnamed IR values.
352480093f4SDimitry Andric static void initSlots2Values(const Function &F,
353480093f4SDimitry Andric                              DenseMap<unsigned, const Value *> &Slots2Values) {
354480093f4SDimitry Andric   ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
355480093f4SDimitry Andric   MST.incorporateFunction(F);
356480093f4SDimitry Andric   for (const auto &Arg : F.args())
357480093f4SDimitry Andric     mapValueToSlot(&Arg, MST, Slots2Values);
358480093f4SDimitry Andric   for (const auto &BB : F) {
359480093f4SDimitry Andric     mapValueToSlot(&BB, MST, Slots2Values);
360480093f4SDimitry Andric     for (const auto &I : BB)
361480093f4SDimitry Andric       mapValueToSlot(&I, MST, Slots2Values);
362480093f4SDimitry Andric   }
363480093f4SDimitry Andric }
364480093f4SDimitry Andric 
365480093f4SDimitry Andric const Value* PerFunctionMIParsingState::getIRValue(unsigned Slot) {
366480093f4SDimitry Andric   if (Slots2Values.empty())
367480093f4SDimitry Andric     initSlots2Values(MF.getFunction(), Slots2Values);
368e8d8bef9SDimitry Andric   return Slots2Values.lookup(Slot);
369480093f4SDimitry Andric }
370480093f4SDimitry Andric 
3710b57cec5SDimitry Andric namespace {
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric /// A wrapper struct around the 'MachineOperand' struct that includes a source
3740b57cec5SDimitry Andric /// range and other attributes.
3750b57cec5SDimitry Andric struct ParsedMachineOperand {
3760b57cec5SDimitry Andric   MachineOperand Operand;
3770b57cec5SDimitry Andric   StringRef::iterator Begin;
3780b57cec5SDimitry Andric   StringRef::iterator End;
379bdd1243dSDimitry Andric   std::optional<unsigned> TiedDefIdx;
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric   ParsedMachineOperand(const MachineOperand &Operand, StringRef::iterator Begin,
382bdd1243dSDimitry Andric                        StringRef::iterator End,
383bdd1243dSDimitry Andric                        std::optional<unsigned> &TiedDefIdx)
3840b57cec5SDimitry Andric       : Operand(Operand), Begin(Begin), End(End), TiedDefIdx(TiedDefIdx) {
3850b57cec5SDimitry Andric     if (TiedDefIdx)
3860b57cec5SDimitry Andric       assert(Operand.isReg() && Operand.isUse() &&
3870b57cec5SDimitry Andric              "Only used register operands can be tied");
3880b57cec5SDimitry Andric   }
3890b57cec5SDimitry Andric };
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric class MIParser {
3920b57cec5SDimitry Andric   MachineFunction &MF;
3930b57cec5SDimitry Andric   SMDiagnostic &Error;
3940b57cec5SDimitry Andric   StringRef Source, CurrentSource;
395fe6060f1SDimitry Andric   SMRange SourceRange;
3960b57cec5SDimitry Andric   MIToken Token;
3970b57cec5SDimitry Andric   PerFunctionMIParsingState &PFS;
3980b57cec5SDimitry Andric   /// Maps from slot numbers to function's unnamed basic blocks.
3990b57cec5SDimitry Andric   DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks;
4000b57cec5SDimitry Andric 
4010b57cec5SDimitry Andric public:
4020b57cec5SDimitry Andric   MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
4030b57cec5SDimitry Andric            StringRef Source);
404fe6060f1SDimitry Andric   MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
405fe6060f1SDimitry Andric            StringRef Source, SMRange SourceRange);
4060b57cec5SDimitry Andric 
4070b57cec5SDimitry Andric   /// \p SkipChar gives the number of characters to skip before looking
4080b57cec5SDimitry Andric   /// for the next token.
4090b57cec5SDimitry Andric   void lex(unsigned SkipChar = 0);
4100b57cec5SDimitry Andric 
4110b57cec5SDimitry Andric   /// Report an error at the current location with the given message.
4120b57cec5SDimitry Andric   ///
4130b57cec5SDimitry Andric   /// This function always return true.
4140b57cec5SDimitry Andric   bool error(const Twine &Msg);
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   /// Report an error at the given location with the given message.
4170b57cec5SDimitry Andric   ///
4180b57cec5SDimitry Andric   /// This function always return true.
4190b57cec5SDimitry Andric   bool error(StringRef::iterator Loc, const Twine &Msg);
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   bool
4220b57cec5SDimitry Andric   parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
4230b57cec5SDimitry Andric   bool parseBasicBlocks();
4240b57cec5SDimitry Andric   bool parse(MachineInstr *&MI);
4250b57cec5SDimitry Andric   bool parseStandaloneMBB(MachineBasicBlock *&MBB);
4265ffd83dbSDimitry Andric   bool parseStandaloneNamedRegister(Register &Reg);
4270b57cec5SDimitry Andric   bool parseStandaloneVirtualRegister(VRegInfo *&Info);
4285ffd83dbSDimitry Andric   bool parseStandaloneRegister(Register &Reg);
4290b57cec5SDimitry Andric   bool parseStandaloneStackObject(int &FI);
4300b57cec5SDimitry Andric   bool parseStandaloneMDNode(MDNode *&Node);
431fe6060f1SDimitry Andric   bool parseMachineMetadata();
432fe6060f1SDimitry Andric   bool parseMDTuple(MDNode *&MD, bool IsDistinct);
433fe6060f1SDimitry Andric   bool parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts);
434fe6060f1SDimitry Andric   bool parseMetadata(Metadata *&MD);
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   bool
4370b57cec5SDimitry Andric   parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
4380b57cec5SDimitry Andric   bool parseBasicBlock(MachineBasicBlock &MBB,
4390b57cec5SDimitry Andric                        MachineBasicBlock *&AddFalthroughFrom);
4400b57cec5SDimitry Andric   bool parseBasicBlockLiveins(MachineBasicBlock &MBB);
4410b57cec5SDimitry Andric   bool parseBasicBlockSuccessors(MachineBasicBlock &MBB);
4420b57cec5SDimitry Andric 
4435ffd83dbSDimitry Andric   bool parseNamedRegister(Register &Reg);
4440b57cec5SDimitry Andric   bool parseVirtualRegister(VRegInfo *&Info);
4450b57cec5SDimitry Andric   bool parseNamedVirtualRegister(VRegInfo *&Info);
4465ffd83dbSDimitry Andric   bool parseRegister(Register &Reg, VRegInfo *&VRegInfo);
4470b57cec5SDimitry Andric   bool parseRegisterFlag(unsigned &Flags);
4480b57cec5SDimitry Andric   bool parseRegisterClassOrBank(VRegInfo &RegInfo);
4490b57cec5SDimitry Andric   bool parseSubRegisterIndex(unsigned &SubReg);
4500b57cec5SDimitry Andric   bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx);
4510b57cec5SDimitry Andric   bool parseRegisterOperand(MachineOperand &Dest,
452bdd1243dSDimitry Andric                             std::optional<unsigned> &TiedDefIdx,
453bdd1243dSDimitry Andric                             bool IsDef = false);
4540b57cec5SDimitry Andric   bool parseImmediateOperand(MachineOperand &Dest);
4550b57cec5SDimitry Andric   bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
4560b57cec5SDimitry Andric                        const Constant *&C);
4570b57cec5SDimitry Andric   bool parseIRConstant(StringRef::iterator Loc, const Constant *&C);
4580b57cec5SDimitry Andric   bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty);
4590b57cec5SDimitry Andric   bool parseTypedImmediateOperand(MachineOperand &Dest);
4600b57cec5SDimitry Andric   bool parseFPImmediateOperand(MachineOperand &Dest);
4610b57cec5SDimitry Andric   bool parseMBBReference(MachineBasicBlock *&MBB);
4620b57cec5SDimitry Andric   bool parseMBBOperand(MachineOperand &Dest);
4630b57cec5SDimitry Andric   bool parseStackFrameIndex(int &FI);
4640b57cec5SDimitry Andric   bool parseStackObjectOperand(MachineOperand &Dest);
4650b57cec5SDimitry Andric   bool parseFixedStackFrameIndex(int &FI);
4660b57cec5SDimitry Andric   bool parseFixedStackObjectOperand(MachineOperand &Dest);
4670b57cec5SDimitry Andric   bool parseGlobalValue(GlobalValue *&GV);
4680b57cec5SDimitry Andric   bool parseGlobalAddressOperand(MachineOperand &Dest);
4690b57cec5SDimitry Andric   bool parseConstantPoolIndexOperand(MachineOperand &Dest);
4700b57cec5SDimitry Andric   bool parseSubRegisterIndexOperand(MachineOperand &Dest);
4710b57cec5SDimitry Andric   bool parseJumpTableIndexOperand(MachineOperand &Dest);
4720b57cec5SDimitry Andric   bool parseExternalSymbolOperand(MachineOperand &Dest);
4730b57cec5SDimitry Andric   bool parseMCSymbolOperand(MachineOperand &Dest);
47406c3fb27SDimitry Andric   [[nodiscard]] bool parseMDNode(MDNode *&Node);
4750b57cec5SDimitry Andric   bool parseDIExpression(MDNode *&Expr);
4760b57cec5SDimitry Andric   bool parseDILocation(MDNode *&Expr);
4770b57cec5SDimitry Andric   bool parseMetadataOperand(MachineOperand &Dest);
4780b57cec5SDimitry Andric   bool parseCFIOffset(int &Offset);
4795ffd83dbSDimitry Andric   bool parseCFIRegister(Register &Reg);
480fe6060f1SDimitry Andric   bool parseCFIAddressSpace(unsigned &AddressSpace);
4810b57cec5SDimitry Andric   bool parseCFIEscapeValues(std::string& Values);
4820b57cec5SDimitry Andric   bool parseCFIOperand(MachineOperand &Dest);
4830b57cec5SDimitry Andric   bool parseIRBlock(BasicBlock *&BB, const Function &F);
4840b57cec5SDimitry Andric   bool parseBlockAddressOperand(MachineOperand &Dest);
4850b57cec5SDimitry Andric   bool parseIntrinsicOperand(MachineOperand &Dest);
4860b57cec5SDimitry Andric   bool parsePredicateOperand(MachineOperand &Dest);
4878bcb0991SDimitry Andric   bool parseShuffleMaskOperand(MachineOperand &Dest);
4880b57cec5SDimitry Andric   bool parseTargetIndexOperand(MachineOperand &Dest);
489bdd1243dSDimitry Andric   bool parseDbgInstrRefOperand(MachineOperand &Dest);
4900b57cec5SDimitry Andric   bool parseCustomRegisterMaskOperand(MachineOperand &Dest);
4910b57cec5SDimitry Andric   bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest);
492480093f4SDimitry Andric   bool parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
493480093f4SDimitry Andric                            MachineOperand &Dest,
494bdd1243dSDimitry Andric                            std::optional<unsigned> &TiedDefIdx);
495480093f4SDimitry Andric   bool parseMachineOperandAndTargetFlags(const unsigned OpCode,
496480093f4SDimitry Andric                                          const unsigned OpIdx,
497480093f4SDimitry Andric                                          MachineOperand &Dest,
498bdd1243dSDimitry Andric                                          std::optional<unsigned> &TiedDefIdx);
4990b57cec5SDimitry Andric   bool parseOffset(int64_t &Offset);
500bdd1243dSDimitry Andric   bool parseIRBlockAddressTaken(BasicBlock *&BB);
501349cc55cSDimitry Andric   bool parseAlignment(uint64_t &Alignment);
5020b57cec5SDimitry Andric   bool parseAddrspace(unsigned &Addrspace);
503bdd1243dSDimitry Andric   bool parseSectionID(std::optional<MBBSectionID> &SID);
5045f757f3fSDimitry Andric   bool parseBBID(std::optional<UniqueBBID> &BBID);
5055f757f3fSDimitry Andric   bool parseCallFrameSize(unsigned &CallFrameSize);
5060b57cec5SDimitry Andric   bool parseOperandsOffset(MachineOperand &Op);
5070b57cec5SDimitry Andric   bool parseIRValue(const Value *&V);
5080b57cec5SDimitry Andric   bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags);
5090b57cec5SDimitry Andric   bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV);
5100b57cec5SDimitry Andric   bool parseMachinePointerInfo(MachinePointerInfo &Dest);
5110b57cec5SDimitry Andric   bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID);
5120b57cec5SDimitry Andric   bool parseOptionalAtomicOrdering(AtomicOrdering &Order);
5130b57cec5SDimitry Andric   bool parseMachineMemoryOperand(MachineMemOperand *&Dest);
5140b57cec5SDimitry Andric   bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol);
515480093f4SDimitry Andric   bool parseHeapAllocMarker(MDNode *&Node);
516bdd1243dSDimitry Andric   bool parsePCSections(MDNode *&Node);
517480093f4SDimitry Andric 
518480093f4SDimitry Andric   bool parseTargetImmMnemonic(const unsigned OpCode, const unsigned OpIdx,
519480093f4SDimitry Andric                               MachineOperand &Dest, const MIRFormatter &MF);
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric private:
5220b57cec5SDimitry Andric   /// Convert the integer literal in the current token into an unsigned integer.
5230b57cec5SDimitry Andric   ///
5240b57cec5SDimitry Andric   /// Return true if an error occurred.
5250b57cec5SDimitry Andric   bool getUnsigned(unsigned &Result);
5260b57cec5SDimitry Andric 
5270b57cec5SDimitry Andric   /// Convert the integer literal in the current token into an uint64.
5280b57cec5SDimitry Andric   ///
5290b57cec5SDimitry Andric   /// Return true if an error occurred.
5300b57cec5SDimitry Andric   bool getUint64(uint64_t &Result);
5310b57cec5SDimitry Andric 
5320b57cec5SDimitry Andric   /// Convert the hexadecimal literal in the current token into an unsigned
5330b57cec5SDimitry Andric   ///  APInt with a minimum bitwidth required to represent the value.
5340b57cec5SDimitry Andric   ///
5350b57cec5SDimitry Andric   /// Return true if the literal does not represent an integer value.
5360b57cec5SDimitry Andric   bool getHexUint(APInt &Result);
5370b57cec5SDimitry Andric 
5380b57cec5SDimitry Andric   /// If the current token is of the given kind, consume it and return false.
5390b57cec5SDimitry Andric   /// Otherwise report an error and return true.
5400b57cec5SDimitry Andric   bool expectAndConsume(MIToken::TokenKind TokenKind);
5410b57cec5SDimitry Andric 
5420b57cec5SDimitry Andric   /// If the current token is of the given kind, consume it and return true.
5430b57cec5SDimitry Andric   /// Otherwise return false.
5440b57cec5SDimitry Andric   bool consumeIfPresent(MIToken::TokenKind TokenKind);
5450b57cec5SDimitry Andric 
5460b57cec5SDimitry Andric   bool parseInstruction(unsigned &OpCode, unsigned &Flags);
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric   bool assignRegisterTies(MachineInstr &MI,
5490b57cec5SDimitry Andric                           ArrayRef<ParsedMachineOperand> Operands);
5500b57cec5SDimitry Andric 
5510b57cec5SDimitry Andric   bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
5520b57cec5SDimitry Andric                               const MCInstrDesc &MCID);
5530b57cec5SDimitry Andric 
5540b57cec5SDimitry Andric   const BasicBlock *getIRBlock(unsigned Slot);
5550b57cec5SDimitry Andric   const BasicBlock *getIRBlock(unsigned Slot, const Function &F);
5560b57cec5SDimitry Andric 
5570b57cec5SDimitry Andric   /// Get or create an MCSymbol for a given name.
5580b57cec5SDimitry Andric   MCSymbol *getOrCreateMCSymbol(StringRef Name);
5590b57cec5SDimitry Andric 
5600b57cec5SDimitry Andric   /// parseStringConstant
5610b57cec5SDimitry Andric   ///   ::= StringConstant
5620b57cec5SDimitry Andric   bool parseStringConstant(std::string &Result);
563fe6060f1SDimitry Andric 
564fe6060f1SDimitry Andric   /// Map the location in the MI string to the corresponding location specified
565fe6060f1SDimitry Andric   /// in `SourceRange`.
566fe6060f1SDimitry Andric   SMLoc mapSMLoc(StringRef::iterator Loc);
5670b57cec5SDimitry Andric };
5680b57cec5SDimitry Andric 
5690b57cec5SDimitry Andric } // end anonymous namespace
5700b57cec5SDimitry Andric 
5710b57cec5SDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
5720b57cec5SDimitry Andric                    StringRef Source)
5730b57cec5SDimitry Andric     : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS)
5740b57cec5SDimitry Andric {}
5750b57cec5SDimitry Andric 
576fe6060f1SDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error,
577fe6060f1SDimitry Andric                    StringRef Source, SMRange SourceRange)
578fe6060f1SDimitry Andric     : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source),
579fe6060f1SDimitry Andric       SourceRange(SourceRange), PFS(PFS) {}
580fe6060f1SDimitry Andric 
5810b57cec5SDimitry Andric void MIParser::lex(unsigned SkipChar) {
5820b57cec5SDimitry Andric   CurrentSource = lexMIToken(
5835ffd83dbSDimitry Andric       CurrentSource.slice(SkipChar, StringRef::npos), Token,
5840b57cec5SDimitry Andric       [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); });
5850b57cec5SDimitry Andric }
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) {
5900b57cec5SDimitry Andric   const SourceMgr &SM = *PFS.SM;
5910b57cec5SDimitry Andric   assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
5920b57cec5SDimitry Andric   const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID());
5930b57cec5SDimitry Andric   if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) {
5940b57cec5SDimitry Andric     // Create an ordinary diagnostic when the source manager's buffer is the
5950b57cec5SDimitry Andric     // source string.
5960b57cec5SDimitry Andric     Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
5970b57cec5SDimitry Andric     return true;
5980b57cec5SDimitry Andric   }
5990b57cec5SDimitry Andric   // Create a diagnostic for a YAML string literal.
6000b57cec5SDimitry Andric   Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1,
6010b57cec5SDimitry Andric                        Loc - Source.data(), SourceMgr::DK_Error, Msg.str(),
602bdd1243dSDimitry Andric                        Source, std::nullopt, std::nullopt);
6030b57cec5SDimitry Andric   return true;
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric 
606fe6060f1SDimitry Andric SMLoc MIParser::mapSMLoc(StringRef::iterator Loc) {
607fe6060f1SDimitry Andric   assert(SourceRange.isValid() && "Invalid source range");
608fe6060f1SDimitry Andric   assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size()));
609fe6060f1SDimitry Andric   return SMLoc::getFromPointer(SourceRange.Start.getPointer() +
610fe6060f1SDimitry Andric                                (Loc - Source.data()));
611fe6060f1SDimitry Andric }
612fe6060f1SDimitry Andric 
613480093f4SDimitry Andric typedef function_ref<bool(StringRef::iterator Loc, const Twine &)>
614480093f4SDimitry Andric     ErrorCallbackType;
615480093f4SDimitry Andric 
6160b57cec5SDimitry Andric static const char *toString(MIToken::TokenKind TokenKind) {
6170b57cec5SDimitry Andric   switch (TokenKind) {
6180b57cec5SDimitry Andric   case MIToken::comma:
6190b57cec5SDimitry Andric     return "','";
6200b57cec5SDimitry Andric   case MIToken::equal:
6210b57cec5SDimitry Andric     return "'='";
6220b57cec5SDimitry Andric   case MIToken::colon:
6230b57cec5SDimitry Andric     return "':'";
6240b57cec5SDimitry Andric   case MIToken::lparen:
6250b57cec5SDimitry Andric     return "'('";
6260b57cec5SDimitry Andric   case MIToken::rparen:
6270b57cec5SDimitry Andric     return "')'";
6280b57cec5SDimitry Andric   default:
6290b57cec5SDimitry Andric     return "<unknown token>";
6300b57cec5SDimitry Andric   }
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) {
6340b57cec5SDimitry Andric   if (Token.isNot(TokenKind))
6350b57cec5SDimitry Andric     return error(Twine("expected ") + toString(TokenKind));
6360b57cec5SDimitry Andric   lex();
6370b57cec5SDimitry Andric   return false;
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) {
6410b57cec5SDimitry Andric   if (Token.isNot(TokenKind))
6420b57cec5SDimitry Andric     return false;
6430b57cec5SDimitry Andric   lex();
6440b57cec5SDimitry Andric   return true;
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric 
6475ffd83dbSDimitry Andric // Parse Machine Basic Block Section ID.
648bdd1243dSDimitry Andric bool MIParser::parseSectionID(std::optional<MBBSectionID> &SID) {
6495ffd83dbSDimitry Andric   assert(Token.is(MIToken::kw_bbsections));
6505ffd83dbSDimitry Andric   lex();
6515ffd83dbSDimitry Andric   if (Token.is(MIToken::IntegerLiteral)) {
6525ffd83dbSDimitry Andric     unsigned Value = 0;
6535ffd83dbSDimitry Andric     if (getUnsigned(Value))
6545ffd83dbSDimitry Andric       return error("Unknown Section ID");
6555ffd83dbSDimitry Andric     SID = MBBSectionID{Value};
6565ffd83dbSDimitry Andric   } else {
6575ffd83dbSDimitry Andric     const StringRef &S = Token.stringValue();
6585ffd83dbSDimitry Andric     if (S == "Exception")
6595ffd83dbSDimitry Andric       SID = MBBSectionID::ExceptionSectionID;
6605ffd83dbSDimitry Andric     else if (S == "Cold")
6615ffd83dbSDimitry Andric       SID = MBBSectionID::ColdSectionID;
6625ffd83dbSDimitry Andric     else
6635ffd83dbSDimitry Andric       return error("Unknown Section ID");
6645ffd83dbSDimitry Andric   }
6655ffd83dbSDimitry Andric   lex();
6665ffd83dbSDimitry Andric   return false;
6675ffd83dbSDimitry Andric }
6685ffd83dbSDimitry Andric 
669bdd1243dSDimitry Andric // Parse Machine Basic Block ID.
6705f757f3fSDimitry Andric bool MIParser::parseBBID(std::optional<UniqueBBID> &BBID) {
671bdd1243dSDimitry Andric   assert(Token.is(MIToken::kw_bb_id));
672bdd1243dSDimitry Andric   lex();
6735f757f3fSDimitry Andric   unsigned BaseID = 0;
6745f757f3fSDimitry Andric   unsigned CloneID = 0;
6755f757f3fSDimitry Andric   if (getUnsigned(BaseID))
6765f757f3fSDimitry Andric     return error("Unknown BB ID");
6775f757f3fSDimitry Andric   lex();
6785f757f3fSDimitry Andric   if (Token.is(MIToken::IntegerLiteral)) {
6795f757f3fSDimitry Andric     if (getUnsigned(CloneID))
6805f757f3fSDimitry Andric       return error("Unknown Clone ID");
6815f757f3fSDimitry Andric     lex();
6825f757f3fSDimitry Andric   }
6835f757f3fSDimitry Andric   BBID = {BaseID, CloneID};
6845f757f3fSDimitry Andric   return false;
6855f757f3fSDimitry Andric }
6865f757f3fSDimitry Andric 
6875f757f3fSDimitry Andric // Parse basic block call frame size.
6885f757f3fSDimitry Andric bool MIParser::parseCallFrameSize(unsigned &CallFrameSize) {
6895f757f3fSDimitry Andric   assert(Token.is(MIToken::kw_call_frame_size));
6905f757f3fSDimitry Andric   lex();
691bdd1243dSDimitry Andric   unsigned Value = 0;
692bdd1243dSDimitry Andric   if (getUnsigned(Value))
6935f757f3fSDimitry Andric     return error("Unknown call frame size");
6945f757f3fSDimitry Andric   CallFrameSize = Value;
695bdd1243dSDimitry Andric   lex();
696bdd1243dSDimitry Andric   return false;
697bdd1243dSDimitry Andric }
698bdd1243dSDimitry Andric 
6990b57cec5SDimitry Andric bool MIParser::parseBasicBlockDefinition(
7000b57cec5SDimitry Andric     DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
7010b57cec5SDimitry Andric   assert(Token.is(MIToken::MachineBasicBlockLabel));
7020b57cec5SDimitry Andric   unsigned ID = 0;
7030b57cec5SDimitry Andric   if (getUnsigned(ID))
7040b57cec5SDimitry Andric     return true;
7050b57cec5SDimitry Andric   auto Loc = Token.location();
7060b57cec5SDimitry Andric   auto Name = Token.stringValue();
7070b57cec5SDimitry Andric   lex();
708bdd1243dSDimitry Andric   bool MachineBlockAddressTaken = false;
709bdd1243dSDimitry Andric   BasicBlock *AddressTakenIRBlock = nullptr;
7100b57cec5SDimitry Andric   bool IsLandingPad = false;
711349cc55cSDimitry Andric   bool IsInlineAsmBrIndirectTarget = false;
7125ffd83dbSDimitry Andric   bool IsEHFuncletEntry = false;
713bdd1243dSDimitry Andric   std::optional<MBBSectionID> SectionID;
714349cc55cSDimitry Andric   uint64_t Alignment = 0;
7155f757f3fSDimitry Andric   std::optional<UniqueBBID> BBID;
7165f757f3fSDimitry Andric   unsigned CallFrameSize = 0;
7170b57cec5SDimitry Andric   BasicBlock *BB = nullptr;
7180b57cec5SDimitry Andric   if (consumeIfPresent(MIToken::lparen)) {
7190b57cec5SDimitry Andric     do {
7200b57cec5SDimitry Andric       // TODO: Report an error when multiple same attributes are specified.
7210b57cec5SDimitry Andric       switch (Token.kind()) {
722bdd1243dSDimitry Andric       case MIToken::kw_machine_block_address_taken:
723bdd1243dSDimitry Andric         MachineBlockAddressTaken = true;
7240b57cec5SDimitry Andric         lex();
7250b57cec5SDimitry Andric         break;
726bdd1243dSDimitry Andric       case MIToken::kw_ir_block_address_taken:
727bdd1243dSDimitry Andric         if (parseIRBlockAddressTaken(AddressTakenIRBlock))
728bdd1243dSDimitry Andric           return true;
729bdd1243dSDimitry Andric         break;
7300b57cec5SDimitry Andric       case MIToken::kw_landing_pad:
7310b57cec5SDimitry Andric         IsLandingPad = true;
7320b57cec5SDimitry Andric         lex();
7330b57cec5SDimitry Andric         break;
734349cc55cSDimitry Andric       case MIToken::kw_inlineasm_br_indirect_target:
735349cc55cSDimitry Andric         IsInlineAsmBrIndirectTarget = true;
736349cc55cSDimitry Andric         lex();
737349cc55cSDimitry Andric         break;
7385ffd83dbSDimitry Andric       case MIToken::kw_ehfunclet_entry:
7395ffd83dbSDimitry Andric         IsEHFuncletEntry = true;
7405ffd83dbSDimitry Andric         lex();
7415ffd83dbSDimitry Andric         break;
7420b57cec5SDimitry Andric       case MIToken::kw_align:
7430b57cec5SDimitry Andric         if (parseAlignment(Alignment))
7440b57cec5SDimitry Andric           return true;
7450b57cec5SDimitry Andric         break;
7460b57cec5SDimitry Andric       case MIToken::IRBlock:
747bdd1243dSDimitry Andric       case MIToken::NamedIRBlock:
7480b57cec5SDimitry Andric         // TODO: Report an error when both name and ir block are specified.
7490b57cec5SDimitry Andric         if (parseIRBlock(BB, MF.getFunction()))
7500b57cec5SDimitry Andric           return true;
7510b57cec5SDimitry Andric         lex();
7520b57cec5SDimitry Andric         break;
7535ffd83dbSDimitry Andric       case MIToken::kw_bbsections:
7545ffd83dbSDimitry Andric         if (parseSectionID(SectionID))
7555ffd83dbSDimitry Andric           return true;
7565ffd83dbSDimitry Andric         break;
757bdd1243dSDimitry Andric       case MIToken::kw_bb_id:
758bdd1243dSDimitry Andric         if (parseBBID(BBID))
759bdd1243dSDimitry Andric           return true;
760bdd1243dSDimitry Andric         break;
7615f757f3fSDimitry Andric       case MIToken::kw_call_frame_size:
7625f757f3fSDimitry Andric         if (parseCallFrameSize(CallFrameSize))
7635f757f3fSDimitry Andric           return true;
7645f757f3fSDimitry Andric         break;
7650b57cec5SDimitry Andric       default:
7660b57cec5SDimitry Andric         break;
7670b57cec5SDimitry Andric       }
7680b57cec5SDimitry Andric     } while (consumeIfPresent(MIToken::comma));
7690b57cec5SDimitry Andric     if (expectAndConsume(MIToken::rparen))
7700b57cec5SDimitry Andric       return true;
7710b57cec5SDimitry Andric   }
7720b57cec5SDimitry Andric   if (expectAndConsume(MIToken::colon))
7730b57cec5SDimitry Andric     return true;
7740b57cec5SDimitry Andric 
7750b57cec5SDimitry Andric   if (!Name.empty()) {
7760b57cec5SDimitry Andric     BB = dyn_cast_or_null<BasicBlock>(
7770b57cec5SDimitry Andric         MF.getFunction().getValueSymbolTable()->lookup(Name));
7780b57cec5SDimitry Andric     if (!BB)
7790b57cec5SDimitry Andric       return error(Loc, Twine("basic block '") + Name +
7800b57cec5SDimitry Andric                             "' is not defined in the function '" +
7810b57cec5SDimitry Andric                             MF.getName() + "'");
7820b57cec5SDimitry Andric   }
7830b57cec5SDimitry Andric   auto *MBB = MF.CreateMachineBasicBlock(BB);
7840b57cec5SDimitry Andric   MF.insert(MF.end(), MBB);
7850b57cec5SDimitry Andric   bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second;
7860b57cec5SDimitry Andric   if (!WasInserted)
7870b57cec5SDimitry Andric     return error(Loc, Twine("redefinition of machine basic block with id #") +
7880b57cec5SDimitry Andric                           Twine(ID));
7890b57cec5SDimitry Andric   if (Alignment)
7908bcb0991SDimitry Andric     MBB->setAlignment(Align(Alignment));
791bdd1243dSDimitry Andric   if (MachineBlockAddressTaken)
792bdd1243dSDimitry Andric     MBB->setMachineBlockAddressTaken();
793bdd1243dSDimitry Andric   if (AddressTakenIRBlock)
794bdd1243dSDimitry Andric     MBB->setAddressTakenIRBlock(AddressTakenIRBlock);
7950b57cec5SDimitry Andric   MBB->setIsEHPad(IsLandingPad);
796349cc55cSDimitry Andric   MBB->setIsInlineAsmBrIndirectTarget(IsInlineAsmBrIndirectTarget);
7975ffd83dbSDimitry Andric   MBB->setIsEHFuncletEntry(IsEHFuncletEntry);
79881ad6265SDimitry Andric   if (SectionID) {
799bdd1243dSDimitry Andric     MBB->setSectionID(*SectionID);
8005ffd83dbSDimitry Andric     MF.setBBSectionsType(BasicBlockSection::List);
8015ffd83dbSDimitry Andric   }
802bdd1243dSDimitry Andric   if (BBID.has_value()) {
803bdd1243dSDimitry Andric     // BBSectionsType is set to `List` if any basic blocks has `SectionID`.
804bdd1243dSDimitry Andric     // Here, we set it to `Labels` if it hasn't been set above.
805bdd1243dSDimitry Andric     if (!MF.hasBBSections())
806bdd1243dSDimitry Andric       MF.setBBSectionsType(BasicBlockSection::Labels);
807bdd1243dSDimitry Andric     MBB->setBBID(BBID.value());
808bdd1243dSDimitry Andric   }
8095f757f3fSDimitry Andric   MBB->setCallFrameSize(CallFrameSize);
8100b57cec5SDimitry Andric   return false;
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric 
8130b57cec5SDimitry Andric bool MIParser::parseBasicBlockDefinitions(
8140b57cec5SDimitry Andric     DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) {
8150b57cec5SDimitry Andric   lex();
8160b57cec5SDimitry Andric   // Skip until the first machine basic block.
8170b57cec5SDimitry Andric   while (Token.is(MIToken::Newline))
8180b57cec5SDimitry Andric     lex();
8190b57cec5SDimitry Andric   if (Token.isErrorOrEOF())
8200b57cec5SDimitry Andric     return Token.isError();
8210b57cec5SDimitry Andric   if (Token.isNot(MIToken::MachineBasicBlockLabel))
8220b57cec5SDimitry Andric     return error("expected a basic block definition before instructions");
8230b57cec5SDimitry Andric   unsigned BraceDepth = 0;
8240b57cec5SDimitry Andric   do {
8250b57cec5SDimitry Andric     if (parseBasicBlockDefinition(MBBSlots))
8260b57cec5SDimitry Andric       return true;
8270b57cec5SDimitry Andric     bool IsAfterNewline = false;
8280b57cec5SDimitry Andric     // Skip until the next machine basic block.
8290b57cec5SDimitry Andric     while (true) {
8300b57cec5SDimitry Andric       if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) ||
8310b57cec5SDimitry Andric           Token.isErrorOrEOF())
8320b57cec5SDimitry Andric         break;
8330b57cec5SDimitry Andric       else if (Token.is(MIToken::MachineBasicBlockLabel))
8340b57cec5SDimitry Andric         return error("basic block definition should be located at the start of "
8350b57cec5SDimitry Andric                      "the line");
8360b57cec5SDimitry Andric       else if (consumeIfPresent(MIToken::Newline)) {
8370b57cec5SDimitry Andric         IsAfterNewline = true;
8380b57cec5SDimitry Andric         continue;
8390b57cec5SDimitry Andric       }
8400b57cec5SDimitry Andric       IsAfterNewline = false;
8410b57cec5SDimitry Andric       if (Token.is(MIToken::lbrace))
8420b57cec5SDimitry Andric         ++BraceDepth;
8430b57cec5SDimitry Andric       if (Token.is(MIToken::rbrace)) {
8440b57cec5SDimitry Andric         if (!BraceDepth)
8450b57cec5SDimitry Andric           return error("extraneous closing brace ('}')");
8460b57cec5SDimitry Andric         --BraceDepth;
8470b57cec5SDimitry Andric       }
8480b57cec5SDimitry Andric       lex();
8490b57cec5SDimitry Andric     }
8500b57cec5SDimitry Andric     // Verify that we closed all of the '{' at the end of a file or a block.
8510b57cec5SDimitry Andric     if (!Token.isError() && BraceDepth)
8520b57cec5SDimitry Andric       return error("expected '}'"); // FIXME: Report a note that shows '{'.
8530b57cec5SDimitry Andric   } while (!Token.isErrorOrEOF());
8540b57cec5SDimitry Andric   return Token.isError();
8550b57cec5SDimitry Andric }
8560b57cec5SDimitry Andric 
8570b57cec5SDimitry Andric bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) {
8580b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_liveins));
8590b57cec5SDimitry Andric   lex();
8600b57cec5SDimitry Andric   if (expectAndConsume(MIToken::colon))
8610b57cec5SDimitry Andric     return true;
8620b57cec5SDimitry Andric   if (Token.isNewlineOrEOF()) // Allow an empty list of liveins.
8630b57cec5SDimitry Andric     return false;
8640b57cec5SDimitry Andric   do {
8650b57cec5SDimitry Andric     if (Token.isNot(MIToken::NamedRegister))
8660b57cec5SDimitry Andric       return error("expected a named register");
8675ffd83dbSDimitry Andric     Register Reg;
8680b57cec5SDimitry Andric     if (parseNamedRegister(Reg))
8690b57cec5SDimitry Andric       return true;
8700b57cec5SDimitry Andric     lex();
8710b57cec5SDimitry Andric     LaneBitmask Mask = LaneBitmask::getAll();
8720b57cec5SDimitry Andric     if (consumeIfPresent(MIToken::colon)) {
8730b57cec5SDimitry Andric       // Parse lane mask.
8740b57cec5SDimitry Andric       if (Token.isNot(MIToken::IntegerLiteral) &&
8750b57cec5SDimitry Andric           Token.isNot(MIToken::HexLiteral))
8760b57cec5SDimitry Andric         return error("expected a lane mask");
8775ffd83dbSDimitry Andric       static_assert(sizeof(LaneBitmask::Type) == sizeof(uint64_t),
8780b57cec5SDimitry Andric                     "Use correct get-function for lane mask");
8790b57cec5SDimitry Andric       LaneBitmask::Type V;
8805ffd83dbSDimitry Andric       if (getUint64(V))
8810b57cec5SDimitry Andric         return error("invalid lane mask value");
8820b57cec5SDimitry Andric       Mask = LaneBitmask(V);
8830b57cec5SDimitry Andric       lex();
8840b57cec5SDimitry Andric     }
8850b57cec5SDimitry Andric     MBB.addLiveIn(Reg, Mask);
8860b57cec5SDimitry Andric   } while (consumeIfPresent(MIToken::comma));
8870b57cec5SDimitry Andric   return false;
8880b57cec5SDimitry Andric }
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) {
8910b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_successors));
8920b57cec5SDimitry Andric   lex();
8930b57cec5SDimitry Andric   if (expectAndConsume(MIToken::colon))
8940b57cec5SDimitry Andric     return true;
8950b57cec5SDimitry Andric   if (Token.isNewlineOrEOF()) // Allow an empty list of successors.
8960b57cec5SDimitry Andric     return false;
8970b57cec5SDimitry Andric   do {
8980b57cec5SDimitry Andric     if (Token.isNot(MIToken::MachineBasicBlock))
8990b57cec5SDimitry Andric       return error("expected a machine basic block reference");
9000b57cec5SDimitry Andric     MachineBasicBlock *SuccMBB = nullptr;
9010b57cec5SDimitry Andric     if (parseMBBReference(SuccMBB))
9020b57cec5SDimitry Andric       return true;
9030b57cec5SDimitry Andric     lex();
9040b57cec5SDimitry Andric     unsigned Weight = 0;
9050b57cec5SDimitry Andric     if (consumeIfPresent(MIToken::lparen)) {
9060b57cec5SDimitry Andric       if (Token.isNot(MIToken::IntegerLiteral) &&
9070b57cec5SDimitry Andric           Token.isNot(MIToken::HexLiteral))
9080b57cec5SDimitry Andric         return error("expected an integer literal after '('");
9090b57cec5SDimitry Andric       if (getUnsigned(Weight))
9100b57cec5SDimitry Andric         return true;
9110b57cec5SDimitry Andric       lex();
9120b57cec5SDimitry Andric       if (expectAndConsume(MIToken::rparen))
9130b57cec5SDimitry Andric         return true;
9140b57cec5SDimitry Andric     }
9150b57cec5SDimitry Andric     MBB.addSuccessor(SuccMBB, BranchProbability::getRaw(Weight));
9160b57cec5SDimitry Andric   } while (consumeIfPresent(MIToken::comma));
9170b57cec5SDimitry Andric   MBB.normalizeSuccProbs();
9180b57cec5SDimitry Andric   return false;
9190b57cec5SDimitry Andric }
9200b57cec5SDimitry Andric 
9210b57cec5SDimitry Andric bool MIParser::parseBasicBlock(MachineBasicBlock &MBB,
9220b57cec5SDimitry Andric                                MachineBasicBlock *&AddFalthroughFrom) {
9230b57cec5SDimitry Andric   // Skip the definition.
9240b57cec5SDimitry Andric   assert(Token.is(MIToken::MachineBasicBlockLabel));
9250b57cec5SDimitry Andric   lex();
9260b57cec5SDimitry Andric   if (consumeIfPresent(MIToken::lparen)) {
9270b57cec5SDimitry Andric     while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF())
9280b57cec5SDimitry Andric       lex();
9290b57cec5SDimitry Andric     consumeIfPresent(MIToken::rparen);
9300b57cec5SDimitry Andric   }
9310b57cec5SDimitry Andric   consumeIfPresent(MIToken::colon);
9320b57cec5SDimitry Andric 
9330b57cec5SDimitry Andric   // Parse the liveins and successors.
9340b57cec5SDimitry Andric   // N.B: Multiple lists of successors and liveins are allowed and they're
9350b57cec5SDimitry Andric   // merged into one.
9360b57cec5SDimitry Andric   // Example:
93704eeddc0SDimitry Andric   //   liveins: $edi
93804eeddc0SDimitry Andric   //   liveins: $esi
9390b57cec5SDimitry Andric   //
9400b57cec5SDimitry Andric   // is equivalent to
94104eeddc0SDimitry Andric   //   liveins: $edi, $esi
9420b57cec5SDimitry Andric   bool ExplicitSuccessors = false;
9430b57cec5SDimitry Andric   while (true) {
9440b57cec5SDimitry Andric     if (Token.is(MIToken::kw_successors)) {
9450b57cec5SDimitry Andric       if (parseBasicBlockSuccessors(MBB))
9460b57cec5SDimitry Andric         return true;
9470b57cec5SDimitry Andric       ExplicitSuccessors = true;
9480b57cec5SDimitry Andric     } else if (Token.is(MIToken::kw_liveins)) {
9490b57cec5SDimitry Andric       if (parseBasicBlockLiveins(MBB))
9500b57cec5SDimitry Andric         return true;
9510b57cec5SDimitry Andric     } else if (consumeIfPresent(MIToken::Newline)) {
9520b57cec5SDimitry Andric       continue;
9530b57cec5SDimitry Andric     } else
9540b57cec5SDimitry Andric       break;
9550b57cec5SDimitry Andric     if (!Token.isNewlineOrEOF())
9560b57cec5SDimitry Andric       return error("expected line break at the end of a list");
9570b57cec5SDimitry Andric     lex();
9580b57cec5SDimitry Andric   }
9590b57cec5SDimitry Andric 
9600b57cec5SDimitry Andric   // Parse the instructions.
9610b57cec5SDimitry Andric   bool IsInBundle = false;
9620b57cec5SDimitry Andric   MachineInstr *PrevMI = nullptr;
9630b57cec5SDimitry Andric   while (!Token.is(MIToken::MachineBasicBlockLabel) &&
9640b57cec5SDimitry Andric          !Token.is(MIToken::Eof)) {
9650b57cec5SDimitry Andric     if (consumeIfPresent(MIToken::Newline))
9660b57cec5SDimitry Andric       continue;
9670b57cec5SDimitry Andric     if (consumeIfPresent(MIToken::rbrace)) {
9680b57cec5SDimitry Andric       // The first parsing pass should verify that all closing '}' have an
9690b57cec5SDimitry Andric       // opening '{'.
9700b57cec5SDimitry Andric       assert(IsInBundle);
9710b57cec5SDimitry Andric       IsInBundle = false;
9720b57cec5SDimitry Andric       continue;
9730b57cec5SDimitry Andric     }
9740b57cec5SDimitry Andric     MachineInstr *MI = nullptr;
9750b57cec5SDimitry Andric     if (parse(MI))
9760b57cec5SDimitry Andric       return true;
9770b57cec5SDimitry Andric     MBB.insert(MBB.end(), MI);
9780b57cec5SDimitry Andric     if (IsInBundle) {
9790b57cec5SDimitry Andric       PrevMI->setFlag(MachineInstr::BundledSucc);
9800b57cec5SDimitry Andric       MI->setFlag(MachineInstr::BundledPred);
9810b57cec5SDimitry Andric     }
9820b57cec5SDimitry Andric     PrevMI = MI;
9830b57cec5SDimitry Andric     if (Token.is(MIToken::lbrace)) {
9840b57cec5SDimitry Andric       if (IsInBundle)
9850b57cec5SDimitry Andric         return error("nested instruction bundles are not allowed");
9860b57cec5SDimitry Andric       lex();
9870b57cec5SDimitry Andric       // This instruction is the start of the bundle.
9880b57cec5SDimitry Andric       MI->setFlag(MachineInstr::BundledSucc);
9890b57cec5SDimitry Andric       IsInBundle = true;
9900b57cec5SDimitry Andric       if (!Token.is(MIToken::Newline))
9910b57cec5SDimitry Andric         // The next instruction can be on the same line.
9920b57cec5SDimitry Andric         continue;
9930b57cec5SDimitry Andric     }
9940b57cec5SDimitry Andric     assert(Token.isNewlineOrEOF() && "MI is not fully parsed");
9950b57cec5SDimitry Andric     lex();
9960b57cec5SDimitry Andric   }
9970b57cec5SDimitry Andric 
9980b57cec5SDimitry Andric   // Construct successor list by searching for basic block machine operands.
9990b57cec5SDimitry Andric   if (!ExplicitSuccessors) {
10000b57cec5SDimitry Andric     SmallVector<MachineBasicBlock*,4> Successors;
10010b57cec5SDimitry Andric     bool IsFallthrough;
10020b57cec5SDimitry Andric     guessSuccessors(MBB, Successors, IsFallthrough);
10030b57cec5SDimitry Andric     for (MachineBasicBlock *Succ : Successors)
10040b57cec5SDimitry Andric       MBB.addSuccessor(Succ);
10050b57cec5SDimitry Andric 
10060b57cec5SDimitry Andric     if (IsFallthrough) {
10070b57cec5SDimitry Andric       AddFalthroughFrom = &MBB;
10080b57cec5SDimitry Andric     } else {
10090b57cec5SDimitry Andric       MBB.normalizeSuccProbs();
10100b57cec5SDimitry Andric     }
10110b57cec5SDimitry Andric   }
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric   return false;
10140b57cec5SDimitry Andric }
10150b57cec5SDimitry Andric 
10160b57cec5SDimitry Andric bool MIParser::parseBasicBlocks() {
10170b57cec5SDimitry Andric   lex();
10180b57cec5SDimitry Andric   // Skip until the first machine basic block.
10190b57cec5SDimitry Andric   while (Token.is(MIToken::Newline))
10200b57cec5SDimitry Andric     lex();
10210b57cec5SDimitry Andric   if (Token.isErrorOrEOF())
10220b57cec5SDimitry Andric     return Token.isError();
10230b57cec5SDimitry Andric   // The first parsing pass should have verified that this token is a MBB label
10240b57cec5SDimitry Andric   // in the 'parseBasicBlockDefinitions' method.
10250b57cec5SDimitry Andric   assert(Token.is(MIToken::MachineBasicBlockLabel));
10260b57cec5SDimitry Andric   MachineBasicBlock *AddFalthroughFrom = nullptr;
10270b57cec5SDimitry Andric   do {
10280b57cec5SDimitry Andric     MachineBasicBlock *MBB = nullptr;
10290b57cec5SDimitry Andric     if (parseMBBReference(MBB))
10300b57cec5SDimitry Andric       return true;
10310b57cec5SDimitry Andric     if (AddFalthroughFrom) {
10320b57cec5SDimitry Andric       if (!AddFalthroughFrom->isSuccessor(MBB))
10330b57cec5SDimitry Andric         AddFalthroughFrom->addSuccessor(MBB);
10340b57cec5SDimitry Andric       AddFalthroughFrom->normalizeSuccProbs();
10350b57cec5SDimitry Andric       AddFalthroughFrom = nullptr;
10360b57cec5SDimitry Andric     }
10370b57cec5SDimitry Andric     if (parseBasicBlock(*MBB, AddFalthroughFrom))
10380b57cec5SDimitry Andric       return true;
10390b57cec5SDimitry Andric     // The method 'parseBasicBlock' should parse the whole block until the next
10400b57cec5SDimitry Andric     // block or the end of file.
10410b57cec5SDimitry Andric     assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof));
10420b57cec5SDimitry Andric   } while (Token.isNot(MIToken::Eof));
10430b57cec5SDimitry Andric   return false;
10440b57cec5SDimitry Andric }
10450b57cec5SDimitry Andric 
10460b57cec5SDimitry Andric bool MIParser::parse(MachineInstr *&MI) {
10470b57cec5SDimitry Andric   // Parse any register operands before '='
10480b57cec5SDimitry Andric   MachineOperand MO = MachineOperand::CreateImm(0);
10490b57cec5SDimitry Andric   SmallVector<ParsedMachineOperand, 8> Operands;
10500b57cec5SDimitry Andric   while (Token.isRegister() || Token.isRegisterFlag()) {
10510b57cec5SDimitry Andric     auto Loc = Token.location();
1052bdd1243dSDimitry Andric     std::optional<unsigned> TiedDefIdx;
10530b57cec5SDimitry Andric     if (parseRegisterOperand(MO, TiedDefIdx, /*IsDef=*/true))
10540b57cec5SDimitry Andric       return true;
10550b57cec5SDimitry Andric     Operands.push_back(
10560b57cec5SDimitry Andric         ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
10570b57cec5SDimitry Andric     if (Token.isNot(MIToken::comma))
10580b57cec5SDimitry Andric       break;
10590b57cec5SDimitry Andric     lex();
10600b57cec5SDimitry Andric   }
10610b57cec5SDimitry Andric   if (!Operands.empty() && expectAndConsume(MIToken::equal))
10620b57cec5SDimitry Andric     return true;
10630b57cec5SDimitry Andric 
10640b57cec5SDimitry Andric   unsigned OpCode, Flags = 0;
10650b57cec5SDimitry Andric   if (Token.isError() || parseInstruction(OpCode, Flags))
10660b57cec5SDimitry Andric     return true;
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric   // Parse the remaining machine operands.
10690b57cec5SDimitry Andric   while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) &&
10700b57cec5SDimitry Andric          Token.isNot(MIToken::kw_post_instr_symbol) &&
1071480093f4SDimitry Andric          Token.isNot(MIToken::kw_heap_alloc_marker) &&
1072bdd1243dSDimitry Andric          Token.isNot(MIToken::kw_pcsections) &&
1073bdd1243dSDimitry Andric          Token.isNot(MIToken::kw_cfi_type) &&
10740b57cec5SDimitry Andric          Token.isNot(MIToken::kw_debug_location) &&
1075e8d8bef9SDimitry Andric          Token.isNot(MIToken::kw_debug_instr_number) &&
10760b57cec5SDimitry Andric          Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) {
10770b57cec5SDimitry Andric     auto Loc = Token.location();
1078bdd1243dSDimitry Andric     std::optional<unsigned> TiedDefIdx;
1079480093f4SDimitry Andric     if (parseMachineOperandAndTargetFlags(OpCode, Operands.size(), MO, TiedDefIdx))
10800b57cec5SDimitry Andric       return true;
10810b57cec5SDimitry Andric     Operands.push_back(
10820b57cec5SDimitry Andric         ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx));
10830b57cec5SDimitry Andric     if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
10840b57cec5SDimitry Andric         Token.is(MIToken::lbrace))
10850b57cec5SDimitry Andric       break;
10860b57cec5SDimitry Andric     if (Token.isNot(MIToken::comma))
10870b57cec5SDimitry Andric       return error("expected ',' before the next machine operand");
10880b57cec5SDimitry Andric     lex();
10890b57cec5SDimitry Andric   }
10900b57cec5SDimitry Andric 
10910b57cec5SDimitry Andric   MCSymbol *PreInstrSymbol = nullptr;
10920b57cec5SDimitry Andric   if (Token.is(MIToken::kw_pre_instr_symbol))
10930b57cec5SDimitry Andric     if (parsePreOrPostInstrSymbol(PreInstrSymbol))
10940b57cec5SDimitry Andric       return true;
10950b57cec5SDimitry Andric   MCSymbol *PostInstrSymbol = nullptr;
10960b57cec5SDimitry Andric   if (Token.is(MIToken::kw_post_instr_symbol))
10970b57cec5SDimitry Andric     if (parsePreOrPostInstrSymbol(PostInstrSymbol))
10980b57cec5SDimitry Andric       return true;
1099480093f4SDimitry Andric   MDNode *HeapAllocMarker = nullptr;
1100480093f4SDimitry Andric   if (Token.is(MIToken::kw_heap_alloc_marker))
1101480093f4SDimitry Andric     if (parseHeapAllocMarker(HeapAllocMarker))
1102480093f4SDimitry Andric       return true;
1103bdd1243dSDimitry Andric   MDNode *PCSections = nullptr;
1104bdd1243dSDimitry Andric   if (Token.is(MIToken::kw_pcsections))
1105bdd1243dSDimitry Andric     if (parsePCSections(PCSections))
1106bdd1243dSDimitry Andric       return true;
1107bdd1243dSDimitry Andric 
1108bdd1243dSDimitry Andric   unsigned CFIType = 0;
1109bdd1243dSDimitry Andric   if (Token.is(MIToken::kw_cfi_type)) {
1110bdd1243dSDimitry Andric     lex();
1111bdd1243dSDimitry Andric     if (Token.isNot(MIToken::IntegerLiteral))
1112bdd1243dSDimitry Andric       return error("expected an integer literal after 'cfi-type'");
1113bdd1243dSDimitry Andric     // getUnsigned is sufficient for 32-bit integers.
1114bdd1243dSDimitry Andric     if (getUnsigned(CFIType))
1115bdd1243dSDimitry Andric       return true;
1116bdd1243dSDimitry Andric     lex();
1117bdd1243dSDimitry Andric     // Lex past trailing comma if present.
1118bdd1243dSDimitry Andric     if (Token.is(MIToken::comma))
1119bdd1243dSDimitry Andric       lex();
1120bdd1243dSDimitry Andric   }
11210b57cec5SDimitry Andric 
1122e8d8bef9SDimitry Andric   unsigned InstrNum = 0;
1123e8d8bef9SDimitry Andric   if (Token.is(MIToken::kw_debug_instr_number)) {
1124e8d8bef9SDimitry Andric     lex();
1125e8d8bef9SDimitry Andric     if (Token.isNot(MIToken::IntegerLiteral))
1126e8d8bef9SDimitry Andric       return error("expected an integer literal after 'debug-instr-number'");
1127e8d8bef9SDimitry Andric     if (getUnsigned(InstrNum))
1128e8d8bef9SDimitry Andric       return true;
1129e8d8bef9SDimitry Andric     lex();
1130e8d8bef9SDimitry Andric     // Lex past trailing comma if present.
1131e8d8bef9SDimitry Andric     if (Token.is(MIToken::comma))
1132e8d8bef9SDimitry Andric       lex();
1133e8d8bef9SDimitry Andric   }
1134e8d8bef9SDimitry Andric 
11350b57cec5SDimitry Andric   DebugLoc DebugLocation;
11360b57cec5SDimitry Andric   if (Token.is(MIToken::kw_debug_location)) {
11370b57cec5SDimitry Andric     lex();
11380b57cec5SDimitry Andric     MDNode *Node = nullptr;
11390b57cec5SDimitry Andric     if (Token.is(MIToken::exclaim)) {
11400b57cec5SDimitry Andric       if (parseMDNode(Node))
11410b57cec5SDimitry Andric         return true;
11420b57cec5SDimitry Andric     } else if (Token.is(MIToken::md_dilocation)) {
11430b57cec5SDimitry Andric       if (parseDILocation(Node))
11440b57cec5SDimitry Andric         return true;
11450b57cec5SDimitry Andric     } else
11460b57cec5SDimitry Andric       return error("expected a metadata node after 'debug-location'");
11470b57cec5SDimitry Andric     if (!isa<DILocation>(Node))
11480b57cec5SDimitry Andric       return error("referenced metadata is not a DILocation");
11490b57cec5SDimitry Andric     DebugLocation = DebugLoc(Node);
11500b57cec5SDimitry Andric   }
11510b57cec5SDimitry Andric 
11520b57cec5SDimitry Andric   // Parse the machine memory operands.
11530b57cec5SDimitry Andric   SmallVector<MachineMemOperand *, 2> MemOperands;
11540b57cec5SDimitry Andric   if (Token.is(MIToken::coloncolon)) {
11550b57cec5SDimitry Andric     lex();
11560b57cec5SDimitry Andric     while (!Token.isNewlineOrEOF()) {
11570b57cec5SDimitry Andric       MachineMemOperand *MemOp = nullptr;
11580b57cec5SDimitry Andric       if (parseMachineMemoryOperand(MemOp))
11590b57cec5SDimitry Andric         return true;
11600b57cec5SDimitry Andric       MemOperands.push_back(MemOp);
11610b57cec5SDimitry Andric       if (Token.isNewlineOrEOF())
11620b57cec5SDimitry Andric         break;
11630b57cec5SDimitry Andric       if (Token.isNot(MIToken::comma))
11640b57cec5SDimitry Andric         return error("expected ',' before the next machine memory operand");
11650b57cec5SDimitry Andric       lex();
11660b57cec5SDimitry Andric     }
11670b57cec5SDimitry Andric   }
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric   const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode);
11700b57cec5SDimitry Andric   if (!MCID.isVariadic()) {
11710b57cec5SDimitry Andric     // FIXME: Move the implicit operand verification to the machine verifier.
11720b57cec5SDimitry Andric     if (verifyImplicitOperands(Operands, MCID))
11730b57cec5SDimitry Andric       return true;
11740b57cec5SDimitry Andric   }
11750b57cec5SDimitry Andric 
11760b57cec5SDimitry Andric   MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true);
11770b57cec5SDimitry Andric   MI->setFlags(Flags);
117881ad6265SDimitry Andric 
11795f757f3fSDimitry Andric   // Don't check the operands make sense, let the verifier catch any
11805f757f3fSDimitry Andric   // improprieties.
11815f757f3fSDimitry Andric   for (const auto &Operand : Operands)
11820b57cec5SDimitry Andric     MI->addOperand(MF, Operand.Operand);
118381ad6265SDimitry Andric 
11840b57cec5SDimitry Andric   if (assignRegisterTies(*MI, Operands))
11850b57cec5SDimitry Andric     return true;
11860b57cec5SDimitry Andric   if (PreInstrSymbol)
11870b57cec5SDimitry Andric     MI->setPreInstrSymbol(MF, PreInstrSymbol);
11880b57cec5SDimitry Andric   if (PostInstrSymbol)
11890b57cec5SDimitry Andric     MI->setPostInstrSymbol(MF, PostInstrSymbol);
1190480093f4SDimitry Andric   if (HeapAllocMarker)
1191480093f4SDimitry Andric     MI->setHeapAllocMarker(MF, HeapAllocMarker);
1192bdd1243dSDimitry Andric   if (PCSections)
1193bdd1243dSDimitry Andric     MI->setPCSections(MF, PCSections);
1194bdd1243dSDimitry Andric   if (CFIType)
1195bdd1243dSDimitry Andric     MI->setCFIType(MF, CFIType);
11960b57cec5SDimitry Andric   if (!MemOperands.empty())
11970b57cec5SDimitry Andric     MI->setMemRefs(MF, MemOperands);
1198e8d8bef9SDimitry Andric   if (InstrNum)
1199e8d8bef9SDimitry Andric     MI->setDebugInstrNum(InstrNum);
12000b57cec5SDimitry Andric   return false;
12010b57cec5SDimitry Andric }
12020b57cec5SDimitry Andric 
12030b57cec5SDimitry Andric bool MIParser::parseStandaloneMBB(MachineBasicBlock *&MBB) {
12040b57cec5SDimitry Andric   lex();
12050b57cec5SDimitry Andric   if (Token.isNot(MIToken::MachineBasicBlock))
12060b57cec5SDimitry Andric     return error("expected a machine basic block reference");
12070b57cec5SDimitry Andric   if (parseMBBReference(MBB))
12080b57cec5SDimitry Andric     return true;
12090b57cec5SDimitry Andric   lex();
12100b57cec5SDimitry Andric   if (Token.isNot(MIToken::Eof))
12110b57cec5SDimitry Andric     return error(
12120b57cec5SDimitry Andric         "expected end of string after the machine basic block reference");
12130b57cec5SDimitry Andric   return false;
12140b57cec5SDimitry Andric }
12150b57cec5SDimitry Andric 
12165ffd83dbSDimitry Andric bool MIParser::parseStandaloneNamedRegister(Register &Reg) {
12170b57cec5SDimitry Andric   lex();
12180b57cec5SDimitry Andric   if (Token.isNot(MIToken::NamedRegister))
12190b57cec5SDimitry Andric     return error("expected a named register");
12200b57cec5SDimitry Andric   if (parseNamedRegister(Reg))
12210b57cec5SDimitry Andric     return true;
12220b57cec5SDimitry Andric   lex();
12230b57cec5SDimitry Andric   if (Token.isNot(MIToken::Eof))
12240b57cec5SDimitry Andric     return error("expected end of string after the register reference");
12250b57cec5SDimitry Andric   return false;
12260b57cec5SDimitry Andric }
12270b57cec5SDimitry Andric 
12280b57cec5SDimitry Andric bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) {
12290b57cec5SDimitry Andric   lex();
12300b57cec5SDimitry Andric   if (Token.isNot(MIToken::VirtualRegister))
12310b57cec5SDimitry Andric     return error("expected a virtual register");
12320b57cec5SDimitry Andric   if (parseVirtualRegister(Info))
12330b57cec5SDimitry Andric     return true;
12340b57cec5SDimitry Andric   lex();
12350b57cec5SDimitry Andric   if (Token.isNot(MIToken::Eof))
12360b57cec5SDimitry Andric     return error("expected end of string after the register reference");
12370b57cec5SDimitry Andric   return false;
12380b57cec5SDimitry Andric }
12390b57cec5SDimitry Andric 
12405ffd83dbSDimitry Andric bool MIParser::parseStandaloneRegister(Register &Reg) {
12410b57cec5SDimitry Andric   lex();
12420b57cec5SDimitry Andric   if (Token.isNot(MIToken::NamedRegister) &&
12430b57cec5SDimitry Andric       Token.isNot(MIToken::VirtualRegister))
12440b57cec5SDimitry Andric     return error("expected either a named or virtual register");
12450b57cec5SDimitry Andric 
12460b57cec5SDimitry Andric   VRegInfo *Info;
12470b57cec5SDimitry Andric   if (parseRegister(Reg, Info))
12480b57cec5SDimitry Andric     return true;
12490b57cec5SDimitry Andric 
12500b57cec5SDimitry Andric   lex();
12510b57cec5SDimitry Andric   if (Token.isNot(MIToken::Eof))
12520b57cec5SDimitry Andric     return error("expected end of string after the register reference");
12530b57cec5SDimitry Andric   return false;
12540b57cec5SDimitry Andric }
12550b57cec5SDimitry Andric 
12560b57cec5SDimitry Andric bool MIParser::parseStandaloneStackObject(int &FI) {
12570b57cec5SDimitry Andric   lex();
12580b57cec5SDimitry Andric   if (Token.isNot(MIToken::StackObject))
12590b57cec5SDimitry Andric     return error("expected a stack object");
12600b57cec5SDimitry Andric   if (parseStackFrameIndex(FI))
12610b57cec5SDimitry Andric     return true;
12620b57cec5SDimitry Andric   if (Token.isNot(MIToken::Eof))
12630b57cec5SDimitry Andric     return error("expected end of string after the stack object reference");
12640b57cec5SDimitry Andric   return false;
12650b57cec5SDimitry Andric }
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric bool MIParser::parseStandaloneMDNode(MDNode *&Node) {
12680b57cec5SDimitry Andric   lex();
12690b57cec5SDimitry Andric   if (Token.is(MIToken::exclaim)) {
12700b57cec5SDimitry Andric     if (parseMDNode(Node))
12710b57cec5SDimitry Andric       return true;
12720b57cec5SDimitry Andric   } else if (Token.is(MIToken::md_diexpr)) {
12730b57cec5SDimitry Andric     if (parseDIExpression(Node))
12740b57cec5SDimitry Andric       return true;
12750b57cec5SDimitry Andric   } else if (Token.is(MIToken::md_dilocation)) {
12760b57cec5SDimitry Andric     if (parseDILocation(Node))
12770b57cec5SDimitry Andric       return true;
12780b57cec5SDimitry Andric   } else
12790b57cec5SDimitry Andric     return error("expected a metadata node");
12800b57cec5SDimitry Andric   if (Token.isNot(MIToken::Eof))
12810b57cec5SDimitry Andric     return error("expected end of string after the metadata node");
12820b57cec5SDimitry Andric   return false;
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric 
1285fe6060f1SDimitry Andric bool MIParser::parseMachineMetadata() {
1286fe6060f1SDimitry Andric   lex();
1287fe6060f1SDimitry Andric   if (Token.isNot(MIToken::exclaim))
1288fe6060f1SDimitry Andric     return error("expected a metadata node");
1289fe6060f1SDimitry Andric 
1290fe6060f1SDimitry Andric   lex();
1291fe6060f1SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1292fe6060f1SDimitry Andric     return error("expected metadata id after '!'");
1293fe6060f1SDimitry Andric   unsigned ID = 0;
1294fe6060f1SDimitry Andric   if (getUnsigned(ID))
1295fe6060f1SDimitry Andric     return true;
1296fe6060f1SDimitry Andric   lex();
1297fe6060f1SDimitry Andric   if (expectAndConsume(MIToken::equal))
1298fe6060f1SDimitry Andric     return true;
1299fe6060f1SDimitry Andric   bool IsDistinct = Token.is(MIToken::kw_distinct);
1300fe6060f1SDimitry Andric   if (IsDistinct)
1301fe6060f1SDimitry Andric     lex();
1302fe6060f1SDimitry Andric   if (Token.isNot(MIToken::exclaim))
1303fe6060f1SDimitry Andric     return error("expected a metadata node");
1304fe6060f1SDimitry Andric   lex();
1305fe6060f1SDimitry Andric 
1306fe6060f1SDimitry Andric   MDNode *MD;
1307fe6060f1SDimitry Andric   if (parseMDTuple(MD, IsDistinct))
1308fe6060f1SDimitry Andric     return true;
1309fe6060f1SDimitry Andric 
1310fe6060f1SDimitry Andric   auto FI = PFS.MachineForwardRefMDNodes.find(ID);
1311fe6060f1SDimitry Andric   if (FI != PFS.MachineForwardRefMDNodes.end()) {
1312fe6060f1SDimitry Andric     FI->second.first->replaceAllUsesWith(MD);
1313fe6060f1SDimitry Andric     PFS.MachineForwardRefMDNodes.erase(FI);
1314fe6060f1SDimitry Andric 
1315fe6060f1SDimitry Andric     assert(PFS.MachineMetadataNodes[ID] == MD && "Tracking VH didn't work");
1316fe6060f1SDimitry Andric   } else {
1317fe6060f1SDimitry Andric     if (PFS.MachineMetadataNodes.count(ID))
1318fe6060f1SDimitry Andric       return error("Metadata id is already used");
1319fe6060f1SDimitry Andric     PFS.MachineMetadataNodes[ID].reset(MD);
1320fe6060f1SDimitry Andric   }
1321fe6060f1SDimitry Andric 
1322fe6060f1SDimitry Andric   return false;
1323fe6060f1SDimitry Andric }
1324fe6060f1SDimitry Andric 
1325fe6060f1SDimitry Andric bool MIParser::parseMDTuple(MDNode *&MD, bool IsDistinct) {
1326fe6060f1SDimitry Andric   SmallVector<Metadata *, 16> Elts;
1327fe6060f1SDimitry Andric   if (parseMDNodeVector(Elts))
1328fe6060f1SDimitry Andric     return true;
1329fe6060f1SDimitry Andric   MD = (IsDistinct ? MDTuple::getDistinct
1330fe6060f1SDimitry Andric                    : MDTuple::get)(MF.getFunction().getContext(), Elts);
1331fe6060f1SDimitry Andric   return false;
1332fe6060f1SDimitry Andric }
1333fe6060f1SDimitry Andric 
1334fe6060f1SDimitry Andric bool MIParser::parseMDNodeVector(SmallVectorImpl<Metadata *> &Elts) {
1335fe6060f1SDimitry Andric   if (Token.isNot(MIToken::lbrace))
1336fe6060f1SDimitry Andric     return error("expected '{' here");
1337fe6060f1SDimitry Andric   lex();
1338fe6060f1SDimitry Andric 
1339fe6060f1SDimitry Andric   if (Token.is(MIToken::rbrace)) {
1340fe6060f1SDimitry Andric     lex();
1341fe6060f1SDimitry Andric     return false;
1342fe6060f1SDimitry Andric   }
1343fe6060f1SDimitry Andric 
1344fe6060f1SDimitry Andric   do {
1345fe6060f1SDimitry Andric     Metadata *MD;
1346fe6060f1SDimitry Andric     if (parseMetadata(MD))
1347fe6060f1SDimitry Andric       return true;
1348fe6060f1SDimitry Andric 
1349fe6060f1SDimitry Andric     Elts.push_back(MD);
1350fe6060f1SDimitry Andric 
1351fe6060f1SDimitry Andric     if (Token.isNot(MIToken::comma))
1352fe6060f1SDimitry Andric       break;
1353fe6060f1SDimitry Andric     lex();
1354fe6060f1SDimitry Andric   } while (true);
1355fe6060f1SDimitry Andric 
1356fe6060f1SDimitry Andric   if (Token.isNot(MIToken::rbrace))
1357fe6060f1SDimitry Andric     return error("expected end of metadata node");
1358fe6060f1SDimitry Andric   lex();
1359fe6060f1SDimitry Andric 
1360fe6060f1SDimitry Andric   return false;
1361fe6060f1SDimitry Andric }
1362fe6060f1SDimitry Andric 
1363fe6060f1SDimitry Andric // ::= !42
1364fe6060f1SDimitry Andric // ::= !"string"
1365fe6060f1SDimitry Andric bool MIParser::parseMetadata(Metadata *&MD) {
1366fe6060f1SDimitry Andric   if (Token.isNot(MIToken::exclaim))
1367fe6060f1SDimitry Andric     return error("expected '!' here");
1368fe6060f1SDimitry Andric   lex();
1369fe6060f1SDimitry Andric 
1370fe6060f1SDimitry Andric   if (Token.is(MIToken::StringConstant)) {
1371fe6060f1SDimitry Andric     std::string Str;
1372fe6060f1SDimitry Andric     if (parseStringConstant(Str))
1373fe6060f1SDimitry Andric       return true;
1374fe6060f1SDimitry Andric     MD = MDString::get(MF.getFunction().getContext(), Str);
1375fe6060f1SDimitry Andric     return false;
1376fe6060f1SDimitry Andric   }
1377fe6060f1SDimitry Andric 
1378fe6060f1SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
1379fe6060f1SDimitry Andric     return error("expected metadata id after '!'");
1380fe6060f1SDimitry Andric 
1381fe6060f1SDimitry Andric   SMLoc Loc = mapSMLoc(Token.location());
1382fe6060f1SDimitry Andric 
1383fe6060f1SDimitry Andric   unsigned ID = 0;
1384fe6060f1SDimitry Andric   if (getUnsigned(ID))
1385fe6060f1SDimitry Andric     return true;
1386fe6060f1SDimitry Andric   lex();
1387fe6060f1SDimitry Andric 
1388fe6060f1SDimitry Andric   auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
1389fe6060f1SDimitry Andric   if (NodeInfo != PFS.IRSlots.MetadataNodes.end()) {
1390fe6060f1SDimitry Andric     MD = NodeInfo->second.get();
1391fe6060f1SDimitry Andric     return false;
1392fe6060f1SDimitry Andric   }
1393fe6060f1SDimitry Andric   // Check machine metadata.
1394fe6060f1SDimitry Andric   NodeInfo = PFS.MachineMetadataNodes.find(ID);
1395fe6060f1SDimitry Andric   if (NodeInfo != PFS.MachineMetadataNodes.end()) {
1396fe6060f1SDimitry Andric     MD = NodeInfo->second.get();
1397fe6060f1SDimitry Andric     return false;
1398fe6060f1SDimitry Andric   }
1399fe6060f1SDimitry Andric   // Forward reference.
1400fe6060f1SDimitry Andric   auto &FwdRef = PFS.MachineForwardRefMDNodes[ID];
1401fe6060f1SDimitry Andric   FwdRef = std::make_pair(
1402bdd1243dSDimitry Andric       MDTuple::getTemporary(MF.getFunction().getContext(), std::nullopt), Loc);
1403fe6060f1SDimitry Andric   PFS.MachineMetadataNodes[ID].reset(FwdRef.first.get());
1404fe6060f1SDimitry Andric   MD = FwdRef.first.get();
1405fe6060f1SDimitry Andric 
1406fe6060f1SDimitry Andric   return false;
1407fe6060f1SDimitry Andric }
1408fe6060f1SDimitry Andric 
14090b57cec5SDimitry Andric static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
14100b57cec5SDimitry Andric   assert(MO.isImplicit());
14110b57cec5SDimitry Andric   return MO.isDef() ? "implicit-def" : "implicit";
14120b57cec5SDimitry Andric }
14130b57cec5SDimitry Andric 
14140b57cec5SDimitry Andric static std::string getRegisterName(const TargetRegisterInfo *TRI,
14155ffd83dbSDimitry Andric                                    Register Reg) {
1416bdd1243dSDimitry Andric   assert(Reg.isPhysical() && "expected phys reg");
14170b57cec5SDimitry Andric   return StringRef(TRI->getName(Reg)).lower();
14180b57cec5SDimitry Andric }
14190b57cec5SDimitry Andric 
14200b57cec5SDimitry Andric /// Return true if the parsed machine operands contain a given machine operand.
14210b57cec5SDimitry Andric static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand,
14220b57cec5SDimitry Andric                                 ArrayRef<ParsedMachineOperand> Operands) {
14230b57cec5SDimitry Andric   for (const auto &I : Operands) {
14240b57cec5SDimitry Andric     if (ImplicitOperand.isIdenticalTo(I.Operand))
14250b57cec5SDimitry Andric       return true;
14260b57cec5SDimitry Andric   }
14270b57cec5SDimitry Andric   return false;
14280b57cec5SDimitry Andric }
14290b57cec5SDimitry Andric 
14300b57cec5SDimitry Andric bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,
14310b57cec5SDimitry Andric                                       const MCInstrDesc &MCID) {
14320b57cec5SDimitry Andric   if (MCID.isCall())
14330b57cec5SDimitry Andric     // We can't verify call instructions as they can contain arbitrary implicit
14340b57cec5SDimitry Andric     // register and register mask operands.
14350b57cec5SDimitry Andric     return false;
14360b57cec5SDimitry Andric 
14370b57cec5SDimitry Andric   // Gather all the expected implicit operands.
14380b57cec5SDimitry Andric   SmallVector<MachineOperand, 4> ImplicitOperands;
1439bdd1243dSDimitry Andric   for (MCPhysReg ImpDef : MCID.implicit_defs())
1440bdd1243dSDimitry Andric     ImplicitOperands.push_back(MachineOperand::CreateReg(ImpDef, true, true));
1441bdd1243dSDimitry Andric   for (MCPhysReg ImpUse : MCID.implicit_uses())
1442bdd1243dSDimitry Andric     ImplicitOperands.push_back(MachineOperand::CreateReg(ImpUse, false, true));
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric   const auto *TRI = MF.getSubtarget().getRegisterInfo();
14450b57cec5SDimitry Andric   assert(TRI && "Expected target register info");
14460b57cec5SDimitry Andric   for (const auto &I : ImplicitOperands) {
14470b57cec5SDimitry Andric     if (isImplicitOperandIn(I, Operands))
14480b57cec5SDimitry Andric       continue;
14490b57cec5SDimitry Andric     return error(Operands.empty() ? Token.location() : Operands.back().End,
14500b57cec5SDimitry Andric                  Twine("missing implicit register operand '") +
14510b57cec5SDimitry Andric                      printImplicitRegisterFlag(I) + " $" +
14520b57cec5SDimitry Andric                      getRegisterName(TRI, I.getReg()) + "'");
14530b57cec5SDimitry Andric   }
14540b57cec5SDimitry Andric   return false;
14550b57cec5SDimitry Andric }
14560b57cec5SDimitry Andric 
14570b57cec5SDimitry Andric bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
14580b57cec5SDimitry Andric   // Allow frame and fast math flags for OPCODE
14595f757f3fSDimitry Andric   // clang-format off
14600b57cec5SDimitry Andric   while (Token.is(MIToken::kw_frame_setup) ||
14610b57cec5SDimitry Andric          Token.is(MIToken::kw_frame_destroy) ||
14620b57cec5SDimitry Andric          Token.is(MIToken::kw_nnan) ||
14630b57cec5SDimitry Andric          Token.is(MIToken::kw_ninf) ||
14640b57cec5SDimitry Andric          Token.is(MIToken::kw_nsz) ||
14650b57cec5SDimitry Andric          Token.is(MIToken::kw_arcp) ||
14660b57cec5SDimitry Andric          Token.is(MIToken::kw_contract) ||
14670b57cec5SDimitry Andric          Token.is(MIToken::kw_afn) ||
14680b57cec5SDimitry Andric          Token.is(MIToken::kw_reassoc) ||
14690b57cec5SDimitry Andric          Token.is(MIToken::kw_nuw) ||
14700b57cec5SDimitry Andric          Token.is(MIToken::kw_nsw) ||
14710b57cec5SDimitry Andric          Token.is(MIToken::kw_exact) ||
147206c3fb27SDimitry Andric          Token.is(MIToken::kw_nofpexcept) ||
14735f757f3fSDimitry Andric          Token.is(MIToken::kw_noconvergent) ||
1474*0fca6ea1SDimitry Andric          Token.is(MIToken::kw_unpredictable) ||
1475*0fca6ea1SDimitry Andric          Token.is(MIToken::kw_nneg) ||
1476*0fca6ea1SDimitry Andric          Token.is(MIToken::kw_disjoint)) {
14775f757f3fSDimitry Andric     // clang-format on
14780b57cec5SDimitry Andric     // Mine frame and fast math flags
14790b57cec5SDimitry Andric     if (Token.is(MIToken::kw_frame_setup))
14800b57cec5SDimitry Andric       Flags |= MachineInstr::FrameSetup;
14810b57cec5SDimitry Andric     if (Token.is(MIToken::kw_frame_destroy))
14820b57cec5SDimitry Andric       Flags |= MachineInstr::FrameDestroy;
14830b57cec5SDimitry Andric     if (Token.is(MIToken::kw_nnan))
14840b57cec5SDimitry Andric       Flags |= MachineInstr::FmNoNans;
14850b57cec5SDimitry Andric     if (Token.is(MIToken::kw_ninf))
14860b57cec5SDimitry Andric       Flags |= MachineInstr::FmNoInfs;
14870b57cec5SDimitry Andric     if (Token.is(MIToken::kw_nsz))
14880b57cec5SDimitry Andric       Flags |= MachineInstr::FmNsz;
14890b57cec5SDimitry Andric     if (Token.is(MIToken::kw_arcp))
14900b57cec5SDimitry Andric       Flags |= MachineInstr::FmArcp;
14910b57cec5SDimitry Andric     if (Token.is(MIToken::kw_contract))
14920b57cec5SDimitry Andric       Flags |= MachineInstr::FmContract;
14930b57cec5SDimitry Andric     if (Token.is(MIToken::kw_afn))
14940b57cec5SDimitry Andric       Flags |= MachineInstr::FmAfn;
14950b57cec5SDimitry Andric     if (Token.is(MIToken::kw_reassoc))
14960b57cec5SDimitry Andric       Flags |= MachineInstr::FmReassoc;
14970b57cec5SDimitry Andric     if (Token.is(MIToken::kw_nuw))
14980b57cec5SDimitry Andric       Flags |= MachineInstr::NoUWrap;
14990b57cec5SDimitry Andric     if (Token.is(MIToken::kw_nsw))
15000b57cec5SDimitry Andric       Flags |= MachineInstr::NoSWrap;
15010b57cec5SDimitry Andric     if (Token.is(MIToken::kw_exact))
15020b57cec5SDimitry Andric       Flags |= MachineInstr::IsExact;
1503480093f4SDimitry Andric     if (Token.is(MIToken::kw_nofpexcept))
1504480093f4SDimitry Andric       Flags |= MachineInstr::NoFPExcept;
150506c3fb27SDimitry Andric     if (Token.is(MIToken::kw_unpredictable))
150606c3fb27SDimitry Andric       Flags |= MachineInstr::Unpredictable;
15075f757f3fSDimitry Andric     if (Token.is(MIToken::kw_noconvergent))
15085f757f3fSDimitry Andric       Flags |= MachineInstr::NoConvergent;
1509*0fca6ea1SDimitry Andric     if (Token.is(MIToken::kw_nneg))
1510*0fca6ea1SDimitry Andric       Flags |= MachineInstr::NonNeg;
1511*0fca6ea1SDimitry Andric     if (Token.is(MIToken::kw_disjoint))
1512*0fca6ea1SDimitry Andric       Flags |= MachineInstr::Disjoint;
15130b57cec5SDimitry Andric 
15140b57cec5SDimitry Andric     lex();
15150b57cec5SDimitry Andric   }
15160b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier))
15170b57cec5SDimitry Andric     return error("expected a machine instruction");
15180b57cec5SDimitry Andric   StringRef InstrName = Token.stringValue();
15190b57cec5SDimitry Andric   if (PFS.Target.parseInstrName(InstrName, OpCode))
15200b57cec5SDimitry Andric     return error(Twine("unknown machine instruction name '") + InstrName + "'");
15210b57cec5SDimitry Andric   lex();
15220b57cec5SDimitry Andric   return false;
15230b57cec5SDimitry Andric }
15240b57cec5SDimitry Andric 
15255ffd83dbSDimitry Andric bool MIParser::parseNamedRegister(Register &Reg) {
15260b57cec5SDimitry Andric   assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token");
15270b57cec5SDimitry Andric   StringRef Name = Token.stringValue();
15280b57cec5SDimitry Andric   if (PFS.Target.getRegisterByName(Name, Reg))
15290b57cec5SDimitry Andric     return error(Twine("unknown register name '") + Name + "'");
15300b57cec5SDimitry Andric   return false;
15310b57cec5SDimitry Andric }
15320b57cec5SDimitry Andric 
15330b57cec5SDimitry Andric bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) {
15340b57cec5SDimitry Andric   assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token");
15350b57cec5SDimitry Andric   StringRef Name = Token.stringValue();
15360b57cec5SDimitry Andric   // TODO: Check that the VReg name is not the same as a physical register name.
15370b57cec5SDimitry Andric   //       If it is, then print a warning (when warnings are implemented).
15380b57cec5SDimitry Andric   Info = &PFS.getVRegInfoNamed(Name);
15390b57cec5SDimitry Andric   return false;
15400b57cec5SDimitry Andric }
15410b57cec5SDimitry Andric 
15420b57cec5SDimitry Andric bool MIParser::parseVirtualRegister(VRegInfo *&Info) {
15430b57cec5SDimitry Andric   if (Token.is(MIToken::NamedVirtualRegister))
15440b57cec5SDimitry Andric     return parseNamedVirtualRegister(Info);
15450b57cec5SDimitry Andric   assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token");
15460b57cec5SDimitry Andric   unsigned ID;
15470b57cec5SDimitry Andric   if (getUnsigned(ID))
15480b57cec5SDimitry Andric     return true;
15490b57cec5SDimitry Andric   Info = &PFS.getVRegInfo(ID);
15500b57cec5SDimitry Andric   return false;
15510b57cec5SDimitry Andric }
15520b57cec5SDimitry Andric 
15535ffd83dbSDimitry Andric bool MIParser::parseRegister(Register &Reg, VRegInfo *&Info) {
15540b57cec5SDimitry Andric   switch (Token.kind()) {
15550b57cec5SDimitry Andric   case MIToken::underscore:
15560b57cec5SDimitry Andric     Reg = 0;
15570b57cec5SDimitry Andric     return false;
15580b57cec5SDimitry Andric   case MIToken::NamedRegister:
15590b57cec5SDimitry Andric     return parseNamedRegister(Reg);
15600b57cec5SDimitry Andric   case MIToken::NamedVirtualRegister:
15610b57cec5SDimitry Andric   case MIToken::VirtualRegister:
15620b57cec5SDimitry Andric     if (parseVirtualRegister(Info))
15630b57cec5SDimitry Andric       return true;
15640b57cec5SDimitry Andric     Reg = Info->VReg;
15650b57cec5SDimitry Andric     return false;
15660b57cec5SDimitry Andric   // TODO: Parse other register kinds.
15670b57cec5SDimitry Andric   default:
15680b57cec5SDimitry Andric     llvm_unreachable("The current token should be a register");
15690b57cec5SDimitry Andric   }
15700b57cec5SDimitry Andric }
15710b57cec5SDimitry Andric 
15720b57cec5SDimitry Andric bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
15730b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore))
15740b57cec5SDimitry Andric     return error("expected '_', register class, or register bank name");
15750b57cec5SDimitry Andric   StringRef::iterator Loc = Token.location();
15760b57cec5SDimitry Andric   StringRef Name = Token.stringValue();
15770b57cec5SDimitry Andric 
15780b57cec5SDimitry Andric   // Was it a register class?
15790b57cec5SDimitry Andric   const TargetRegisterClass *RC = PFS.Target.getRegClass(Name);
15800b57cec5SDimitry Andric   if (RC) {
15810b57cec5SDimitry Andric     lex();
15820b57cec5SDimitry Andric 
15830b57cec5SDimitry Andric     switch (RegInfo.Kind) {
15840b57cec5SDimitry Andric     case VRegInfo::UNKNOWN:
15850b57cec5SDimitry Andric     case VRegInfo::NORMAL:
15860b57cec5SDimitry Andric       RegInfo.Kind = VRegInfo::NORMAL;
15870b57cec5SDimitry Andric       if (RegInfo.Explicit && RegInfo.D.RC != RC) {
15880b57cec5SDimitry Andric         const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
15890b57cec5SDimitry Andric         return error(Loc, Twine("conflicting register classes, previously: ") +
15900b57cec5SDimitry Andric                      Twine(TRI.getRegClassName(RegInfo.D.RC)));
15910b57cec5SDimitry Andric       }
15920b57cec5SDimitry Andric       RegInfo.D.RC = RC;
15930b57cec5SDimitry Andric       RegInfo.Explicit = true;
15940b57cec5SDimitry Andric       return false;
15950b57cec5SDimitry Andric 
15960b57cec5SDimitry Andric     case VRegInfo::GENERIC:
15970b57cec5SDimitry Andric     case VRegInfo::REGBANK:
15980b57cec5SDimitry Andric       return error(Loc, "register class specification on generic register");
15990b57cec5SDimitry Andric     }
16000b57cec5SDimitry Andric     llvm_unreachable("Unexpected register kind");
16010b57cec5SDimitry Andric   }
16020b57cec5SDimitry Andric 
16030b57cec5SDimitry Andric   // Should be a register bank or a generic register.
16040b57cec5SDimitry Andric   const RegisterBank *RegBank = nullptr;
16050b57cec5SDimitry Andric   if (Name != "_") {
16060b57cec5SDimitry Andric     RegBank = PFS.Target.getRegBank(Name);
16070b57cec5SDimitry Andric     if (!RegBank)
16080b57cec5SDimitry Andric       return error(Loc, "expected '_', register class, or register bank name");
16090b57cec5SDimitry Andric   }
16100b57cec5SDimitry Andric 
16110b57cec5SDimitry Andric   lex();
16120b57cec5SDimitry Andric 
16130b57cec5SDimitry Andric   switch (RegInfo.Kind) {
16140b57cec5SDimitry Andric   case VRegInfo::UNKNOWN:
16150b57cec5SDimitry Andric   case VRegInfo::GENERIC:
16160b57cec5SDimitry Andric   case VRegInfo::REGBANK:
16170b57cec5SDimitry Andric     RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC;
16180b57cec5SDimitry Andric     if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank)
16190b57cec5SDimitry Andric       return error(Loc, "conflicting generic register banks");
16200b57cec5SDimitry Andric     RegInfo.D.RegBank = RegBank;
16210b57cec5SDimitry Andric     RegInfo.Explicit = true;
16220b57cec5SDimitry Andric     return false;
16230b57cec5SDimitry Andric 
16240b57cec5SDimitry Andric   case VRegInfo::NORMAL:
16250b57cec5SDimitry Andric     return error(Loc, "register bank specification on normal register");
16260b57cec5SDimitry Andric   }
16270b57cec5SDimitry Andric   llvm_unreachable("Unexpected register kind");
16280b57cec5SDimitry Andric }
16290b57cec5SDimitry Andric 
16300b57cec5SDimitry Andric bool MIParser::parseRegisterFlag(unsigned &Flags) {
16310b57cec5SDimitry Andric   const unsigned OldFlags = Flags;
16320b57cec5SDimitry Andric   switch (Token.kind()) {
16330b57cec5SDimitry Andric   case MIToken::kw_implicit:
16340b57cec5SDimitry Andric     Flags |= RegState::Implicit;
16350b57cec5SDimitry Andric     break;
16360b57cec5SDimitry Andric   case MIToken::kw_implicit_define:
16370b57cec5SDimitry Andric     Flags |= RegState::ImplicitDefine;
16380b57cec5SDimitry Andric     break;
16390b57cec5SDimitry Andric   case MIToken::kw_def:
16400b57cec5SDimitry Andric     Flags |= RegState::Define;
16410b57cec5SDimitry Andric     break;
16420b57cec5SDimitry Andric   case MIToken::kw_dead:
16430b57cec5SDimitry Andric     Flags |= RegState::Dead;
16440b57cec5SDimitry Andric     break;
16450b57cec5SDimitry Andric   case MIToken::kw_killed:
16460b57cec5SDimitry Andric     Flags |= RegState::Kill;
16470b57cec5SDimitry Andric     break;
16480b57cec5SDimitry Andric   case MIToken::kw_undef:
16490b57cec5SDimitry Andric     Flags |= RegState::Undef;
16500b57cec5SDimitry Andric     break;
16510b57cec5SDimitry Andric   case MIToken::kw_internal:
16520b57cec5SDimitry Andric     Flags |= RegState::InternalRead;
16530b57cec5SDimitry Andric     break;
16540b57cec5SDimitry Andric   case MIToken::kw_early_clobber:
16550b57cec5SDimitry Andric     Flags |= RegState::EarlyClobber;
16560b57cec5SDimitry Andric     break;
16570b57cec5SDimitry Andric   case MIToken::kw_debug_use:
16580b57cec5SDimitry Andric     Flags |= RegState::Debug;
16590b57cec5SDimitry Andric     break;
16600b57cec5SDimitry Andric   case MIToken::kw_renamable:
16610b57cec5SDimitry Andric     Flags |= RegState::Renamable;
16620b57cec5SDimitry Andric     break;
16630b57cec5SDimitry Andric   default:
16640b57cec5SDimitry Andric     llvm_unreachable("The current token should be a register flag");
16650b57cec5SDimitry Andric   }
16660b57cec5SDimitry Andric   if (OldFlags == Flags)
16670b57cec5SDimitry Andric     // We know that the same flag is specified more than once when the flags
16680b57cec5SDimitry Andric     // weren't modified.
16690b57cec5SDimitry Andric     return error("duplicate '" + Token.stringValue() + "' register flag");
16700b57cec5SDimitry Andric   lex();
16710b57cec5SDimitry Andric   return false;
16720b57cec5SDimitry Andric }
16730b57cec5SDimitry Andric 
16740b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
16750b57cec5SDimitry Andric   assert(Token.is(MIToken::dot));
16760b57cec5SDimitry Andric   lex();
16770b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier))
16780b57cec5SDimitry Andric     return error("expected a subregister index after '.'");
16790b57cec5SDimitry Andric   auto Name = Token.stringValue();
16800b57cec5SDimitry Andric   SubReg = PFS.Target.getSubRegIndex(Name);
16810b57cec5SDimitry Andric   if (!SubReg)
16820b57cec5SDimitry Andric     return error(Twine("use of unknown subregister index '") + Name + "'");
16830b57cec5SDimitry Andric   lex();
16840b57cec5SDimitry Andric   return false;
16850b57cec5SDimitry Andric }
16860b57cec5SDimitry Andric 
16870b57cec5SDimitry Andric bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
16880b57cec5SDimitry Andric   if (!consumeIfPresent(MIToken::kw_tied_def))
16890b57cec5SDimitry Andric     return true;
16900b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral))
16910b57cec5SDimitry Andric     return error("expected an integer literal after 'tied-def'");
16920b57cec5SDimitry Andric   if (getUnsigned(TiedDefIdx))
16930b57cec5SDimitry Andric     return true;
16940b57cec5SDimitry Andric   lex();
16950b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
16960b57cec5SDimitry Andric     return true;
16970b57cec5SDimitry Andric   return false;
16980b57cec5SDimitry Andric }
16990b57cec5SDimitry Andric 
17000b57cec5SDimitry Andric bool MIParser::assignRegisterTies(MachineInstr &MI,
17010b57cec5SDimitry Andric                                   ArrayRef<ParsedMachineOperand> Operands) {
17020b57cec5SDimitry Andric   SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs;
17030b57cec5SDimitry Andric   for (unsigned I = 0, E = Operands.size(); I != E; ++I) {
17040b57cec5SDimitry Andric     if (!Operands[I].TiedDefIdx)
17050b57cec5SDimitry Andric       continue;
17060b57cec5SDimitry Andric     // The parser ensures that this operand is a register use, so we just have
17070b57cec5SDimitry Andric     // to check the tied-def operand.
170881ad6265SDimitry Andric     unsigned DefIdx = *Operands[I].TiedDefIdx;
17090b57cec5SDimitry Andric     if (DefIdx >= E)
17100b57cec5SDimitry Andric       return error(Operands[I].Begin,
17110b57cec5SDimitry Andric                    Twine("use of invalid tied-def operand index '" +
17120b57cec5SDimitry Andric                          Twine(DefIdx) + "'; instruction has only ") +
17130b57cec5SDimitry Andric                        Twine(E) + " operands");
17140b57cec5SDimitry Andric     const auto &DefOperand = Operands[DefIdx].Operand;
17150b57cec5SDimitry Andric     if (!DefOperand.isReg() || !DefOperand.isDef())
17160b57cec5SDimitry Andric       // FIXME: add note with the def operand.
17170b57cec5SDimitry Andric       return error(Operands[I].Begin,
17180b57cec5SDimitry Andric                    Twine("use of invalid tied-def operand index '") +
17190b57cec5SDimitry Andric                        Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) +
17200b57cec5SDimitry Andric                        " isn't a defined register");
17210b57cec5SDimitry Andric     // Check that the tied-def operand wasn't tied elsewhere.
17220b57cec5SDimitry Andric     for (const auto &TiedPair : TiedRegisterPairs) {
17230b57cec5SDimitry Andric       if (TiedPair.first == DefIdx)
17240b57cec5SDimitry Andric         return error(Operands[I].Begin,
17250b57cec5SDimitry Andric                      Twine("the tied-def operand #") + Twine(DefIdx) +
17260b57cec5SDimitry Andric                          " is already tied with another register operand");
17270b57cec5SDimitry Andric     }
17280b57cec5SDimitry Andric     TiedRegisterPairs.push_back(std::make_pair(DefIdx, I));
17290b57cec5SDimitry Andric   }
17300b57cec5SDimitry Andric   // FIXME: Verify that for non INLINEASM instructions, the def and use tied
17310b57cec5SDimitry Andric   // indices must be less than tied max.
17320b57cec5SDimitry Andric   for (const auto &TiedPair : TiedRegisterPairs)
17330b57cec5SDimitry Andric     MI.tieOperands(TiedPair.first, TiedPair.second);
17340b57cec5SDimitry Andric   return false;
17350b57cec5SDimitry Andric }
17360b57cec5SDimitry Andric 
17370b57cec5SDimitry Andric bool MIParser::parseRegisterOperand(MachineOperand &Dest,
1738bdd1243dSDimitry Andric                                     std::optional<unsigned> &TiedDefIdx,
17390b57cec5SDimitry Andric                                     bool IsDef) {
17400b57cec5SDimitry Andric   unsigned Flags = IsDef ? RegState::Define : 0;
17410b57cec5SDimitry Andric   while (Token.isRegisterFlag()) {
17420b57cec5SDimitry Andric     if (parseRegisterFlag(Flags))
17430b57cec5SDimitry Andric       return true;
17440b57cec5SDimitry Andric   }
17450b57cec5SDimitry Andric   if (!Token.isRegister())
17460b57cec5SDimitry Andric     return error("expected a register after register flags");
17475ffd83dbSDimitry Andric   Register Reg;
17480b57cec5SDimitry Andric   VRegInfo *RegInfo;
17490b57cec5SDimitry Andric   if (parseRegister(Reg, RegInfo))
17500b57cec5SDimitry Andric     return true;
17510b57cec5SDimitry Andric   lex();
17520b57cec5SDimitry Andric   unsigned SubReg = 0;
17530b57cec5SDimitry Andric   if (Token.is(MIToken::dot)) {
17540b57cec5SDimitry Andric     if (parseSubRegisterIndex(SubReg))
17550b57cec5SDimitry Andric       return true;
1756bdd1243dSDimitry Andric     if (!Reg.isVirtual())
17570b57cec5SDimitry Andric       return error("subregister index expects a virtual register");
17580b57cec5SDimitry Andric   }
17590b57cec5SDimitry Andric   if (Token.is(MIToken::colon)) {
1760bdd1243dSDimitry Andric     if (!Reg.isVirtual())
17610b57cec5SDimitry Andric       return error("register class specification expects a virtual register");
17620b57cec5SDimitry Andric     lex();
17630b57cec5SDimitry Andric     if (parseRegisterClassOrBank(*RegInfo))
17640b57cec5SDimitry Andric         return true;
17650b57cec5SDimitry Andric   }
17660b57cec5SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
17670b57cec5SDimitry Andric   if ((Flags & RegState::Define) == 0) {
17680b57cec5SDimitry Andric     if (consumeIfPresent(MIToken::lparen)) {
17690b57cec5SDimitry Andric       unsigned Idx;
17700b57cec5SDimitry Andric       if (!parseRegisterTiedDefIndex(Idx))
17710b57cec5SDimitry Andric         TiedDefIdx = Idx;
17720b57cec5SDimitry Andric       else {
17730b57cec5SDimitry Andric         // Try a redundant low-level type.
17740b57cec5SDimitry Andric         LLT Ty;
17750b57cec5SDimitry Andric         if (parseLowLevelType(Token.location(), Ty))
17760b57cec5SDimitry Andric           return error("expected tied-def or low-level type after '('");
17770b57cec5SDimitry Andric 
17780b57cec5SDimitry Andric         if (expectAndConsume(MIToken::rparen))
17790b57cec5SDimitry Andric           return true;
17800b57cec5SDimitry Andric 
17810b57cec5SDimitry Andric         if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
17820b57cec5SDimitry Andric           return error("inconsistent type for generic virtual register");
17830b57cec5SDimitry Andric 
17848bcb0991SDimitry Andric         MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
17850b57cec5SDimitry Andric         MRI.setType(Reg, Ty);
17860b57cec5SDimitry Andric       }
17870b57cec5SDimitry Andric     }
17880b57cec5SDimitry Andric   } else if (consumeIfPresent(MIToken::lparen)) {
17890b57cec5SDimitry Andric     // Virtual registers may have a tpe with GlobalISel.
1790bdd1243dSDimitry Andric     if (!Reg.isVirtual())
17910b57cec5SDimitry Andric       return error("unexpected type on physical register");
17920b57cec5SDimitry Andric 
17930b57cec5SDimitry Andric     LLT Ty;
17940b57cec5SDimitry Andric     if (parseLowLevelType(Token.location(), Ty))
17950b57cec5SDimitry Andric       return true;
17960b57cec5SDimitry Andric 
17970b57cec5SDimitry Andric     if (expectAndConsume(MIToken::rparen))
17980b57cec5SDimitry Andric       return true;
17990b57cec5SDimitry Andric 
18000b57cec5SDimitry Andric     if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
18010b57cec5SDimitry Andric       return error("inconsistent type for generic virtual register");
18020b57cec5SDimitry Andric 
18038bcb0991SDimitry Andric     MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
18040b57cec5SDimitry Andric     MRI.setType(Reg, Ty);
1805bdd1243dSDimitry Andric   } else if (Reg.isVirtual()) {
18060b57cec5SDimitry Andric     // Generic virtual registers must have a type.
18070b57cec5SDimitry Andric     // If we end up here this means the type hasn't been specified and
18080b57cec5SDimitry Andric     // this is bad!
18090b57cec5SDimitry Andric     if (RegInfo->Kind == VRegInfo::GENERIC ||
18100b57cec5SDimitry Andric         RegInfo->Kind == VRegInfo::REGBANK)
18110b57cec5SDimitry Andric       return error("generic virtual registers must have a type");
18120b57cec5SDimitry Andric   }
181381ad6265SDimitry Andric 
181481ad6265SDimitry Andric   if (Flags & RegState::Define) {
181581ad6265SDimitry Andric     if (Flags & RegState::Kill)
181681ad6265SDimitry Andric       return error("cannot have a killed def operand");
181781ad6265SDimitry Andric   } else {
181881ad6265SDimitry Andric     if (Flags & RegState::Dead)
181981ad6265SDimitry Andric       return error("cannot have a dead use operand");
182081ad6265SDimitry Andric   }
182181ad6265SDimitry Andric 
18220b57cec5SDimitry Andric   Dest = MachineOperand::CreateReg(
18230b57cec5SDimitry Andric       Reg, Flags & RegState::Define, Flags & RegState::Implicit,
18240b57cec5SDimitry Andric       Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef,
18250b57cec5SDimitry Andric       Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug,
18260b57cec5SDimitry Andric       Flags & RegState::InternalRead, Flags & RegState::Renamable);
18270b57cec5SDimitry Andric 
18280b57cec5SDimitry Andric   return false;
18290b57cec5SDimitry Andric }
18300b57cec5SDimitry Andric 
18310b57cec5SDimitry Andric bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
18320b57cec5SDimitry Andric   assert(Token.is(MIToken::IntegerLiteral));
18330b57cec5SDimitry Andric   const APSInt &Int = Token.integerValue();
1834bdd1243dSDimitry Andric   if (auto SImm = Int.trySExtValue(); Int.isSigned() && SImm.has_value())
1835bdd1243dSDimitry Andric     Dest = MachineOperand::CreateImm(*SImm);
1836bdd1243dSDimitry Andric   else if (auto UImm = Int.tryZExtValue(); !Int.isSigned() && UImm.has_value())
1837bdd1243dSDimitry Andric     Dest = MachineOperand::CreateImm(*UImm);
1838bdd1243dSDimitry Andric   else
18390b57cec5SDimitry Andric     return error("integer literal is too large to be an immediate operand");
18400b57cec5SDimitry Andric   lex();
18410b57cec5SDimitry Andric   return false;
18420b57cec5SDimitry Andric }
18430b57cec5SDimitry Andric 
1844480093f4SDimitry Andric bool MIParser::parseTargetImmMnemonic(const unsigned OpCode,
1845480093f4SDimitry Andric                                       const unsigned OpIdx,
1846480093f4SDimitry Andric                                       MachineOperand &Dest,
1847480093f4SDimitry Andric                                       const MIRFormatter &MF) {
1848480093f4SDimitry Andric   assert(Token.is(MIToken::dot));
1849480093f4SDimitry Andric   auto Loc = Token.location(); // record start position
1850480093f4SDimitry Andric   size_t Len = 1;              // for "."
1851480093f4SDimitry Andric   lex();
1852480093f4SDimitry Andric 
1853480093f4SDimitry Andric   // Handle the case that mnemonic starts with number.
1854480093f4SDimitry Andric   if (Token.is(MIToken::IntegerLiteral)) {
1855480093f4SDimitry Andric     Len += Token.range().size();
1856480093f4SDimitry Andric     lex();
1857480093f4SDimitry Andric   }
1858480093f4SDimitry Andric 
1859480093f4SDimitry Andric   StringRef Src;
1860480093f4SDimitry Andric   if (Token.is(MIToken::comma))
1861480093f4SDimitry Andric     Src = StringRef(Loc, Len);
1862480093f4SDimitry Andric   else {
1863480093f4SDimitry Andric     assert(Token.is(MIToken::Identifier));
1864480093f4SDimitry Andric     Src = StringRef(Loc, Len + Token.stringValue().size());
1865480093f4SDimitry Andric   }
1866480093f4SDimitry Andric   int64_t Val;
1867480093f4SDimitry Andric   if (MF.parseImmMnemonic(OpCode, OpIdx, Src, Val,
1868480093f4SDimitry Andric                           [this](StringRef::iterator Loc, const Twine &Msg)
1869480093f4SDimitry Andric                               -> bool { return error(Loc, Msg); }))
1870480093f4SDimitry Andric     return true;
1871480093f4SDimitry Andric 
1872480093f4SDimitry Andric   Dest = MachineOperand::CreateImm(Val);
1873480093f4SDimitry Andric   if (!Token.is(MIToken::comma))
1874480093f4SDimitry Andric     lex();
1875480093f4SDimitry Andric   return false;
1876480093f4SDimitry Andric }
1877480093f4SDimitry Andric 
1878480093f4SDimitry Andric static bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1879480093f4SDimitry Andric                             PerFunctionMIParsingState &PFS, const Constant *&C,
1880480093f4SDimitry Andric                             ErrorCallbackType ErrCB) {
18810b57cec5SDimitry Andric   auto Source = StringValue.str(); // The source has to be null terminated.
18820b57cec5SDimitry Andric   SMDiagnostic Err;
1883480093f4SDimitry Andric   C = parseConstantValue(Source, Err, *PFS.MF.getFunction().getParent(),
18840b57cec5SDimitry Andric                          &PFS.IRSlots);
18850b57cec5SDimitry Andric   if (!C)
1886480093f4SDimitry Andric     return ErrCB(Loc + Err.getColumnNo(), Err.getMessage());
18870b57cec5SDimitry Andric   return false;
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric 
1890480093f4SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1891480093f4SDimitry Andric                                const Constant *&C) {
1892480093f4SDimitry Andric   return ::parseIRConstant(
1893480093f4SDimitry Andric       Loc, StringValue, PFS, C,
1894480093f4SDimitry Andric       [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
1895480093f4SDimitry Andric         return error(Loc, Msg);
1896480093f4SDimitry Andric       });
1897480093f4SDimitry Andric }
1898480093f4SDimitry Andric 
18990b57cec5SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
19000b57cec5SDimitry Andric   if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C))
19010b57cec5SDimitry Andric     return true;
19020b57cec5SDimitry Andric   lex();
19030b57cec5SDimitry Andric   return false;
19040b57cec5SDimitry Andric }
19050b57cec5SDimitry Andric 
1906bdd1243dSDimitry Andric // See LLT implementation for bit size limits.
19070b57cec5SDimitry Andric static bool verifyScalarSize(uint64_t Size) {
19080b57cec5SDimitry Andric   return Size != 0 && isUInt<16>(Size);
19090b57cec5SDimitry Andric }
19100b57cec5SDimitry Andric 
19110b57cec5SDimitry Andric static bool verifyVectorElementCount(uint64_t NumElts) {
19120b57cec5SDimitry Andric   return NumElts != 0 && isUInt<16>(NumElts);
19130b57cec5SDimitry Andric }
19140b57cec5SDimitry Andric 
19150b57cec5SDimitry Andric static bool verifyAddrSpace(uint64_t AddrSpace) {
19160b57cec5SDimitry Andric   return isUInt<24>(AddrSpace);
19170b57cec5SDimitry Andric }
19180b57cec5SDimitry Andric 
19190b57cec5SDimitry Andric bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
19200b57cec5SDimitry Andric   if (Token.range().front() == 's' || Token.range().front() == 'p') {
19210b57cec5SDimitry Andric     StringRef SizeStr = Token.range().drop_front();
19220b57cec5SDimitry Andric     if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
19230b57cec5SDimitry Andric       return error("expected integers after 's'/'p' type character");
19240b57cec5SDimitry Andric   }
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric   if (Token.range().front() == 's') {
19270b57cec5SDimitry Andric     auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
1928*0fca6ea1SDimitry Andric     if (ScalarSize) {
19290b57cec5SDimitry Andric       if (!verifyScalarSize(ScalarSize))
19300b57cec5SDimitry Andric         return error("invalid size for scalar type");
19310b57cec5SDimitry Andric       Ty = LLT::scalar(ScalarSize);
1932*0fca6ea1SDimitry Andric     } else {
1933*0fca6ea1SDimitry Andric       Ty = LLT::token();
1934*0fca6ea1SDimitry Andric     }
19350b57cec5SDimitry Andric     lex();
19360b57cec5SDimitry Andric     return false;
19370b57cec5SDimitry Andric   } else if (Token.range().front() == 'p') {
19380b57cec5SDimitry Andric     const DataLayout &DL = MF.getDataLayout();
19390b57cec5SDimitry Andric     uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
19400b57cec5SDimitry Andric     if (!verifyAddrSpace(AS))
19410b57cec5SDimitry Andric       return error("invalid address space number");
19420b57cec5SDimitry Andric 
19430b57cec5SDimitry Andric     Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
19440b57cec5SDimitry Andric     lex();
19450b57cec5SDimitry Andric     return false;
19460b57cec5SDimitry Andric   }
19470b57cec5SDimitry Andric 
19480b57cec5SDimitry Andric   // Now we're looking for a vector.
19490b57cec5SDimitry Andric   if (Token.isNot(MIToken::less))
19505f757f3fSDimitry Andric     return error(Loc, "expected sN, pA, <M x sN>, <M x pA>, <vscale x M x sN>, "
19515f757f3fSDimitry Andric                       "or <vscale x M x pA> for GlobalISel type");
19520b57cec5SDimitry Andric   lex();
19530b57cec5SDimitry Andric 
19545f757f3fSDimitry Andric   bool HasVScale =
19555f757f3fSDimitry Andric       Token.is(MIToken::Identifier) && Token.stringValue() == "vscale";
19565f757f3fSDimitry Andric   if (HasVScale) {
19575f757f3fSDimitry Andric     lex();
19585f757f3fSDimitry Andric     if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
19595f757f3fSDimitry Andric       return error("expected <vscale x M x sN> or <vscale x M x pA>");
19605f757f3fSDimitry Andric     lex();
19615f757f3fSDimitry Andric   }
19625f757f3fSDimitry Andric 
19635f757f3fSDimitry Andric   auto GetError = [this, &HasVScale, Loc]() {
19645f757f3fSDimitry Andric     if (HasVScale)
19655f757f3fSDimitry Andric       return error(
19665f757f3fSDimitry Andric           Loc, "expected <vscale x M x sN> or <vscale M x pA> for vector type");
19670b57cec5SDimitry Andric     return error(Loc, "expected <M x sN> or <M x pA> for vector type");
19685f757f3fSDimitry Andric   };
19695f757f3fSDimitry Andric 
19705f757f3fSDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral))
19715f757f3fSDimitry Andric     return GetError();
19720b57cec5SDimitry Andric   uint64_t NumElements = Token.integerValue().getZExtValue();
19730b57cec5SDimitry Andric   if (!verifyVectorElementCount(NumElements))
19740b57cec5SDimitry Andric     return error("invalid number of vector elements");
19750b57cec5SDimitry Andric 
19760b57cec5SDimitry Andric   lex();
19770b57cec5SDimitry Andric 
19780b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
19795f757f3fSDimitry Andric     return GetError();
19800b57cec5SDimitry Andric   lex();
19810b57cec5SDimitry Andric 
19820b57cec5SDimitry Andric   if (Token.range().front() != 's' && Token.range().front() != 'p')
19835f757f3fSDimitry Andric     return GetError();
19845f757f3fSDimitry Andric 
19850b57cec5SDimitry Andric   StringRef SizeStr = Token.range().drop_front();
19860b57cec5SDimitry Andric   if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
19870b57cec5SDimitry Andric     return error("expected integers after 's'/'p' type character");
19880b57cec5SDimitry Andric 
19890b57cec5SDimitry Andric   if (Token.range().front() == 's') {
19900b57cec5SDimitry Andric     auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
19910b57cec5SDimitry Andric     if (!verifyScalarSize(ScalarSize))
1992*0fca6ea1SDimitry Andric       return error("invalid size for scalar element in vector");
19930b57cec5SDimitry Andric     Ty = LLT::scalar(ScalarSize);
19940b57cec5SDimitry Andric   } else if (Token.range().front() == 'p') {
19950b57cec5SDimitry Andric     const DataLayout &DL = MF.getDataLayout();
19960b57cec5SDimitry Andric     uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
19970b57cec5SDimitry Andric     if (!verifyAddrSpace(AS))
19980b57cec5SDimitry Andric       return error("invalid address space number");
19990b57cec5SDimitry Andric 
20000b57cec5SDimitry Andric     Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
20010b57cec5SDimitry Andric   } else
20025f757f3fSDimitry Andric     return GetError();
20030b57cec5SDimitry Andric   lex();
20040b57cec5SDimitry Andric 
20050b57cec5SDimitry Andric   if (Token.isNot(MIToken::greater))
20065f757f3fSDimitry Andric     return GetError();
20075f757f3fSDimitry Andric 
20080b57cec5SDimitry Andric   lex();
20090b57cec5SDimitry Andric 
20105f757f3fSDimitry Andric   Ty = LLT::vector(ElementCount::get(NumElements, HasVScale), Ty);
20110b57cec5SDimitry Andric   return false;
20120b57cec5SDimitry Andric }
20130b57cec5SDimitry Andric 
20140b57cec5SDimitry Andric bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) {
20150b57cec5SDimitry Andric   assert(Token.is(MIToken::Identifier));
20160b57cec5SDimitry Andric   StringRef TypeStr = Token.range();
20170b57cec5SDimitry Andric   if (TypeStr.front() != 'i' && TypeStr.front() != 's' &&
20180b57cec5SDimitry Andric       TypeStr.front() != 'p')
20190b57cec5SDimitry Andric     return error(
20200b57cec5SDimitry Andric         "a typed immediate operand should start with one of 'i', 's', or 'p'");
20210b57cec5SDimitry Andric   StringRef SizeStr = Token.range().drop_front();
20220b57cec5SDimitry Andric   if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
20230b57cec5SDimitry Andric     return error("expected integers after 'i'/'s'/'p' type character");
20240b57cec5SDimitry Andric 
20250b57cec5SDimitry Andric   auto Loc = Token.location();
20260b57cec5SDimitry Andric   lex();
20270b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral)) {
20280b57cec5SDimitry Andric     if (Token.isNot(MIToken::Identifier) ||
20290b57cec5SDimitry Andric         !(Token.range() == "true" || Token.range() == "false"))
20300b57cec5SDimitry Andric       return error("expected an integer literal");
20310b57cec5SDimitry Andric   }
20320b57cec5SDimitry Andric   const Constant *C = nullptr;
20330b57cec5SDimitry Andric   if (parseIRConstant(Loc, C))
20340b57cec5SDimitry Andric     return true;
20350b57cec5SDimitry Andric   Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C));
20360b57cec5SDimitry Andric   return false;
20370b57cec5SDimitry Andric }
20380b57cec5SDimitry Andric 
20390b57cec5SDimitry Andric bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
20400b57cec5SDimitry Andric   auto Loc = Token.location();
20410b57cec5SDimitry Andric   lex();
20420b57cec5SDimitry Andric   if (Token.isNot(MIToken::FloatingPointLiteral) &&
20430b57cec5SDimitry Andric       Token.isNot(MIToken::HexLiteral))
20440b57cec5SDimitry Andric     return error("expected a floating point literal");
20450b57cec5SDimitry Andric   const Constant *C = nullptr;
20460b57cec5SDimitry Andric   if (parseIRConstant(Loc, C))
20470b57cec5SDimitry Andric     return true;
20480b57cec5SDimitry Andric   Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C));
20490b57cec5SDimitry Andric   return false;
20500b57cec5SDimitry Andric }
20510b57cec5SDimitry Andric 
2052480093f4SDimitry Andric static bool getHexUint(const MIToken &Token, APInt &Result) {
2053480093f4SDimitry Andric   assert(Token.is(MIToken::HexLiteral));
2054480093f4SDimitry Andric   StringRef S = Token.range();
2055480093f4SDimitry Andric   assert(S[0] == '0' && tolower(S[1]) == 'x');
2056480093f4SDimitry Andric   // This could be a floating point literal with a special prefix.
2057480093f4SDimitry Andric   if (!isxdigit(S[2]))
2058480093f4SDimitry Andric     return true;
2059480093f4SDimitry Andric   StringRef V = S.substr(2);
2060480093f4SDimitry Andric   APInt A(V.size()*4, V, 16);
2061480093f4SDimitry Andric 
2062480093f4SDimitry Andric   // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make
2063480093f4SDimitry Andric   // sure it isn't the case before constructing result.
2064480093f4SDimitry Andric   unsigned NumBits = (A == 0) ? 32 : A.getActiveBits();
2065480093f4SDimitry Andric   Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
2066480093f4SDimitry Andric   return false;
2067480093f4SDimitry Andric }
2068480093f4SDimitry Andric 
2069480093f4SDimitry Andric static bool getUnsigned(const MIToken &Token, unsigned &Result,
2070480093f4SDimitry Andric                         ErrorCallbackType ErrCB) {
20710b57cec5SDimitry Andric   if (Token.hasIntegerValue()) {
20720b57cec5SDimitry Andric     const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
20730b57cec5SDimitry Andric     uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
20740b57cec5SDimitry Andric     if (Val64 == Limit)
2075480093f4SDimitry Andric       return ErrCB(Token.location(), "expected 32-bit integer (too large)");
20760b57cec5SDimitry Andric     Result = Val64;
20770b57cec5SDimitry Andric     return false;
20780b57cec5SDimitry Andric   }
20790b57cec5SDimitry Andric   if (Token.is(MIToken::HexLiteral)) {
20800b57cec5SDimitry Andric     APInt A;
2081480093f4SDimitry Andric     if (getHexUint(Token, A))
20820b57cec5SDimitry Andric       return true;
20830b57cec5SDimitry Andric     if (A.getBitWidth() > 32)
2084480093f4SDimitry Andric       return ErrCB(Token.location(), "expected 32-bit integer (too large)");
20850b57cec5SDimitry Andric     Result = A.getZExtValue();
20860b57cec5SDimitry Andric     return false;
20870b57cec5SDimitry Andric   }
20880b57cec5SDimitry Andric   return true;
20890b57cec5SDimitry Andric }
20900b57cec5SDimitry Andric 
2091480093f4SDimitry Andric bool MIParser::getUnsigned(unsigned &Result) {
2092480093f4SDimitry Andric   return ::getUnsigned(
2093480093f4SDimitry Andric       Token, Result, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2094480093f4SDimitry Andric         return error(Loc, Msg);
2095480093f4SDimitry Andric       });
2096480093f4SDimitry Andric }
2097480093f4SDimitry Andric 
20980b57cec5SDimitry Andric bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
20990b57cec5SDimitry Andric   assert(Token.is(MIToken::MachineBasicBlock) ||
21000b57cec5SDimitry Andric          Token.is(MIToken::MachineBasicBlockLabel));
21010b57cec5SDimitry Andric   unsigned Number;
21020b57cec5SDimitry Andric   if (getUnsigned(Number))
21030b57cec5SDimitry Andric     return true;
21040b57cec5SDimitry Andric   auto MBBInfo = PFS.MBBSlots.find(Number);
21050b57cec5SDimitry Andric   if (MBBInfo == PFS.MBBSlots.end())
21060b57cec5SDimitry Andric     return error(Twine("use of undefined machine basic block #") +
21070b57cec5SDimitry Andric                  Twine(Number));
21080b57cec5SDimitry Andric   MBB = MBBInfo->second;
21090b57cec5SDimitry Andric   // TODO: Only parse the name if it's a MachineBasicBlockLabel. Deprecate once
21100b57cec5SDimitry Andric   // we drop the <irname> from the bb.<id>.<irname> format.
21110b57cec5SDimitry Andric   if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
21120b57cec5SDimitry Andric     return error(Twine("the name of machine basic block #") + Twine(Number) +
21130b57cec5SDimitry Andric                  " isn't '" + Token.stringValue() + "'");
21140b57cec5SDimitry Andric   return false;
21150b57cec5SDimitry Andric }
21160b57cec5SDimitry Andric 
21170b57cec5SDimitry Andric bool MIParser::parseMBBOperand(MachineOperand &Dest) {
21180b57cec5SDimitry Andric   MachineBasicBlock *MBB;
21190b57cec5SDimitry Andric   if (parseMBBReference(MBB))
21200b57cec5SDimitry Andric     return true;
21210b57cec5SDimitry Andric   Dest = MachineOperand::CreateMBB(MBB);
21220b57cec5SDimitry Andric   lex();
21230b57cec5SDimitry Andric   return false;
21240b57cec5SDimitry Andric }
21250b57cec5SDimitry Andric 
21260b57cec5SDimitry Andric bool MIParser::parseStackFrameIndex(int &FI) {
21270b57cec5SDimitry Andric   assert(Token.is(MIToken::StackObject));
21280b57cec5SDimitry Andric   unsigned ID;
21290b57cec5SDimitry Andric   if (getUnsigned(ID))
21300b57cec5SDimitry Andric     return true;
21310b57cec5SDimitry Andric   auto ObjectInfo = PFS.StackObjectSlots.find(ID);
21320b57cec5SDimitry Andric   if (ObjectInfo == PFS.StackObjectSlots.end())
21330b57cec5SDimitry Andric     return error(Twine("use of undefined stack object '%stack.") + Twine(ID) +
21340b57cec5SDimitry Andric                  "'");
21350b57cec5SDimitry Andric   StringRef Name;
21360b57cec5SDimitry Andric   if (const auto *Alloca =
21370b57cec5SDimitry Andric           MF.getFrameInfo().getObjectAllocation(ObjectInfo->second))
21380b57cec5SDimitry Andric     Name = Alloca->getName();
21390b57cec5SDimitry Andric   if (!Token.stringValue().empty() && Token.stringValue() != Name)
21400b57cec5SDimitry Andric     return error(Twine("the name of the stack object '%stack.") + Twine(ID) +
21410b57cec5SDimitry Andric                  "' isn't '" + Token.stringValue() + "'");
21420b57cec5SDimitry Andric   lex();
21430b57cec5SDimitry Andric   FI = ObjectInfo->second;
21440b57cec5SDimitry Andric   return false;
21450b57cec5SDimitry Andric }
21460b57cec5SDimitry Andric 
21470b57cec5SDimitry Andric bool MIParser::parseStackObjectOperand(MachineOperand &Dest) {
21480b57cec5SDimitry Andric   int FI;
21490b57cec5SDimitry Andric   if (parseStackFrameIndex(FI))
21500b57cec5SDimitry Andric     return true;
21510b57cec5SDimitry Andric   Dest = MachineOperand::CreateFI(FI);
21520b57cec5SDimitry Andric   return false;
21530b57cec5SDimitry Andric }
21540b57cec5SDimitry Andric 
21550b57cec5SDimitry Andric bool MIParser::parseFixedStackFrameIndex(int &FI) {
21560b57cec5SDimitry Andric   assert(Token.is(MIToken::FixedStackObject));
21570b57cec5SDimitry Andric   unsigned ID;
21580b57cec5SDimitry Andric   if (getUnsigned(ID))
21590b57cec5SDimitry Andric     return true;
21600b57cec5SDimitry Andric   auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID);
21610b57cec5SDimitry Andric   if (ObjectInfo == PFS.FixedStackObjectSlots.end())
21620b57cec5SDimitry Andric     return error(Twine("use of undefined fixed stack object '%fixed-stack.") +
21630b57cec5SDimitry Andric                  Twine(ID) + "'");
21640b57cec5SDimitry Andric   lex();
21650b57cec5SDimitry Andric   FI = ObjectInfo->second;
21660b57cec5SDimitry Andric   return false;
21670b57cec5SDimitry Andric }
21680b57cec5SDimitry Andric 
21690b57cec5SDimitry Andric bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
21700b57cec5SDimitry Andric   int FI;
21710b57cec5SDimitry Andric   if (parseFixedStackFrameIndex(FI))
21720b57cec5SDimitry Andric     return true;
21730b57cec5SDimitry Andric   Dest = MachineOperand::CreateFI(FI);
21740b57cec5SDimitry Andric   return false;
21750b57cec5SDimitry Andric }
21760b57cec5SDimitry Andric 
2177480093f4SDimitry Andric static bool parseGlobalValue(const MIToken &Token,
2178480093f4SDimitry Andric                              PerFunctionMIParsingState &PFS, GlobalValue *&GV,
2179480093f4SDimitry Andric                              ErrorCallbackType ErrCB) {
21800b57cec5SDimitry Andric   switch (Token.kind()) {
21810b57cec5SDimitry Andric   case MIToken::NamedGlobalValue: {
2182480093f4SDimitry Andric     const Module *M = PFS.MF.getFunction().getParent();
21830b57cec5SDimitry Andric     GV = M->getNamedValue(Token.stringValue());
21840b57cec5SDimitry Andric     if (!GV)
2185480093f4SDimitry Andric       return ErrCB(Token.location(), Twine("use of undefined global value '") +
2186480093f4SDimitry Andric                                          Token.range() + "'");
21870b57cec5SDimitry Andric     break;
21880b57cec5SDimitry Andric   }
21890b57cec5SDimitry Andric   case MIToken::GlobalValue: {
21900b57cec5SDimitry Andric     unsigned GVIdx;
2191480093f4SDimitry Andric     if (getUnsigned(Token, GVIdx, ErrCB))
21920b57cec5SDimitry Andric       return true;
2193*0fca6ea1SDimitry Andric     GV = PFS.IRSlots.GlobalValues.get(GVIdx);
2194*0fca6ea1SDimitry Andric     if (!GV)
2195480093f4SDimitry Andric       return ErrCB(Token.location(), Twine("use of undefined global value '@") +
2196480093f4SDimitry Andric                                          Twine(GVIdx) + "'");
21970b57cec5SDimitry Andric     break;
21980b57cec5SDimitry Andric   }
21990b57cec5SDimitry Andric   default:
22000b57cec5SDimitry Andric     llvm_unreachable("The current token should be a global value");
22010b57cec5SDimitry Andric   }
22020b57cec5SDimitry Andric   return false;
22030b57cec5SDimitry Andric }
22040b57cec5SDimitry Andric 
2205480093f4SDimitry Andric bool MIParser::parseGlobalValue(GlobalValue *&GV) {
2206480093f4SDimitry Andric   return ::parseGlobalValue(
2207480093f4SDimitry Andric       Token, PFS, GV,
2208480093f4SDimitry Andric       [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2209480093f4SDimitry Andric         return error(Loc, Msg);
2210480093f4SDimitry Andric       });
2211480093f4SDimitry Andric }
2212480093f4SDimitry Andric 
22130b57cec5SDimitry Andric bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
22140b57cec5SDimitry Andric   GlobalValue *GV = nullptr;
22150b57cec5SDimitry Andric   if (parseGlobalValue(GV))
22160b57cec5SDimitry Andric     return true;
22170b57cec5SDimitry Andric   lex();
22180b57cec5SDimitry Andric   Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
22190b57cec5SDimitry Andric   if (parseOperandsOffset(Dest))
22200b57cec5SDimitry Andric     return true;
22210b57cec5SDimitry Andric   return false;
22220b57cec5SDimitry Andric }
22230b57cec5SDimitry Andric 
22240b57cec5SDimitry Andric bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) {
22250b57cec5SDimitry Andric   assert(Token.is(MIToken::ConstantPoolItem));
22260b57cec5SDimitry Andric   unsigned ID;
22270b57cec5SDimitry Andric   if (getUnsigned(ID))
22280b57cec5SDimitry Andric     return true;
22290b57cec5SDimitry Andric   auto ConstantInfo = PFS.ConstantPoolSlots.find(ID);
22300b57cec5SDimitry Andric   if (ConstantInfo == PFS.ConstantPoolSlots.end())
22310b57cec5SDimitry Andric     return error("use of undefined constant '%const." + Twine(ID) + "'");
22320b57cec5SDimitry Andric   lex();
22330b57cec5SDimitry Andric   Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0);
22340b57cec5SDimitry Andric   if (parseOperandsOffset(Dest))
22350b57cec5SDimitry Andric     return true;
22360b57cec5SDimitry Andric   return false;
22370b57cec5SDimitry Andric }
22380b57cec5SDimitry Andric 
22390b57cec5SDimitry Andric bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
22400b57cec5SDimitry Andric   assert(Token.is(MIToken::JumpTableIndex));
22410b57cec5SDimitry Andric   unsigned ID;
22420b57cec5SDimitry Andric   if (getUnsigned(ID))
22430b57cec5SDimitry Andric     return true;
22440b57cec5SDimitry Andric   auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID);
22450b57cec5SDimitry Andric   if (JumpTableEntryInfo == PFS.JumpTableSlots.end())
22460b57cec5SDimitry Andric     return error("use of undefined jump table '%jump-table." + Twine(ID) + "'");
22470b57cec5SDimitry Andric   lex();
22480b57cec5SDimitry Andric   Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second);
22490b57cec5SDimitry Andric   return false;
22500b57cec5SDimitry Andric }
22510b57cec5SDimitry Andric 
22520b57cec5SDimitry Andric bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
22530b57cec5SDimitry Andric   assert(Token.is(MIToken::ExternalSymbol));
22540b57cec5SDimitry Andric   const char *Symbol = MF.createExternalSymbolName(Token.stringValue());
22550b57cec5SDimitry Andric   lex();
22560b57cec5SDimitry Andric   Dest = MachineOperand::CreateES(Symbol);
22570b57cec5SDimitry Andric   if (parseOperandsOffset(Dest))
22580b57cec5SDimitry Andric     return true;
22590b57cec5SDimitry Andric   return false;
22600b57cec5SDimitry Andric }
22610b57cec5SDimitry Andric 
22620b57cec5SDimitry Andric bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) {
22630b57cec5SDimitry Andric   assert(Token.is(MIToken::MCSymbol));
22640b57cec5SDimitry Andric   MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue());
22650b57cec5SDimitry Andric   lex();
22660b57cec5SDimitry Andric   Dest = MachineOperand::CreateMCSymbol(Symbol);
22670b57cec5SDimitry Andric   if (parseOperandsOffset(Dest))
22680b57cec5SDimitry Andric     return true;
22690b57cec5SDimitry Andric   return false;
22700b57cec5SDimitry Andric }
22710b57cec5SDimitry Andric 
22720b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) {
22730b57cec5SDimitry Andric   assert(Token.is(MIToken::SubRegisterIndex));
22740b57cec5SDimitry Andric   StringRef Name = Token.stringValue();
22750b57cec5SDimitry Andric   unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue());
22760b57cec5SDimitry Andric   if (SubRegIndex == 0)
22770b57cec5SDimitry Andric     return error(Twine("unknown subregister index '") + Name + "'");
22780b57cec5SDimitry Andric   lex();
22790b57cec5SDimitry Andric   Dest = MachineOperand::CreateImm(SubRegIndex);
22800b57cec5SDimitry Andric   return false;
22810b57cec5SDimitry Andric }
22820b57cec5SDimitry Andric 
22830b57cec5SDimitry Andric bool MIParser::parseMDNode(MDNode *&Node) {
22840b57cec5SDimitry Andric   assert(Token.is(MIToken::exclaim));
22850b57cec5SDimitry Andric 
22860b57cec5SDimitry Andric   auto Loc = Token.location();
22870b57cec5SDimitry Andric   lex();
22880b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
22890b57cec5SDimitry Andric     return error("expected metadata id after '!'");
22900b57cec5SDimitry Andric   unsigned ID;
22910b57cec5SDimitry Andric   if (getUnsigned(ID))
22920b57cec5SDimitry Andric     return true;
22930b57cec5SDimitry Andric   auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
2294fe6060f1SDimitry Andric   if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) {
2295fe6060f1SDimitry Andric     NodeInfo = PFS.MachineMetadataNodes.find(ID);
2296fe6060f1SDimitry Andric     if (NodeInfo == PFS.MachineMetadataNodes.end())
22970b57cec5SDimitry Andric       return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
2298fe6060f1SDimitry Andric   }
22990b57cec5SDimitry Andric   lex();
23000b57cec5SDimitry Andric   Node = NodeInfo->second.get();
23010b57cec5SDimitry Andric   return false;
23020b57cec5SDimitry Andric }
23030b57cec5SDimitry Andric 
23040b57cec5SDimitry Andric bool MIParser::parseDIExpression(MDNode *&Expr) {
2305*0fca6ea1SDimitry Andric   unsigned Read;
2306*0fca6ea1SDimitry Andric   Expr = llvm::parseDIExpressionBodyAtBeginning(
2307*0fca6ea1SDimitry Andric       CurrentSource, Read, Error, *PFS.MF.getFunction().getParent(),
2308*0fca6ea1SDimitry Andric       &PFS.IRSlots);
2309*0fca6ea1SDimitry Andric   CurrentSource = CurrentSource.slice(Read, StringRef::npos);
23100b57cec5SDimitry Andric   lex();
2311*0fca6ea1SDimitry Andric   if (!Expr)
2312*0fca6ea1SDimitry Andric     return error(Error.getMessage());
23130b57cec5SDimitry Andric   return false;
23140b57cec5SDimitry Andric }
23150b57cec5SDimitry Andric 
23160b57cec5SDimitry Andric bool MIParser::parseDILocation(MDNode *&Loc) {
23170b57cec5SDimitry Andric   assert(Token.is(MIToken::md_dilocation));
23180b57cec5SDimitry Andric   lex();
23190b57cec5SDimitry Andric 
23200b57cec5SDimitry Andric   bool HaveLine = false;
23210b57cec5SDimitry Andric   unsigned Line = 0;
23220b57cec5SDimitry Andric   unsigned Column = 0;
23230b57cec5SDimitry Andric   MDNode *Scope = nullptr;
23240b57cec5SDimitry Andric   MDNode *InlinedAt = nullptr;
23250b57cec5SDimitry Andric   bool ImplicitCode = false;
23260b57cec5SDimitry Andric 
23270b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
23280b57cec5SDimitry Andric     return true;
23290b57cec5SDimitry Andric 
23300b57cec5SDimitry Andric   if (Token.isNot(MIToken::rparen)) {
23310b57cec5SDimitry Andric     do {
23320b57cec5SDimitry Andric       if (Token.is(MIToken::Identifier)) {
23330b57cec5SDimitry Andric         if (Token.stringValue() == "line") {
23340b57cec5SDimitry Andric           lex();
23350b57cec5SDimitry Andric           if (expectAndConsume(MIToken::colon))
23360b57cec5SDimitry Andric             return true;
23370b57cec5SDimitry Andric           if (Token.isNot(MIToken::IntegerLiteral) ||
23380b57cec5SDimitry Andric               Token.integerValue().isSigned())
23390b57cec5SDimitry Andric             return error("expected unsigned integer");
23400b57cec5SDimitry Andric           Line = Token.integerValue().getZExtValue();
23410b57cec5SDimitry Andric           HaveLine = true;
23420b57cec5SDimitry Andric           lex();
23430b57cec5SDimitry Andric           continue;
23440b57cec5SDimitry Andric         }
23450b57cec5SDimitry Andric         if (Token.stringValue() == "column") {
23460b57cec5SDimitry Andric           lex();
23470b57cec5SDimitry Andric           if (expectAndConsume(MIToken::colon))
23480b57cec5SDimitry Andric             return true;
23490b57cec5SDimitry Andric           if (Token.isNot(MIToken::IntegerLiteral) ||
23500b57cec5SDimitry Andric               Token.integerValue().isSigned())
23510b57cec5SDimitry Andric             return error("expected unsigned integer");
23520b57cec5SDimitry Andric           Column = Token.integerValue().getZExtValue();
23530b57cec5SDimitry Andric           lex();
23540b57cec5SDimitry Andric           continue;
23550b57cec5SDimitry Andric         }
23560b57cec5SDimitry Andric         if (Token.stringValue() == "scope") {
23570b57cec5SDimitry Andric           lex();
23580b57cec5SDimitry Andric           if (expectAndConsume(MIToken::colon))
23590b57cec5SDimitry Andric             return true;
23600b57cec5SDimitry Andric           if (parseMDNode(Scope))
23610b57cec5SDimitry Andric             return error("expected metadata node");
23620b57cec5SDimitry Andric           if (!isa<DIScope>(Scope))
23630b57cec5SDimitry Andric             return error("expected DIScope node");
23640b57cec5SDimitry Andric           continue;
23650b57cec5SDimitry Andric         }
23660b57cec5SDimitry Andric         if (Token.stringValue() == "inlinedAt") {
23670b57cec5SDimitry Andric           lex();
23680b57cec5SDimitry Andric           if (expectAndConsume(MIToken::colon))
23690b57cec5SDimitry Andric             return true;
23700b57cec5SDimitry Andric           if (Token.is(MIToken::exclaim)) {
23710b57cec5SDimitry Andric             if (parseMDNode(InlinedAt))
23720b57cec5SDimitry Andric               return true;
23730b57cec5SDimitry Andric           } else if (Token.is(MIToken::md_dilocation)) {
23740b57cec5SDimitry Andric             if (parseDILocation(InlinedAt))
23750b57cec5SDimitry Andric               return true;
23760b57cec5SDimitry Andric           } else
23770b57cec5SDimitry Andric             return error("expected metadata node");
23780b57cec5SDimitry Andric           if (!isa<DILocation>(InlinedAt))
23790b57cec5SDimitry Andric             return error("expected DILocation node");
23800b57cec5SDimitry Andric           continue;
23810b57cec5SDimitry Andric         }
23820b57cec5SDimitry Andric         if (Token.stringValue() == "isImplicitCode") {
23830b57cec5SDimitry Andric           lex();
23840b57cec5SDimitry Andric           if (expectAndConsume(MIToken::colon))
23850b57cec5SDimitry Andric             return true;
23860b57cec5SDimitry Andric           if (!Token.is(MIToken::Identifier))
23870b57cec5SDimitry Andric             return error("expected true/false");
23880b57cec5SDimitry Andric           // As far as I can see, we don't have any existing need for parsing
23890b57cec5SDimitry Andric           // true/false in MIR yet. Do it ad-hoc until there's something else
23900b57cec5SDimitry Andric           // that needs it.
23910b57cec5SDimitry Andric           if (Token.stringValue() == "true")
23920b57cec5SDimitry Andric             ImplicitCode = true;
23930b57cec5SDimitry Andric           else if (Token.stringValue() == "false")
23940b57cec5SDimitry Andric             ImplicitCode = false;
23950b57cec5SDimitry Andric           else
23960b57cec5SDimitry Andric             return error("expected true/false");
23970b57cec5SDimitry Andric           lex();
23980b57cec5SDimitry Andric           continue;
23990b57cec5SDimitry Andric         }
24000b57cec5SDimitry Andric       }
24010b57cec5SDimitry Andric       return error(Twine("invalid DILocation argument '") +
24020b57cec5SDimitry Andric                    Token.stringValue() + "'");
24030b57cec5SDimitry Andric     } while (consumeIfPresent(MIToken::comma));
24040b57cec5SDimitry Andric   }
24050b57cec5SDimitry Andric 
24060b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
24070b57cec5SDimitry Andric     return true;
24080b57cec5SDimitry Andric 
24090b57cec5SDimitry Andric   if (!HaveLine)
24100b57cec5SDimitry Andric     return error("DILocation requires line number");
24110b57cec5SDimitry Andric   if (!Scope)
24120b57cec5SDimitry Andric     return error("DILocation requires a scope");
24130b57cec5SDimitry Andric 
24140b57cec5SDimitry Andric   Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope,
24150b57cec5SDimitry Andric                         InlinedAt, ImplicitCode);
24160b57cec5SDimitry Andric   return false;
24170b57cec5SDimitry Andric }
24180b57cec5SDimitry Andric 
24190b57cec5SDimitry Andric bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
24200b57cec5SDimitry Andric   MDNode *Node = nullptr;
24210b57cec5SDimitry Andric   if (Token.is(MIToken::exclaim)) {
24220b57cec5SDimitry Andric     if (parseMDNode(Node))
24230b57cec5SDimitry Andric       return true;
24240b57cec5SDimitry Andric   } else if (Token.is(MIToken::md_diexpr)) {
24250b57cec5SDimitry Andric     if (parseDIExpression(Node))
24260b57cec5SDimitry Andric       return true;
24270b57cec5SDimitry Andric   }
24280b57cec5SDimitry Andric   Dest = MachineOperand::CreateMetadata(Node);
24290b57cec5SDimitry Andric   return false;
24300b57cec5SDimitry Andric }
24310b57cec5SDimitry Andric 
24320b57cec5SDimitry Andric bool MIParser::parseCFIOffset(int &Offset) {
24330b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral))
24340b57cec5SDimitry Andric     return error("expected a cfi offset");
243506c3fb27SDimitry Andric   if (Token.integerValue().getSignificantBits() > 32)
24360b57cec5SDimitry Andric     return error("expected a 32 bit integer (the cfi offset is too large)");
24370b57cec5SDimitry Andric   Offset = (int)Token.integerValue().getExtValue();
24380b57cec5SDimitry Andric   lex();
24390b57cec5SDimitry Andric   return false;
24400b57cec5SDimitry Andric }
24410b57cec5SDimitry Andric 
24425ffd83dbSDimitry Andric bool MIParser::parseCFIRegister(Register &Reg) {
24430b57cec5SDimitry Andric   if (Token.isNot(MIToken::NamedRegister))
24440b57cec5SDimitry Andric     return error("expected a cfi register");
24455ffd83dbSDimitry Andric   Register LLVMReg;
24460b57cec5SDimitry Andric   if (parseNamedRegister(LLVMReg))
24470b57cec5SDimitry Andric     return true;
24480b57cec5SDimitry Andric   const auto *TRI = MF.getSubtarget().getRegisterInfo();
24490b57cec5SDimitry Andric   assert(TRI && "Expected target register info");
24500b57cec5SDimitry Andric   int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true);
24510b57cec5SDimitry Andric   if (DwarfReg < 0)
24520b57cec5SDimitry Andric     return error("invalid DWARF register");
24530b57cec5SDimitry Andric   Reg = (unsigned)DwarfReg;
24540b57cec5SDimitry Andric   lex();
24550b57cec5SDimitry Andric   return false;
24560b57cec5SDimitry Andric }
24570b57cec5SDimitry Andric 
2458fe6060f1SDimitry Andric bool MIParser::parseCFIAddressSpace(unsigned &AddressSpace) {
2459fe6060f1SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral))
2460fe6060f1SDimitry Andric     return error("expected a cfi address space literal");
2461fe6060f1SDimitry Andric   if (Token.integerValue().isSigned())
2462fe6060f1SDimitry Andric     return error("expected an unsigned integer (cfi address space)");
2463fe6060f1SDimitry Andric   AddressSpace = Token.integerValue().getZExtValue();
2464fe6060f1SDimitry Andric   lex();
2465fe6060f1SDimitry Andric   return false;
2466fe6060f1SDimitry Andric }
2467fe6060f1SDimitry Andric 
24680b57cec5SDimitry Andric bool MIParser::parseCFIEscapeValues(std::string &Values) {
24690b57cec5SDimitry Andric   do {
24700b57cec5SDimitry Andric     if (Token.isNot(MIToken::HexLiteral))
24710b57cec5SDimitry Andric       return error("expected a hexadecimal literal");
24720b57cec5SDimitry Andric     unsigned Value;
24730b57cec5SDimitry Andric     if (getUnsigned(Value))
24740b57cec5SDimitry Andric       return true;
24750b57cec5SDimitry Andric     if (Value > UINT8_MAX)
24760b57cec5SDimitry Andric       return error("expected a 8-bit integer (too large)");
24770b57cec5SDimitry Andric     Values.push_back(static_cast<uint8_t>(Value));
24780b57cec5SDimitry Andric     lex();
24790b57cec5SDimitry Andric   } while (consumeIfPresent(MIToken::comma));
24800b57cec5SDimitry Andric   return false;
24810b57cec5SDimitry Andric }
24820b57cec5SDimitry Andric 
24830b57cec5SDimitry Andric bool MIParser::parseCFIOperand(MachineOperand &Dest) {
24840b57cec5SDimitry Andric   auto Kind = Token.kind();
24850b57cec5SDimitry Andric   lex();
24860b57cec5SDimitry Andric   int Offset;
24875ffd83dbSDimitry Andric   Register Reg;
2488fe6060f1SDimitry Andric   unsigned AddressSpace;
24890b57cec5SDimitry Andric   unsigned CFIIndex;
24900b57cec5SDimitry Andric   switch (Kind) {
24910b57cec5SDimitry Andric   case MIToken::kw_cfi_same_value:
24920b57cec5SDimitry Andric     if (parseCFIRegister(Reg))
24930b57cec5SDimitry Andric       return true;
24940b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg));
24950b57cec5SDimitry Andric     break;
24960b57cec5SDimitry Andric   case MIToken::kw_cfi_offset:
24970b57cec5SDimitry Andric     if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
24980b57cec5SDimitry Andric         parseCFIOffset(Offset))
24990b57cec5SDimitry Andric       return true;
25000b57cec5SDimitry Andric     CFIIndex =
25010b57cec5SDimitry Andric         MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
25020b57cec5SDimitry Andric     break;
25030b57cec5SDimitry Andric   case MIToken::kw_cfi_rel_offset:
25040b57cec5SDimitry Andric     if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
25050b57cec5SDimitry Andric         parseCFIOffset(Offset))
25060b57cec5SDimitry Andric       return true;
25070b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(
25080b57cec5SDimitry Andric         MCCFIInstruction::createRelOffset(nullptr, Reg, Offset));
25090b57cec5SDimitry Andric     break;
25100b57cec5SDimitry Andric   case MIToken::kw_cfi_def_cfa_register:
25110b57cec5SDimitry Andric     if (parseCFIRegister(Reg))
25120b57cec5SDimitry Andric       return true;
25130b57cec5SDimitry Andric     CFIIndex =
25140b57cec5SDimitry Andric         MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
25150b57cec5SDimitry Andric     break;
25160b57cec5SDimitry Andric   case MIToken::kw_cfi_def_cfa_offset:
25170b57cec5SDimitry Andric     if (parseCFIOffset(Offset))
25180b57cec5SDimitry Andric       return true;
25195ffd83dbSDimitry Andric     CFIIndex =
25205ffd83dbSDimitry Andric         MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset));
25210b57cec5SDimitry Andric     break;
25220b57cec5SDimitry Andric   case MIToken::kw_cfi_adjust_cfa_offset:
25230b57cec5SDimitry Andric     if (parseCFIOffset(Offset))
25240b57cec5SDimitry Andric       return true;
25250b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(
25260b57cec5SDimitry Andric         MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset));
25270b57cec5SDimitry Andric     break;
25280b57cec5SDimitry Andric   case MIToken::kw_cfi_def_cfa:
25290b57cec5SDimitry Andric     if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
25300b57cec5SDimitry Andric         parseCFIOffset(Offset))
25310b57cec5SDimitry Andric       return true;
25320b57cec5SDimitry Andric     CFIIndex =
25335ffd83dbSDimitry Andric         MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, Offset));
25340b57cec5SDimitry Andric     break;
2535fe6060f1SDimitry Andric   case MIToken::kw_cfi_llvm_def_aspace_cfa:
2536fe6060f1SDimitry Andric     if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2537fe6060f1SDimitry Andric         parseCFIOffset(Offset) || expectAndConsume(MIToken::comma) ||
2538fe6060f1SDimitry Andric         parseCFIAddressSpace(AddressSpace))
2539fe6060f1SDimitry Andric       return true;
2540fe6060f1SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMDefAspaceCfa(
254106c3fb27SDimitry Andric         nullptr, Reg, Offset, AddressSpace, SMLoc()));
2542fe6060f1SDimitry Andric     break;
25430b57cec5SDimitry Andric   case MIToken::kw_cfi_remember_state:
25440b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
25450b57cec5SDimitry Andric     break;
25460b57cec5SDimitry Andric   case MIToken::kw_cfi_restore:
25470b57cec5SDimitry Andric     if (parseCFIRegister(Reg))
25480b57cec5SDimitry Andric       return true;
25490b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
25500b57cec5SDimitry Andric     break;
25510b57cec5SDimitry Andric   case MIToken::kw_cfi_restore_state:
25520b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr));
25530b57cec5SDimitry Andric     break;
25540b57cec5SDimitry Andric   case MIToken::kw_cfi_undefined:
25550b57cec5SDimitry Andric     if (parseCFIRegister(Reg))
25560b57cec5SDimitry Andric       return true;
25570b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg));
25580b57cec5SDimitry Andric     break;
25590b57cec5SDimitry Andric   case MIToken::kw_cfi_register: {
25605ffd83dbSDimitry Andric     Register Reg2;
25610b57cec5SDimitry Andric     if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
25620b57cec5SDimitry Andric         parseCFIRegister(Reg2))
25630b57cec5SDimitry Andric       return true;
25640b57cec5SDimitry Andric 
25650b57cec5SDimitry Andric     CFIIndex =
25660b57cec5SDimitry Andric         MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2));
25670b57cec5SDimitry Andric     break;
25680b57cec5SDimitry Andric   }
25690b57cec5SDimitry Andric   case MIToken::kw_cfi_window_save:
25700b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
25710b57cec5SDimitry Andric     break;
25720b57cec5SDimitry Andric   case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
25730b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
25740b57cec5SDimitry Andric     break;
25750b57cec5SDimitry Andric   case MIToken::kw_cfi_escape: {
25760b57cec5SDimitry Andric     std::string Values;
25770b57cec5SDimitry Andric     if (parseCFIEscapeValues(Values))
25780b57cec5SDimitry Andric       return true;
25790b57cec5SDimitry Andric     CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values));
25800b57cec5SDimitry Andric     break;
25810b57cec5SDimitry Andric   }
25820b57cec5SDimitry Andric   default:
25830b57cec5SDimitry Andric     // TODO: Parse the other CFI operands.
25840b57cec5SDimitry Andric     llvm_unreachable("The current token should be a cfi operand");
25850b57cec5SDimitry Andric   }
25860b57cec5SDimitry Andric   Dest = MachineOperand::CreateCFIIndex(CFIIndex);
25870b57cec5SDimitry Andric   return false;
25880b57cec5SDimitry Andric }
25890b57cec5SDimitry Andric 
25900b57cec5SDimitry Andric bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
25910b57cec5SDimitry Andric   switch (Token.kind()) {
25920b57cec5SDimitry Andric   case MIToken::NamedIRBlock: {
25930b57cec5SDimitry Andric     BB = dyn_cast_or_null<BasicBlock>(
25940b57cec5SDimitry Andric         F.getValueSymbolTable()->lookup(Token.stringValue()));
25950b57cec5SDimitry Andric     if (!BB)
25960b57cec5SDimitry Andric       return error(Twine("use of undefined IR block '") + Token.range() + "'");
25970b57cec5SDimitry Andric     break;
25980b57cec5SDimitry Andric   }
25990b57cec5SDimitry Andric   case MIToken::IRBlock: {
26000b57cec5SDimitry Andric     unsigned SlotNumber = 0;
26010b57cec5SDimitry Andric     if (getUnsigned(SlotNumber))
26020b57cec5SDimitry Andric       return true;
26030b57cec5SDimitry Andric     BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F));
26040b57cec5SDimitry Andric     if (!BB)
26050b57cec5SDimitry Andric       return error(Twine("use of undefined IR block '%ir-block.") +
26060b57cec5SDimitry Andric                    Twine(SlotNumber) + "'");
26070b57cec5SDimitry Andric     break;
26080b57cec5SDimitry Andric   }
26090b57cec5SDimitry Andric   default:
26100b57cec5SDimitry Andric     llvm_unreachable("The current token should be an IR block reference");
26110b57cec5SDimitry Andric   }
26120b57cec5SDimitry Andric   return false;
26130b57cec5SDimitry Andric }
26140b57cec5SDimitry Andric 
26150b57cec5SDimitry Andric bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
26160b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_blockaddress));
26170b57cec5SDimitry Andric   lex();
26180b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
26190b57cec5SDimitry Andric     return true;
26200b57cec5SDimitry Andric   if (Token.isNot(MIToken::GlobalValue) &&
26210b57cec5SDimitry Andric       Token.isNot(MIToken::NamedGlobalValue))
26220b57cec5SDimitry Andric     return error("expected a global value");
26230b57cec5SDimitry Andric   GlobalValue *GV = nullptr;
26240b57cec5SDimitry Andric   if (parseGlobalValue(GV))
26250b57cec5SDimitry Andric     return true;
26260b57cec5SDimitry Andric   auto *F = dyn_cast<Function>(GV);
26270b57cec5SDimitry Andric   if (!F)
26280b57cec5SDimitry Andric     return error("expected an IR function reference");
26290b57cec5SDimitry Andric   lex();
26300b57cec5SDimitry Andric   if (expectAndConsume(MIToken::comma))
26310b57cec5SDimitry Andric     return true;
26320b57cec5SDimitry Andric   BasicBlock *BB = nullptr;
26330b57cec5SDimitry Andric   if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
26340b57cec5SDimitry Andric     return error("expected an IR block reference");
26350b57cec5SDimitry Andric   if (parseIRBlock(BB, *F))
26360b57cec5SDimitry Andric     return true;
26370b57cec5SDimitry Andric   lex();
26380b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
26390b57cec5SDimitry Andric     return true;
26400b57cec5SDimitry Andric   Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
26410b57cec5SDimitry Andric   if (parseOperandsOffset(Dest))
26420b57cec5SDimitry Andric     return true;
26430b57cec5SDimitry Andric   return false;
26440b57cec5SDimitry Andric }
26450b57cec5SDimitry Andric 
26460b57cec5SDimitry Andric bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) {
26470b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_intrinsic));
26480b57cec5SDimitry Andric   lex();
26490b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
26500b57cec5SDimitry Andric     return error("expected syntax intrinsic(@llvm.whatever)");
26510b57cec5SDimitry Andric 
26520b57cec5SDimitry Andric   if (Token.isNot(MIToken::NamedGlobalValue))
26530b57cec5SDimitry Andric     return error("expected syntax intrinsic(@llvm.whatever)");
26540b57cec5SDimitry Andric 
26555ffd83dbSDimitry Andric   std::string Name = std::string(Token.stringValue());
26560b57cec5SDimitry Andric   lex();
26570b57cec5SDimitry Andric 
26580b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
26590b57cec5SDimitry Andric     return error("expected ')' to terminate intrinsic name");
26600b57cec5SDimitry Andric 
26610b57cec5SDimitry Andric   // Find out what intrinsic we're dealing with, first try the global namespace
26620b57cec5SDimitry Andric   // and then the target's private intrinsics if that fails.
26630b57cec5SDimitry Andric   const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo();
26640b57cec5SDimitry Andric   Intrinsic::ID ID = Function::lookupIntrinsicID(Name);
26650b57cec5SDimitry Andric   if (ID == Intrinsic::not_intrinsic && TII)
26660b57cec5SDimitry Andric     ID = static_cast<Intrinsic::ID>(TII->lookupName(Name));
26670b57cec5SDimitry Andric 
26680b57cec5SDimitry Andric   if (ID == Intrinsic::not_intrinsic)
26690b57cec5SDimitry Andric     return error("unknown intrinsic name");
26700b57cec5SDimitry Andric   Dest = MachineOperand::CreateIntrinsicID(ID);
26710b57cec5SDimitry Andric 
26720b57cec5SDimitry Andric   return false;
26730b57cec5SDimitry Andric }
26740b57cec5SDimitry Andric 
26750b57cec5SDimitry Andric bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
26760b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred));
26770b57cec5SDimitry Andric   bool IsFloat = Token.is(MIToken::kw_floatpred);
26780b57cec5SDimitry Andric   lex();
26790b57cec5SDimitry Andric 
26800b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
26810b57cec5SDimitry Andric     return error("expected syntax intpred(whatever) or floatpred(whatever");
26820b57cec5SDimitry Andric 
26830b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier))
26840b57cec5SDimitry Andric     return error("whatever");
26850b57cec5SDimitry Andric 
26860b57cec5SDimitry Andric   CmpInst::Predicate Pred;
26870b57cec5SDimitry Andric   if (IsFloat) {
26880b57cec5SDimitry Andric     Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
26890b57cec5SDimitry Andric                .Case("false", CmpInst::FCMP_FALSE)
26900b57cec5SDimitry Andric                .Case("oeq", CmpInst::FCMP_OEQ)
26910b57cec5SDimitry Andric                .Case("ogt", CmpInst::FCMP_OGT)
26920b57cec5SDimitry Andric                .Case("oge", CmpInst::FCMP_OGE)
26930b57cec5SDimitry Andric                .Case("olt", CmpInst::FCMP_OLT)
26940b57cec5SDimitry Andric                .Case("ole", CmpInst::FCMP_OLE)
26950b57cec5SDimitry Andric                .Case("one", CmpInst::FCMP_ONE)
26960b57cec5SDimitry Andric                .Case("ord", CmpInst::FCMP_ORD)
26970b57cec5SDimitry Andric                .Case("uno", CmpInst::FCMP_UNO)
26980b57cec5SDimitry Andric                .Case("ueq", CmpInst::FCMP_UEQ)
26990b57cec5SDimitry Andric                .Case("ugt", CmpInst::FCMP_UGT)
27000b57cec5SDimitry Andric                .Case("uge", CmpInst::FCMP_UGE)
27010b57cec5SDimitry Andric                .Case("ult", CmpInst::FCMP_ULT)
27020b57cec5SDimitry Andric                .Case("ule", CmpInst::FCMP_ULE)
27030b57cec5SDimitry Andric                .Case("une", CmpInst::FCMP_UNE)
27040b57cec5SDimitry Andric                .Case("true", CmpInst::FCMP_TRUE)
27050b57cec5SDimitry Andric                .Default(CmpInst::BAD_FCMP_PREDICATE);
27060b57cec5SDimitry Andric     if (!CmpInst::isFPPredicate(Pred))
27070b57cec5SDimitry Andric       return error("invalid floating-point predicate");
27080b57cec5SDimitry Andric   } else {
27090b57cec5SDimitry Andric     Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
27100b57cec5SDimitry Andric                .Case("eq", CmpInst::ICMP_EQ)
27110b57cec5SDimitry Andric                .Case("ne", CmpInst::ICMP_NE)
27120b57cec5SDimitry Andric                .Case("sgt", CmpInst::ICMP_SGT)
27130b57cec5SDimitry Andric                .Case("sge", CmpInst::ICMP_SGE)
27140b57cec5SDimitry Andric                .Case("slt", CmpInst::ICMP_SLT)
27150b57cec5SDimitry Andric                .Case("sle", CmpInst::ICMP_SLE)
27160b57cec5SDimitry Andric                .Case("ugt", CmpInst::ICMP_UGT)
27170b57cec5SDimitry Andric                .Case("uge", CmpInst::ICMP_UGE)
27180b57cec5SDimitry Andric                .Case("ult", CmpInst::ICMP_ULT)
27190b57cec5SDimitry Andric                .Case("ule", CmpInst::ICMP_ULE)
27200b57cec5SDimitry Andric                .Default(CmpInst::BAD_ICMP_PREDICATE);
27210b57cec5SDimitry Andric     if (!CmpInst::isIntPredicate(Pred))
27220b57cec5SDimitry Andric       return error("invalid integer predicate");
27230b57cec5SDimitry Andric   }
27240b57cec5SDimitry Andric 
27250b57cec5SDimitry Andric   lex();
27260b57cec5SDimitry Andric   Dest = MachineOperand::CreatePredicate(Pred);
27270b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
27280b57cec5SDimitry Andric     return error("predicate should be terminated by ')'.");
27290b57cec5SDimitry Andric 
27300b57cec5SDimitry Andric   return false;
27310b57cec5SDimitry Andric }
27320b57cec5SDimitry Andric 
27338bcb0991SDimitry Andric bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
27348bcb0991SDimitry Andric   assert(Token.is(MIToken::kw_shufflemask));
27358bcb0991SDimitry Andric 
27368bcb0991SDimitry Andric   lex();
27378bcb0991SDimitry Andric   if (expectAndConsume(MIToken::lparen))
27388bcb0991SDimitry Andric     return error("expected syntax shufflemask(<integer or undef>, ...)");
27398bcb0991SDimitry Andric 
2740480093f4SDimitry Andric   SmallVector<int, 32> ShufMask;
27418bcb0991SDimitry Andric   do {
27428bcb0991SDimitry Andric     if (Token.is(MIToken::kw_undef)) {
2743480093f4SDimitry Andric       ShufMask.push_back(-1);
27448bcb0991SDimitry Andric     } else if (Token.is(MIToken::IntegerLiteral)) {
27458bcb0991SDimitry Andric       const APSInt &Int = Token.integerValue();
2746480093f4SDimitry Andric       ShufMask.push_back(Int.getExtValue());
27478bcb0991SDimitry Andric     } else
27488bcb0991SDimitry Andric       return error("expected integer constant");
27498bcb0991SDimitry Andric 
27508bcb0991SDimitry Andric     lex();
27518bcb0991SDimitry Andric   } while (consumeIfPresent(MIToken::comma));
27528bcb0991SDimitry Andric 
27538bcb0991SDimitry Andric   if (expectAndConsume(MIToken::rparen))
27548bcb0991SDimitry Andric     return error("shufflemask should be terminated by ')'.");
27558bcb0991SDimitry Andric 
2756480093f4SDimitry Andric   ArrayRef<int> MaskAlloc = MF.allocateShuffleMask(ShufMask);
2757480093f4SDimitry Andric   Dest = MachineOperand::CreateShuffleMask(MaskAlloc);
27588bcb0991SDimitry Andric   return false;
27598bcb0991SDimitry Andric }
27608bcb0991SDimitry Andric 
2761bdd1243dSDimitry Andric bool MIParser::parseDbgInstrRefOperand(MachineOperand &Dest) {
2762bdd1243dSDimitry Andric   assert(Token.is(MIToken::kw_dbg_instr_ref));
2763bdd1243dSDimitry Andric 
2764bdd1243dSDimitry Andric   lex();
2765bdd1243dSDimitry Andric   if (expectAndConsume(MIToken::lparen))
2766bdd1243dSDimitry Andric     return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2767bdd1243dSDimitry Andric 
2768bdd1243dSDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
2769bdd1243dSDimitry Andric     return error("expected unsigned integer for instruction index");
2770bdd1243dSDimitry Andric   uint64_t InstrIdx = Token.integerValue().getZExtValue();
2771bdd1243dSDimitry Andric   assert(InstrIdx <= std::numeric_limits<unsigned>::max() &&
2772bdd1243dSDimitry Andric          "Instruction reference's instruction index is too large");
2773bdd1243dSDimitry Andric   lex();
2774bdd1243dSDimitry Andric 
2775bdd1243dSDimitry Andric   if (expectAndConsume(MIToken::comma))
2776bdd1243dSDimitry Andric     return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2777bdd1243dSDimitry Andric 
2778bdd1243dSDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
2779bdd1243dSDimitry Andric     return error("expected unsigned integer for operand index");
2780bdd1243dSDimitry Andric   uint64_t OpIdx = Token.integerValue().getZExtValue();
2781bdd1243dSDimitry Andric   assert(OpIdx <= std::numeric_limits<unsigned>::max() &&
2782bdd1243dSDimitry Andric          "Instruction reference's operand index is too large");
2783bdd1243dSDimitry Andric   lex();
2784bdd1243dSDimitry Andric 
2785bdd1243dSDimitry Andric   if (expectAndConsume(MIToken::rparen))
2786bdd1243dSDimitry Andric     return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2787bdd1243dSDimitry Andric 
2788bdd1243dSDimitry Andric   Dest = MachineOperand::CreateDbgInstrRef(InstrIdx, OpIdx);
2789bdd1243dSDimitry Andric   return false;
2790bdd1243dSDimitry Andric }
2791bdd1243dSDimitry Andric 
27920b57cec5SDimitry Andric bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
27930b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_target_index));
27940b57cec5SDimitry Andric   lex();
27950b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
27960b57cec5SDimitry Andric     return true;
27970b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier))
27980b57cec5SDimitry Andric     return error("expected the name of the target index");
27990b57cec5SDimitry Andric   int Index = 0;
28000b57cec5SDimitry Andric   if (PFS.Target.getTargetIndex(Token.stringValue(), Index))
28010b57cec5SDimitry Andric     return error("use of undefined target index '" + Token.stringValue() + "'");
28020b57cec5SDimitry Andric   lex();
28030b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
28040b57cec5SDimitry Andric     return true;
28050b57cec5SDimitry Andric   Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0);
28060b57cec5SDimitry Andric   if (parseOperandsOffset(Dest))
28070b57cec5SDimitry Andric     return true;
28080b57cec5SDimitry Andric   return false;
28090b57cec5SDimitry Andric }
28100b57cec5SDimitry Andric 
28110b57cec5SDimitry Andric bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) {
28120b57cec5SDimitry Andric   assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask");
28130b57cec5SDimitry Andric   lex();
28140b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
28150b57cec5SDimitry Andric     return true;
28160b57cec5SDimitry Andric 
28170b57cec5SDimitry Andric   uint32_t *Mask = MF.allocateRegMask();
281881ad6265SDimitry Andric   do {
281981ad6265SDimitry Andric     if (Token.isNot(MIToken::rparen)) {
28200b57cec5SDimitry Andric       if (Token.isNot(MIToken::NamedRegister))
28210b57cec5SDimitry Andric         return error("expected a named register");
28225ffd83dbSDimitry Andric       Register Reg;
28230b57cec5SDimitry Andric       if (parseNamedRegister(Reg))
28240b57cec5SDimitry Andric         return true;
28250b57cec5SDimitry Andric       lex();
28260b57cec5SDimitry Andric       Mask[Reg / 32] |= 1U << (Reg % 32);
28270b57cec5SDimitry Andric     }
28280b57cec5SDimitry Andric 
282981ad6265SDimitry Andric     // TODO: Report an error if the same register is used more than once.
283081ad6265SDimitry Andric   } while (consumeIfPresent(MIToken::comma));
283181ad6265SDimitry Andric 
28320b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
28330b57cec5SDimitry Andric     return true;
28340b57cec5SDimitry Andric   Dest = MachineOperand::CreateRegMask(Mask);
28350b57cec5SDimitry Andric   return false;
28360b57cec5SDimitry Andric }
28370b57cec5SDimitry Andric 
28380b57cec5SDimitry Andric bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) {
28390b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_liveout));
28400b57cec5SDimitry Andric   uint32_t *Mask = MF.allocateRegMask();
28410b57cec5SDimitry Andric   lex();
28420b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
28430b57cec5SDimitry Andric     return true;
28440b57cec5SDimitry Andric   while (true) {
28450b57cec5SDimitry Andric     if (Token.isNot(MIToken::NamedRegister))
28460b57cec5SDimitry Andric       return error("expected a named register");
28475ffd83dbSDimitry Andric     Register Reg;
28480b57cec5SDimitry Andric     if (parseNamedRegister(Reg))
28490b57cec5SDimitry Andric       return true;
28500b57cec5SDimitry Andric     lex();
28510b57cec5SDimitry Andric     Mask[Reg / 32] |= 1U << (Reg % 32);
28520b57cec5SDimitry Andric     // TODO: Report an error if the same register is used more than once.
28530b57cec5SDimitry Andric     if (Token.isNot(MIToken::comma))
28540b57cec5SDimitry Andric       break;
28550b57cec5SDimitry Andric     lex();
28560b57cec5SDimitry Andric   }
28570b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
28580b57cec5SDimitry Andric     return true;
28590b57cec5SDimitry Andric   Dest = MachineOperand::CreateRegLiveOut(Mask);
28600b57cec5SDimitry Andric   return false;
28610b57cec5SDimitry Andric }
28620b57cec5SDimitry Andric 
2863480093f4SDimitry Andric bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
2864480093f4SDimitry Andric                                    MachineOperand &Dest,
2865bdd1243dSDimitry Andric                                    std::optional<unsigned> &TiedDefIdx) {
28660b57cec5SDimitry Andric   switch (Token.kind()) {
28670b57cec5SDimitry Andric   case MIToken::kw_implicit:
28680b57cec5SDimitry Andric   case MIToken::kw_implicit_define:
28690b57cec5SDimitry Andric   case MIToken::kw_def:
28700b57cec5SDimitry Andric   case MIToken::kw_dead:
28710b57cec5SDimitry Andric   case MIToken::kw_killed:
28720b57cec5SDimitry Andric   case MIToken::kw_undef:
28730b57cec5SDimitry Andric   case MIToken::kw_internal:
28740b57cec5SDimitry Andric   case MIToken::kw_early_clobber:
28750b57cec5SDimitry Andric   case MIToken::kw_debug_use:
28760b57cec5SDimitry Andric   case MIToken::kw_renamable:
28770b57cec5SDimitry Andric   case MIToken::underscore:
28780b57cec5SDimitry Andric   case MIToken::NamedRegister:
28790b57cec5SDimitry Andric   case MIToken::VirtualRegister:
28800b57cec5SDimitry Andric   case MIToken::NamedVirtualRegister:
28810b57cec5SDimitry Andric     return parseRegisterOperand(Dest, TiedDefIdx);
28820b57cec5SDimitry Andric   case MIToken::IntegerLiteral:
28830b57cec5SDimitry Andric     return parseImmediateOperand(Dest);
28840b57cec5SDimitry Andric   case MIToken::kw_half:
2885*0fca6ea1SDimitry Andric   case MIToken::kw_bfloat:
28860b57cec5SDimitry Andric   case MIToken::kw_float:
28870b57cec5SDimitry Andric   case MIToken::kw_double:
28880b57cec5SDimitry Andric   case MIToken::kw_x86_fp80:
28890b57cec5SDimitry Andric   case MIToken::kw_fp128:
28900b57cec5SDimitry Andric   case MIToken::kw_ppc_fp128:
28910b57cec5SDimitry Andric     return parseFPImmediateOperand(Dest);
28920b57cec5SDimitry Andric   case MIToken::MachineBasicBlock:
28930b57cec5SDimitry Andric     return parseMBBOperand(Dest);
28940b57cec5SDimitry Andric   case MIToken::StackObject:
28950b57cec5SDimitry Andric     return parseStackObjectOperand(Dest);
28960b57cec5SDimitry Andric   case MIToken::FixedStackObject:
28970b57cec5SDimitry Andric     return parseFixedStackObjectOperand(Dest);
28980b57cec5SDimitry Andric   case MIToken::GlobalValue:
28990b57cec5SDimitry Andric   case MIToken::NamedGlobalValue:
29000b57cec5SDimitry Andric     return parseGlobalAddressOperand(Dest);
29010b57cec5SDimitry Andric   case MIToken::ConstantPoolItem:
29020b57cec5SDimitry Andric     return parseConstantPoolIndexOperand(Dest);
29030b57cec5SDimitry Andric   case MIToken::JumpTableIndex:
29040b57cec5SDimitry Andric     return parseJumpTableIndexOperand(Dest);
29050b57cec5SDimitry Andric   case MIToken::ExternalSymbol:
29060b57cec5SDimitry Andric     return parseExternalSymbolOperand(Dest);
29070b57cec5SDimitry Andric   case MIToken::MCSymbol:
29080b57cec5SDimitry Andric     return parseMCSymbolOperand(Dest);
29090b57cec5SDimitry Andric   case MIToken::SubRegisterIndex:
29100b57cec5SDimitry Andric     return parseSubRegisterIndexOperand(Dest);
29110b57cec5SDimitry Andric   case MIToken::md_diexpr:
29120b57cec5SDimitry Andric   case MIToken::exclaim:
29130b57cec5SDimitry Andric     return parseMetadataOperand(Dest);
29140b57cec5SDimitry Andric   case MIToken::kw_cfi_same_value:
29150b57cec5SDimitry Andric   case MIToken::kw_cfi_offset:
29160b57cec5SDimitry Andric   case MIToken::kw_cfi_rel_offset:
29170b57cec5SDimitry Andric   case MIToken::kw_cfi_def_cfa_register:
29180b57cec5SDimitry Andric   case MIToken::kw_cfi_def_cfa_offset:
29190b57cec5SDimitry Andric   case MIToken::kw_cfi_adjust_cfa_offset:
29200b57cec5SDimitry Andric   case MIToken::kw_cfi_escape:
29210b57cec5SDimitry Andric   case MIToken::kw_cfi_def_cfa:
2922fe6060f1SDimitry Andric   case MIToken::kw_cfi_llvm_def_aspace_cfa:
29230b57cec5SDimitry Andric   case MIToken::kw_cfi_register:
29240b57cec5SDimitry Andric   case MIToken::kw_cfi_remember_state:
29250b57cec5SDimitry Andric   case MIToken::kw_cfi_restore:
29260b57cec5SDimitry Andric   case MIToken::kw_cfi_restore_state:
29270b57cec5SDimitry Andric   case MIToken::kw_cfi_undefined:
29280b57cec5SDimitry Andric   case MIToken::kw_cfi_window_save:
29290b57cec5SDimitry Andric   case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
29300b57cec5SDimitry Andric     return parseCFIOperand(Dest);
29310b57cec5SDimitry Andric   case MIToken::kw_blockaddress:
29320b57cec5SDimitry Andric     return parseBlockAddressOperand(Dest);
29330b57cec5SDimitry Andric   case MIToken::kw_intrinsic:
29340b57cec5SDimitry Andric     return parseIntrinsicOperand(Dest);
29350b57cec5SDimitry Andric   case MIToken::kw_target_index:
29360b57cec5SDimitry Andric     return parseTargetIndexOperand(Dest);
29370b57cec5SDimitry Andric   case MIToken::kw_liveout:
29380b57cec5SDimitry Andric     return parseLiveoutRegisterMaskOperand(Dest);
29390b57cec5SDimitry Andric   case MIToken::kw_floatpred:
29400b57cec5SDimitry Andric   case MIToken::kw_intpred:
29410b57cec5SDimitry Andric     return parsePredicateOperand(Dest);
29428bcb0991SDimitry Andric   case MIToken::kw_shufflemask:
29438bcb0991SDimitry Andric     return parseShuffleMaskOperand(Dest);
2944bdd1243dSDimitry Andric   case MIToken::kw_dbg_instr_ref:
2945bdd1243dSDimitry Andric     return parseDbgInstrRefOperand(Dest);
29460b57cec5SDimitry Andric   case MIToken::Error:
29470b57cec5SDimitry Andric     return true;
29480b57cec5SDimitry Andric   case MIToken::Identifier:
29490b57cec5SDimitry Andric     if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) {
29500b57cec5SDimitry Andric       Dest = MachineOperand::CreateRegMask(RegMask);
29510b57cec5SDimitry Andric       lex();
29520b57cec5SDimitry Andric       break;
29530b57cec5SDimitry Andric     } else if (Token.stringValue() == "CustomRegMask") {
29540b57cec5SDimitry Andric       return parseCustomRegisterMaskOperand(Dest);
29550b57cec5SDimitry Andric     } else
29560b57cec5SDimitry Andric       return parseTypedImmediateOperand(Dest);
2957480093f4SDimitry Andric   case MIToken::dot: {
2958480093f4SDimitry Andric     const auto *TII = MF.getSubtarget().getInstrInfo();
2959480093f4SDimitry Andric     if (const auto *Formatter = TII->getMIRFormatter()) {
2960480093f4SDimitry Andric       return parseTargetImmMnemonic(OpCode, OpIdx, Dest, *Formatter);
2961480093f4SDimitry Andric     }
2962bdd1243dSDimitry Andric     [[fallthrough]];
2963480093f4SDimitry Andric   }
29640b57cec5SDimitry Andric   default:
29650b57cec5SDimitry Andric     // FIXME: Parse the MCSymbol machine operand.
29660b57cec5SDimitry Andric     return error("expected a machine operand");
29670b57cec5SDimitry Andric   }
29680b57cec5SDimitry Andric   return false;
29690b57cec5SDimitry Andric }
29700b57cec5SDimitry Andric 
29710b57cec5SDimitry Andric bool MIParser::parseMachineOperandAndTargetFlags(
2972480093f4SDimitry Andric     const unsigned OpCode, const unsigned OpIdx, MachineOperand &Dest,
2973bdd1243dSDimitry Andric     std::optional<unsigned> &TiedDefIdx) {
29740b57cec5SDimitry Andric   unsigned TF = 0;
29750b57cec5SDimitry Andric   bool HasTargetFlags = false;
29760b57cec5SDimitry Andric   if (Token.is(MIToken::kw_target_flags)) {
29770b57cec5SDimitry Andric     HasTargetFlags = true;
29780b57cec5SDimitry Andric     lex();
29790b57cec5SDimitry Andric     if (expectAndConsume(MIToken::lparen))
29800b57cec5SDimitry Andric       return true;
29810b57cec5SDimitry Andric     if (Token.isNot(MIToken::Identifier))
29820b57cec5SDimitry Andric       return error("expected the name of the target flag");
29830b57cec5SDimitry Andric     if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) {
29840b57cec5SDimitry Andric       if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF))
29850b57cec5SDimitry Andric         return error("use of undefined target flag '" + Token.stringValue() +
29860b57cec5SDimitry Andric                      "'");
29870b57cec5SDimitry Andric     }
29880b57cec5SDimitry Andric     lex();
29890b57cec5SDimitry Andric     while (Token.is(MIToken::comma)) {
29900b57cec5SDimitry Andric       lex();
29910b57cec5SDimitry Andric       if (Token.isNot(MIToken::Identifier))
29920b57cec5SDimitry Andric         return error("expected the name of the target flag");
29930b57cec5SDimitry Andric       unsigned BitFlag = 0;
29940b57cec5SDimitry Andric       if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag))
29950b57cec5SDimitry Andric         return error("use of undefined target flag '" + Token.stringValue() +
29960b57cec5SDimitry Andric                      "'");
29970b57cec5SDimitry Andric       // TODO: Report an error when using a duplicate bit target flag.
29980b57cec5SDimitry Andric       TF |= BitFlag;
29990b57cec5SDimitry Andric       lex();
30000b57cec5SDimitry Andric     }
30010b57cec5SDimitry Andric     if (expectAndConsume(MIToken::rparen))
30020b57cec5SDimitry Andric       return true;
30030b57cec5SDimitry Andric   }
30040b57cec5SDimitry Andric   auto Loc = Token.location();
3005480093f4SDimitry Andric   if (parseMachineOperand(OpCode, OpIdx, Dest, TiedDefIdx))
30060b57cec5SDimitry Andric     return true;
30070b57cec5SDimitry Andric   if (!HasTargetFlags)
30080b57cec5SDimitry Andric     return false;
30090b57cec5SDimitry Andric   if (Dest.isReg())
30100b57cec5SDimitry Andric     return error(Loc, "register operands can't have target flags");
30110b57cec5SDimitry Andric   Dest.setTargetFlags(TF);
30120b57cec5SDimitry Andric   return false;
30130b57cec5SDimitry Andric }
30140b57cec5SDimitry Andric 
30150b57cec5SDimitry Andric bool MIParser::parseOffset(int64_t &Offset) {
30160b57cec5SDimitry Andric   if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus))
30170b57cec5SDimitry Andric     return false;
30180b57cec5SDimitry Andric   StringRef Sign = Token.range();
30190b57cec5SDimitry Andric   bool IsNegative = Token.is(MIToken::minus);
30200b57cec5SDimitry Andric   lex();
30210b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral))
30220b57cec5SDimitry Andric     return error("expected an integer literal after '" + Sign + "'");
302306c3fb27SDimitry Andric   if (Token.integerValue().getSignificantBits() > 64)
30240b57cec5SDimitry Andric     return error("expected 64-bit integer (too large)");
30250b57cec5SDimitry Andric   Offset = Token.integerValue().getExtValue();
30260b57cec5SDimitry Andric   if (IsNegative)
30270b57cec5SDimitry Andric     Offset = -Offset;
30280b57cec5SDimitry Andric   lex();
30290b57cec5SDimitry Andric   return false;
30300b57cec5SDimitry Andric }
30310b57cec5SDimitry Andric 
3032bdd1243dSDimitry Andric bool MIParser::parseIRBlockAddressTaken(BasicBlock *&BB) {
3033bdd1243dSDimitry Andric   assert(Token.is(MIToken::kw_ir_block_address_taken));
3034bdd1243dSDimitry Andric   lex();
3035bdd1243dSDimitry Andric   if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
3036bdd1243dSDimitry Andric     return error("expected basic block after 'ir_block_address_taken'");
3037bdd1243dSDimitry Andric 
3038bdd1243dSDimitry Andric   if (parseIRBlock(BB, MF.getFunction()))
3039bdd1243dSDimitry Andric     return true;
3040bdd1243dSDimitry Andric 
3041bdd1243dSDimitry Andric   lex();
3042bdd1243dSDimitry Andric   return false;
3043bdd1243dSDimitry Andric }
3044bdd1243dSDimitry Andric 
3045349cc55cSDimitry Andric bool MIParser::parseAlignment(uint64_t &Alignment) {
3046e8d8bef9SDimitry Andric   assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
30470b57cec5SDimitry Andric   lex();
30480b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
30490b57cec5SDimitry Andric     return error("expected an integer literal after 'align'");
3050349cc55cSDimitry Andric   if (getUint64(Alignment))
30510b57cec5SDimitry Andric     return true;
30520b57cec5SDimitry Andric   lex();
30530b57cec5SDimitry Andric 
3054349cc55cSDimitry Andric   if (!isPowerOf2_64(Alignment))
30550b57cec5SDimitry Andric     return error("expected a power-of-2 literal after 'align'");
30560b57cec5SDimitry Andric 
30570b57cec5SDimitry Andric   return false;
30580b57cec5SDimitry Andric }
30590b57cec5SDimitry Andric 
30600b57cec5SDimitry Andric bool MIParser::parseAddrspace(unsigned &Addrspace) {
30610b57cec5SDimitry Andric   assert(Token.is(MIToken::kw_addrspace));
30620b57cec5SDimitry Andric   lex();
30630b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
30640b57cec5SDimitry Andric     return error("expected an integer literal after 'addrspace'");
30650b57cec5SDimitry Andric   if (getUnsigned(Addrspace))
30660b57cec5SDimitry Andric     return true;
30670b57cec5SDimitry Andric   lex();
30680b57cec5SDimitry Andric   return false;
30690b57cec5SDimitry Andric }
30700b57cec5SDimitry Andric 
30710b57cec5SDimitry Andric bool MIParser::parseOperandsOffset(MachineOperand &Op) {
30720b57cec5SDimitry Andric   int64_t Offset = 0;
30730b57cec5SDimitry Andric   if (parseOffset(Offset))
30740b57cec5SDimitry Andric     return true;
30750b57cec5SDimitry Andric   Op.setOffset(Offset);
30760b57cec5SDimitry Andric   return false;
30770b57cec5SDimitry Andric }
30780b57cec5SDimitry Andric 
3079480093f4SDimitry Andric static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS,
3080480093f4SDimitry Andric                          const Value *&V, ErrorCallbackType ErrCB) {
30810b57cec5SDimitry Andric   switch (Token.kind()) {
30820b57cec5SDimitry Andric   case MIToken::NamedIRValue: {
3083480093f4SDimitry Andric     V = PFS.MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue());
30840b57cec5SDimitry Andric     break;
30850b57cec5SDimitry Andric   }
30860b57cec5SDimitry Andric   case MIToken::IRValue: {
30870b57cec5SDimitry Andric     unsigned SlotNumber = 0;
3088480093f4SDimitry Andric     if (getUnsigned(Token, SlotNumber, ErrCB))
30890b57cec5SDimitry Andric       return true;
3090480093f4SDimitry Andric     V = PFS.getIRValue(SlotNumber);
30910b57cec5SDimitry Andric     break;
30920b57cec5SDimitry Andric   }
30930b57cec5SDimitry Andric   case MIToken::NamedGlobalValue:
30940b57cec5SDimitry Andric   case MIToken::GlobalValue: {
30950b57cec5SDimitry Andric     GlobalValue *GV = nullptr;
3096480093f4SDimitry Andric     if (parseGlobalValue(Token, PFS, GV, ErrCB))
30970b57cec5SDimitry Andric       return true;
30980b57cec5SDimitry Andric     V = GV;
30990b57cec5SDimitry Andric     break;
31000b57cec5SDimitry Andric   }
31010b57cec5SDimitry Andric   case MIToken::QuotedIRValue: {
31020b57cec5SDimitry Andric     const Constant *C = nullptr;
3103480093f4SDimitry Andric     if (parseIRConstant(Token.location(), Token.stringValue(), PFS, C, ErrCB))
31040b57cec5SDimitry Andric       return true;
31050b57cec5SDimitry Andric     V = C;
31060b57cec5SDimitry Andric     break;
31070b57cec5SDimitry Andric   }
3108fe6060f1SDimitry Andric   case MIToken::kw_unknown_address:
3109fe6060f1SDimitry Andric     V = nullptr;
3110fe6060f1SDimitry Andric     return false;
31110b57cec5SDimitry Andric   default:
31120b57cec5SDimitry Andric     llvm_unreachable("The current token should be an IR block reference");
31130b57cec5SDimitry Andric   }
31140b57cec5SDimitry Andric   if (!V)
3115480093f4SDimitry Andric     return ErrCB(Token.location(), Twine("use of undefined IR value '") + Token.range() + "'");
31160b57cec5SDimitry Andric   return false;
31170b57cec5SDimitry Andric }
31180b57cec5SDimitry Andric 
3119480093f4SDimitry Andric bool MIParser::parseIRValue(const Value *&V) {
3120480093f4SDimitry Andric   return ::parseIRValue(
3121480093f4SDimitry Andric       Token, PFS, V, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
3122480093f4SDimitry Andric         return error(Loc, Msg);
3123480093f4SDimitry Andric       });
3124480093f4SDimitry Andric }
3125480093f4SDimitry Andric 
31260b57cec5SDimitry Andric bool MIParser::getUint64(uint64_t &Result) {
31270b57cec5SDimitry Andric   if (Token.hasIntegerValue()) {
31280b57cec5SDimitry Andric     if (Token.integerValue().getActiveBits() > 64)
31290b57cec5SDimitry Andric       return error("expected 64-bit integer (too large)");
31300b57cec5SDimitry Andric     Result = Token.integerValue().getZExtValue();
31310b57cec5SDimitry Andric     return false;
31320b57cec5SDimitry Andric   }
31330b57cec5SDimitry Andric   if (Token.is(MIToken::HexLiteral)) {
31340b57cec5SDimitry Andric     APInt A;
31350b57cec5SDimitry Andric     if (getHexUint(A))
31360b57cec5SDimitry Andric       return true;
31370b57cec5SDimitry Andric     if (A.getBitWidth() > 64)
31380b57cec5SDimitry Andric       return error("expected 64-bit integer (too large)");
31390b57cec5SDimitry Andric     Result = A.getZExtValue();
31400b57cec5SDimitry Andric     return false;
31410b57cec5SDimitry Andric   }
31420b57cec5SDimitry Andric   return true;
31430b57cec5SDimitry Andric }
31440b57cec5SDimitry Andric 
31450b57cec5SDimitry Andric bool MIParser::getHexUint(APInt &Result) {
3146480093f4SDimitry Andric   return ::getHexUint(Token, Result);
31470b57cec5SDimitry Andric }
31480b57cec5SDimitry Andric 
31490b57cec5SDimitry Andric bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
31500b57cec5SDimitry Andric   const auto OldFlags = Flags;
31510b57cec5SDimitry Andric   switch (Token.kind()) {
31520b57cec5SDimitry Andric   case MIToken::kw_volatile:
31530b57cec5SDimitry Andric     Flags |= MachineMemOperand::MOVolatile;
31540b57cec5SDimitry Andric     break;
31550b57cec5SDimitry Andric   case MIToken::kw_non_temporal:
31560b57cec5SDimitry Andric     Flags |= MachineMemOperand::MONonTemporal;
31570b57cec5SDimitry Andric     break;
31580b57cec5SDimitry Andric   case MIToken::kw_dereferenceable:
31590b57cec5SDimitry Andric     Flags |= MachineMemOperand::MODereferenceable;
31600b57cec5SDimitry Andric     break;
31610b57cec5SDimitry Andric   case MIToken::kw_invariant:
31620b57cec5SDimitry Andric     Flags |= MachineMemOperand::MOInvariant;
31630b57cec5SDimitry Andric     break;
31640b57cec5SDimitry Andric   case MIToken::StringConstant: {
31650b57cec5SDimitry Andric     MachineMemOperand::Flags TF;
31660b57cec5SDimitry Andric     if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF))
31670b57cec5SDimitry Andric       return error("use of undefined target MMO flag '" + Token.stringValue() +
31680b57cec5SDimitry Andric                    "'");
31690b57cec5SDimitry Andric     Flags |= TF;
31700b57cec5SDimitry Andric     break;
31710b57cec5SDimitry Andric   }
31720b57cec5SDimitry Andric   default:
31730b57cec5SDimitry Andric     llvm_unreachable("The current token should be a memory operand flag");
31740b57cec5SDimitry Andric   }
31750b57cec5SDimitry Andric   if (OldFlags == Flags)
31760b57cec5SDimitry Andric     // We know that the same flag is specified more than once when the flags
31770b57cec5SDimitry Andric     // weren't modified.
31780b57cec5SDimitry Andric     return error("duplicate '" + Token.stringValue() + "' memory operand flag");
31790b57cec5SDimitry Andric   lex();
31800b57cec5SDimitry Andric   return false;
31810b57cec5SDimitry Andric }
31820b57cec5SDimitry Andric 
31830b57cec5SDimitry Andric bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) {
31840b57cec5SDimitry Andric   switch (Token.kind()) {
31850b57cec5SDimitry Andric   case MIToken::kw_stack:
31860b57cec5SDimitry Andric     PSV = MF.getPSVManager().getStack();
31870b57cec5SDimitry Andric     break;
31880b57cec5SDimitry Andric   case MIToken::kw_got:
31890b57cec5SDimitry Andric     PSV = MF.getPSVManager().getGOT();
31900b57cec5SDimitry Andric     break;
31910b57cec5SDimitry Andric   case MIToken::kw_jump_table:
31920b57cec5SDimitry Andric     PSV = MF.getPSVManager().getJumpTable();
31930b57cec5SDimitry Andric     break;
31940b57cec5SDimitry Andric   case MIToken::kw_constant_pool:
31950b57cec5SDimitry Andric     PSV = MF.getPSVManager().getConstantPool();
31960b57cec5SDimitry Andric     break;
31970b57cec5SDimitry Andric   case MIToken::FixedStackObject: {
31980b57cec5SDimitry Andric     int FI;
31990b57cec5SDimitry Andric     if (parseFixedStackFrameIndex(FI))
32000b57cec5SDimitry Andric       return true;
32010b57cec5SDimitry Andric     PSV = MF.getPSVManager().getFixedStack(FI);
32020b57cec5SDimitry Andric     // The token was already consumed, so use return here instead of break.
32030b57cec5SDimitry Andric     return false;
32040b57cec5SDimitry Andric   }
32050b57cec5SDimitry Andric   case MIToken::StackObject: {
32060b57cec5SDimitry Andric     int FI;
32070b57cec5SDimitry Andric     if (parseStackFrameIndex(FI))
32080b57cec5SDimitry Andric       return true;
32090b57cec5SDimitry Andric     PSV = MF.getPSVManager().getFixedStack(FI);
32100b57cec5SDimitry Andric     // The token was already consumed, so use return here instead of break.
32110b57cec5SDimitry Andric     return false;
32120b57cec5SDimitry Andric   }
32130b57cec5SDimitry Andric   case MIToken::kw_call_entry:
32140b57cec5SDimitry Andric     lex();
32150b57cec5SDimitry Andric     switch (Token.kind()) {
32160b57cec5SDimitry Andric     case MIToken::GlobalValue:
32170b57cec5SDimitry Andric     case MIToken::NamedGlobalValue: {
32180b57cec5SDimitry Andric       GlobalValue *GV = nullptr;
32190b57cec5SDimitry Andric       if (parseGlobalValue(GV))
32200b57cec5SDimitry Andric         return true;
32210b57cec5SDimitry Andric       PSV = MF.getPSVManager().getGlobalValueCallEntry(GV);
32220b57cec5SDimitry Andric       break;
32230b57cec5SDimitry Andric     }
32240b57cec5SDimitry Andric     case MIToken::ExternalSymbol:
32250b57cec5SDimitry Andric       PSV = MF.getPSVManager().getExternalSymbolCallEntry(
32260b57cec5SDimitry Andric           MF.createExternalSymbolName(Token.stringValue()));
32270b57cec5SDimitry Andric       break;
32280b57cec5SDimitry Andric     default:
32290b57cec5SDimitry Andric       return error(
32300b57cec5SDimitry Andric           "expected a global value or an external symbol after 'call-entry'");
32310b57cec5SDimitry Andric     }
32320b57cec5SDimitry Andric     break;
3233480093f4SDimitry Andric   case MIToken::kw_custom: {
3234480093f4SDimitry Andric     lex();
3235480093f4SDimitry Andric     const auto *TII = MF.getSubtarget().getInstrInfo();
3236480093f4SDimitry Andric     if (const auto *Formatter = TII->getMIRFormatter()) {
3237480093f4SDimitry Andric       if (Formatter->parseCustomPseudoSourceValue(
3238480093f4SDimitry Andric               Token.stringValue(), MF, PFS, PSV,
3239480093f4SDimitry Andric               [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
3240480093f4SDimitry Andric                 return error(Loc, Msg);
3241480093f4SDimitry Andric               }))
3242480093f4SDimitry Andric         return true;
3243480093f4SDimitry Andric     } else
3244480093f4SDimitry Andric       return error("unable to parse target custom pseudo source value");
3245480093f4SDimitry Andric     break;
3246480093f4SDimitry Andric   }
32470b57cec5SDimitry Andric   default:
32480b57cec5SDimitry Andric     llvm_unreachable("The current token should be pseudo source value");
32490b57cec5SDimitry Andric   }
32500b57cec5SDimitry Andric   lex();
32510b57cec5SDimitry Andric   return false;
32520b57cec5SDimitry Andric }
32530b57cec5SDimitry Andric 
32540b57cec5SDimitry Andric bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
32550b57cec5SDimitry Andric   if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) ||
32560b57cec5SDimitry Andric       Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) ||
32570b57cec5SDimitry Andric       Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) ||
3258480093f4SDimitry Andric       Token.is(MIToken::kw_call_entry) || Token.is(MIToken::kw_custom)) {
32590b57cec5SDimitry Andric     const PseudoSourceValue *PSV = nullptr;
32600b57cec5SDimitry Andric     if (parseMemoryPseudoSourceValue(PSV))
32610b57cec5SDimitry Andric       return true;
32620b57cec5SDimitry Andric     int64_t Offset = 0;
32630b57cec5SDimitry Andric     if (parseOffset(Offset))
32640b57cec5SDimitry Andric       return true;
32650b57cec5SDimitry Andric     Dest = MachinePointerInfo(PSV, Offset);
32660b57cec5SDimitry Andric     return false;
32670b57cec5SDimitry Andric   }
32680b57cec5SDimitry Andric   if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) &&
32690b57cec5SDimitry Andric       Token.isNot(MIToken::GlobalValue) &&
32700b57cec5SDimitry Andric       Token.isNot(MIToken::NamedGlobalValue) &&
3271fe6060f1SDimitry Andric       Token.isNot(MIToken::QuotedIRValue) &&
3272fe6060f1SDimitry Andric       Token.isNot(MIToken::kw_unknown_address))
32730b57cec5SDimitry Andric     return error("expected an IR value reference");
32740b57cec5SDimitry Andric   const Value *V = nullptr;
32750b57cec5SDimitry Andric   if (parseIRValue(V))
32760b57cec5SDimitry Andric     return true;
3277fe6060f1SDimitry Andric   if (V && !V->getType()->isPointerTy())
32780b57cec5SDimitry Andric     return error("expected a pointer IR value");
32790b57cec5SDimitry Andric   lex();
32800b57cec5SDimitry Andric   int64_t Offset = 0;
32810b57cec5SDimitry Andric   if (parseOffset(Offset))
32820b57cec5SDimitry Andric     return true;
32830b57cec5SDimitry Andric   Dest = MachinePointerInfo(V, Offset);
32840b57cec5SDimitry Andric   return false;
32850b57cec5SDimitry Andric }
32860b57cec5SDimitry Andric 
32870b57cec5SDimitry Andric bool MIParser::parseOptionalScope(LLVMContext &Context,
32880b57cec5SDimitry Andric                                   SyncScope::ID &SSID) {
32890b57cec5SDimitry Andric   SSID = SyncScope::System;
32900b57cec5SDimitry Andric   if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") {
32910b57cec5SDimitry Andric     lex();
32920b57cec5SDimitry Andric     if (expectAndConsume(MIToken::lparen))
32930b57cec5SDimitry Andric       return error("expected '(' in syncscope");
32940b57cec5SDimitry Andric 
32950b57cec5SDimitry Andric     std::string SSN;
32960b57cec5SDimitry Andric     if (parseStringConstant(SSN))
32970b57cec5SDimitry Andric       return true;
32980b57cec5SDimitry Andric 
32990b57cec5SDimitry Andric     SSID = Context.getOrInsertSyncScopeID(SSN);
33000b57cec5SDimitry Andric     if (expectAndConsume(MIToken::rparen))
33010b57cec5SDimitry Andric       return error("expected ')' in syncscope");
33020b57cec5SDimitry Andric   }
33030b57cec5SDimitry Andric 
33040b57cec5SDimitry Andric   return false;
33050b57cec5SDimitry Andric }
33060b57cec5SDimitry Andric 
33070b57cec5SDimitry Andric bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) {
33080b57cec5SDimitry Andric   Order = AtomicOrdering::NotAtomic;
33090b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier))
33100b57cec5SDimitry Andric     return false;
33110b57cec5SDimitry Andric 
33120b57cec5SDimitry Andric   Order = StringSwitch<AtomicOrdering>(Token.stringValue())
33130b57cec5SDimitry Andric               .Case("unordered", AtomicOrdering::Unordered)
33140b57cec5SDimitry Andric               .Case("monotonic", AtomicOrdering::Monotonic)
33150b57cec5SDimitry Andric               .Case("acquire", AtomicOrdering::Acquire)
33160b57cec5SDimitry Andric               .Case("release", AtomicOrdering::Release)
33170b57cec5SDimitry Andric               .Case("acq_rel", AtomicOrdering::AcquireRelease)
33180b57cec5SDimitry Andric               .Case("seq_cst", AtomicOrdering::SequentiallyConsistent)
33190b57cec5SDimitry Andric               .Default(AtomicOrdering::NotAtomic);
33200b57cec5SDimitry Andric 
33210b57cec5SDimitry Andric   if (Order != AtomicOrdering::NotAtomic) {
33220b57cec5SDimitry Andric     lex();
33230b57cec5SDimitry Andric     return false;
33240b57cec5SDimitry Andric   }
33250b57cec5SDimitry Andric 
33260b57cec5SDimitry Andric   return error("expected an atomic scope, ordering or a size specification");
33270b57cec5SDimitry Andric }
33280b57cec5SDimitry Andric 
33290b57cec5SDimitry Andric bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
33300b57cec5SDimitry Andric   if (expectAndConsume(MIToken::lparen))
33310b57cec5SDimitry Andric     return true;
33320b57cec5SDimitry Andric   MachineMemOperand::Flags Flags = MachineMemOperand::MONone;
33330b57cec5SDimitry Andric   while (Token.isMemoryOperandFlag()) {
33340b57cec5SDimitry Andric     if (parseMemoryOperandFlag(Flags))
33350b57cec5SDimitry Andric       return true;
33360b57cec5SDimitry Andric   }
33370b57cec5SDimitry Andric   if (Token.isNot(MIToken::Identifier) ||
33380b57cec5SDimitry Andric       (Token.stringValue() != "load" && Token.stringValue() != "store"))
33390b57cec5SDimitry Andric     return error("expected 'load' or 'store' memory operation");
33400b57cec5SDimitry Andric   if (Token.stringValue() == "load")
33410b57cec5SDimitry Andric     Flags |= MachineMemOperand::MOLoad;
33420b57cec5SDimitry Andric   else
33430b57cec5SDimitry Andric     Flags |= MachineMemOperand::MOStore;
33440b57cec5SDimitry Andric   lex();
33450b57cec5SDimitry Andric 
33460b57cec5SDimitry Andric   // Optional 'store' for operands that both load and store.
33470b57cec5SDimitry Andric   if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") {
33480b57cec5SDimitry Andric     Flags |= MachineMemOperand::MOStore;
33490b57cec5SDimitry Andric     lex();
33500b57cec5SDimitry Andric   }
33510b57cec5SDimitry Andric 
33520b57cec5SDimitry Andric   // Optional synchronization scope.
33530b57cec5SDimitry Andric   SyncScope::ID SSID;
33540b57cec5SDimitry Andric   if (parseOptionalScope(MF.getFunction().getContext(), SSID))
33550b57cec5SDimitry Andric     return true;
33560b57cec5SDimitry Andric 
33570b57cec5SDimitry Andric   // Up to two atomic orderings (cmpxchg provides guarantees on failure).
33580b57cec5SDimitry Andric   AtomicOrdering Order, FailureOrder;
33590b57cec5SDimitry Andric   if (parseOptionalAtomicOrdering(Order))
33600b57cec5SDimitry Andric     return true;
33610b57cec5SDimitry Andric 
33620b57cec5SDimitry Andric   if (parseOptionalAtomicOrdering(FailureOrder))
33630b57cec5SDimitry Andric     return true;
33640b57cec5SDimitry Andric 
3365fe6060f1SDimitry Andric   LLT MemoryType;
33660b57cec5SDimitry Andric   if (Token.isNot(MIToken::IntegerLiteral) &&
3367fe6060f1SDimitry Andric       Token.isNot(MIToken::kw_unknown_size) &&
3368fe6060f1SDimitry Andric       Token.isNot(MIToken::lparen))
3369fe6060f1SDimitry Andric     return error("expected memory LLT, the size integer literal or 'unknown-size' after "
33700b57cec5SDimitry Andric                  "memory operation");
3371fe6060f1SDimitry Andric 
3372fe6060f1SDimitry Andric   uint64_t Size = MemoryLocation::UnknownSize;
33730b57cec5SDimitry Andric   if (Token.is(MIToken::IntegerLiteral)) {
33740b57cec5SDimitry Andric     if (getUint64(Size))
33750b57cec5SDimitry Andric       return true;
3376fe6060f1SDimitry Andric 
3377fe6060f1SDimitry Andric     // Convert from bytes to bits for storage.
3378fe6060f1SDimitry Andric     MemoryType = LLT::scalar(8 * Size);
3379fe6060f1SDimitry Andric     lex();
33800b57cec5SDimitry Andric   } else if (Token.is(MIToken::kw_unknown_size)) {
33810b57cec5SDimitry Andric     Size = MemoryLocation::UnknownSize;
33820b57cec5SDimitry Andric     lex();
3383fe6060f1SDimitry Andric   } else {
3384fe6060f1SDimitry Andric     if (expectAndConsume(MIToken::lparen))
3385fe6060f1SDimitry Andric       return true;
3386fe6060f1SDimitry Andric     if (parseLowLevelType(Token.location(), MemoryType))
3387fe6060f1SDimitry Andric       return true;
3388fe6060f1SDimitry Andric     if (expectAndConsume(MIToken::rparen))
3389fe6060f1SDimitry Andric       return true;
3390fe6060f1SDimitry Andric 
3391fe6060f1SDimitry Andric     Size = MemoryType.getSizeInBytes();
3392fe6060f1SDimitry Andric   }
33930b57cec5SDimitry Andric 
33940b57cec5SDimitry Andric   MachinePointerInfo Ptr = MachinePointerInfo();
33950b57cec5SDimitry Andric   if (Token.is(MIToken::Identifier)) {
33960b57cec5SDimitry Andric     const char *Word =
33970b57cec5SDimitry Andric         ((Flags & MachineMemOperand::MOLoad) &&
33980b57cec5SDimitry Andric          (Flags & MachineMemOperand::MOStore))
33990b57cec5SDimitry Andric             ? "on"
34000b57cec5SDimitry Andric             : Flags & MachineMemOperand::MOLoad ? "from" : "into";
34010b57cec5SDimitry Andric     if (Token.stringValue() != Word)
34020b57cec5SDimitry Andric       return error(Twine("expected '") + Word + "'");
34030b57cec5SDimitry Andric     lex();
34040b57cec5SDimitry Andric 
34050b57cec5SDimitry Andric     if (parseMachinePointerInfo(Ptr))
34060b57cec5SDimitry Andric       return true;
34070b57cec5SDimitry Andric   }
3408349cc55cSDimitry Andric   uint64_t BaseAlignment =
3409fe6060f1SDimitry Andric       (Size != MemoryLocation::UnknownSize ? PowerOf2Ceil(Size) : 1);
34100b57cec5SDimitry Andric   AAMDNodes AAInfo;
34110b57cec5SDimitry Andric   MDNode *Range = nullptr;
34120b57cec5SDimitry Andric   while (consumeIfPresent(MIToken::comma)) {
34130b57cec5SDimitry Andric     switch (Token.kind()) {
341481ad6265SDimitry Andric     case MIToken::kw_align: {
3415e8d8bef9SDimitry Andric       // align is printed if it is different than size.
341681ad6265SDimitry Andric       uint64_t Alignment;
341781ad6265SDimitry Andric       if (parseAlignment(Alignment))
3418e8d8bef9SDimitry Andric         return true;
341981ad6265SDimitry Andric       if (Ptr.Offset & (Alignment - 1)) {
342081ad6265SDimitry Andric         // MachineMemOperand::getAlign never returns a value greater than the
342181ad6265SDimitry Andric         // alignment of offset, so this just guards against hand-written MIR
342281ad6265SDimitry Andric         // that specifies a large "align" value when it should probably use
342381ad6265SDimitry Andric         // "basealign" instead.
342481ad6265SDimitry Andric         return error("specified alignment is more aligned than offset");
342581ad6265SDimitry Andric       }
342681ad6265SDimitry Andric       BaseAlignment = Alignment;
3427e8d8bef9SDimitry Andric       break;
342881ad6265SDimitry Andric     }
3429e8d8bef9SDimitry Andric     case MIToken::kw_basealign:
3430e8d8bef9SDimitry Andric       // basealign is printed if it is different than align.
34310b57cec5SDimitry Andric       if (parseAlignment(BaseAlignment))
34320b57cec5SDimitry Andric         return true;
34330b57cec5SDimitry Andric       break;
34340b57cec5SDimitry Andric     case MIToken::kw_addrspace:
34350b57cec5SDimitry Andric       if (parseAddrspace(Ptr.AddrSpace))
34360b57cec5SDimitry Andric         return true;
34370b57cec5SDimitry Andric       break;
34380b57cec5SDimitry Andric     case MIToken::md_tbaa:
34390b57cec5SDimitry Andric       lex();
34400b57cec5SDimitry Andric       if (parseMDNode(AAInfo.TBAA))
34410b57cec5SDimitry Andric         return true;
34420b57cec5SDimitry Andric       break;
34430b57cec5SDimitry Andric     case MIToken::md_alias_scope:
34440b57cec5SDimitry Andric       lex();
34450b57cec5SDimitry Andric       if (parseMDNode(AAInfo.Scope))
34460b57cec5SDimitry Andric         return true;
34470b57cec5SDimitry Andric       break;
34480b57cec5SDimitry Andric     case MIToken::md_noalias:
34490b57cec5SDimitry Andric       lex();
34500b57cec5SDimitry Andric       if (parseMDNode(AAInfo.NoAlias))
34510b57cec5SDimitry Andric         return true;
34520b57cec5SDimitry Andric       break;
34530b57cec5SDimitry Andric     case MIToken::md_range:
34540b57cec5SDimitry Andric       lex();
34550b57cec5SDimitry Andric       if (parseMDNode(Range))
34560b57cec5SDimitry Andric         return true;
34570b57cec5SDimitry Andric       break;
34580b57cec5SDimitry Andric     // TODO: Report an error on duplicate metadata nodes.
34590b57cec5SDimitry Andric     default:
34600b57cec5SDimitry Andric       return error("expected 'align' or '!tbaa' or '!alias.scope' or "
34610b57cec5SDimitry Andric                    "'!noalias' or '!range'");
34620b57cec5SDimitry Andric     }
34630b57cec5SDimitry Andric   }
34640b57cec5SDimitry Andric   if (expectAndConsume(MIToken::rparen))
34650b57cec5SDimitry Andric     return true;
3466fe6060f1SDimitry Andric   Dest = MF.getMachineMemOperand(Ptr, Flags, MemoryType, Align(BaseAlignment),
3467fe6060f1SDimitry Andric                                  AAInfo, Range, SSID, Order, FailureOrder);
34680b57cec5SDimitry Andric   return false;
34690b57cec5SDimitry Andric }
34700b57cec5SDimitry Andric 
34710b57cec5SDimitry Andric bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
34720b57cec5SDimitry Andric   assert((Token.is(MIToken::kw_pre_instr_symbol) ||
34730b57cec5SDimitry Andric           Token.is(MIToken::kw_post_instr_symbol)) &&
34740b57cec5SDimitry Andric          "Invalid token for a pre- post-instruction symbol!");
34750b57cec5SDimitry Andric   lex();
34760b57cec5SDimitry Andric   if (Token.isNot(MIToken::MCSymbol))
34770b57cec5SDimitry Andric     return error("expected a symbol after 'pre-instr-symbol'");
34780b57cec5SDimitry Andric   Symbol = getOrCreateMCSymbol(Token.stringValue());
34790b57cec5SDimitry Andric   lex();
34800b57cec5SDimitry Andric   if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
34810b57cec5SDimitry Andric       Token.is(MIToken::lbrace))
34820b57cec5SDimitry Andric     return false;
34830b57cec5SDimitry Andric   if (Token.isNot(MIToken::comma))
34840b57cec5SDimitry Andric     return error("expected ',' before the next machine operand");
34850b57cec5SDimitry Andric   lex();
34860b57cec5SDimitry Andric   return false;
34870b57cec5SDimitry Andric }
34880b57cec5SDimitry Andric 
3489480093f4SDimitry Andric bool MIParser::parseHeapAllocMarker(MDNode *&Node) {
3490480093f4SDimitry Andric   assert(Token.is(MIToken::kw_heap_alloc_marker) &&
3491480093f4SDimitry Andric          "Invalid token for a heap alloc marker!");
3492480093f4SDimitry Andric   lex();
349306c3fb27SDimitry Andric   if (parseMDNode(Node))
349406c3fb27SDimitry Andric     return true;
3495480093f4SDimitry Andric   if (!Node)
3496480093f4SDimitry Andric     return error("expected a MDNode after 'heap-alloc-marker'");
3497480093f4SDimitry Andric   if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3498480093f4SDimitry Andric       Token.is(MIToken::lbrace))
3499480093f4SDimitry Andric     return false;
3500480093f4SDimitry Andric   if (Token.isNot(MIToken::comma))
3501480093f4SDimitry Andric     return error("expected ',' before the next machine operand");
3502480093f4SDimitry Andric   lex();
3503480093f4SDimitry Andric   return false;
3504480093f4SDimitry Andric }
3505480093f4SDimitry Andric 
3506bdd1243dSDimitry Andric bool MIParser::parsePCSections(MDNode *&Node) {
3507bdd1243dSDimitry Andric   assert(Token.is(MIToken::kw_pcsections) &&
3508bdd1243dSDimitry Andric          "Invalid token for a PC sections!");
3509bdd1243dSDimitry Andric   lex();
351006c3fb27SDimitry Andric   if (parseMDNode(Node))
351106c3fb27SDimitry Andric     return true;
3512bdd1243dSDimitry Andric   if (!Node)
3513bdd1243dSDimitry Andric     return error("expected a MDNode after 'pcsections'");
3514bdd1243dSDimitry Andric   if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3515bdd1243dSDimitry Andric       Token.is(MIToken::lbrace))
3516bdd1243dSDimitry Andric     return false;
3517bdd1243dSDimitry Andric   if (Token.isNot(MIToken::comma))
3518bdd1243dSDimitry Andric     return error("expected ',' before the next machine operand");
3519bdd1243dSDimitry Andric   lex();
3520bdd1243dSDimitry Andric   return false;
3521bdd1243dSDimitry Andric }
3522bdd1243dSDimitry Andric 
35230b57cec5SDimitry Andric static void initSlots2BasicBlocks(
35240b57cec5SDimitry Andric     const Function &F,
35250b57cec5SDimitry Andric     DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
35260b57cec5SDimitry Andric   ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
35270b57cec5SDimitry Andric   MST.incorporateFunction(F);
3528fcaf7f86SDimitry Andric   for (const auto &BB : F) {
35290b57cec5SDimitry Andric     if (BB.hasName())
35300b57cec5SDimitry Andric       continue;
35310b57cec5SDimitry Andric     int Slot = MST.getLocalSlot(&BB);
35320b57cec5SDimitry Andric     if (Slot == -1)
35330b57cec5SDimitry Andric       continue;
35340b57cec5SDimitry Andric     Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB));
35350b57cec5SDimitry Andric   }
35360b57cec5SDimitry Andric }
35370b57cec5SDimitry Andric 
35380b57cec5SDimitry Andric static const BasicBlock *getIRBlockFromSlot(
35390b57cec5SDimitry Andric     unsigned Slot,
35400b57cec5SDimitry Andric     const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
3541e8d8bef9SDimitry Andric   return Slots2BasicBlocks.lookup(Slot);
35420b57cec5SDimitry Andric }
35430b57cec5SDimitry Andric 
35440b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot) {
35450b57cec5SDimitry Andric   if (Slots2BasicBlocks.empty())
35460b57cec5SDimitry Andric     initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks);
35470b57cec5SDimitry Andric   return getIRBlockFromSlot(Slot, Slots2BasicBlocks);
35480b57cec5SDimitry Andric }
35490b57cec5SDimitry Andric 
35500b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) {
35510b57cec5SDimitry Andric   if (&F == &MF.getFunction())
35520b57cec5SDimitry Andric     return getIRBlock(Slot);
35530b57cec5SDimitry Andric   DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks;
35540b57cec5SDimitry Andric   initSlots2BasicBlocks(F, CustomSlots2BasicBlocks);
35550b57cec5SDimitry Andric   return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks);
35560b57cec5SDimitry Andric }
35570b57cec5SDimitry Andric 
35580b57cec5SDimitry Andric MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) {
35590b57cec5SDimitry Andric   // FIXME: Currently we can't recognize temporary or local symbols and call all
35600b57cec5SDimitry Andric   // of the appropriate forms to create them. However, this handles basic cases
35610b57cec5SDimitry Andric   // well as most of the special aspects are recognized by a prefix on their
35620b57cec5SDimitry Andric   // name, and the input names should already be unique. For test cases, keeping
35630b57cec5SDimitry Andric   // the symbol name out of the symbol table isn't terribly important.
35640b57cec5SDimitry Andric   return MF.getContext().getOrCreateSymbol(Name);
35650b57cec5SDimitry Andric }
35660b57cec5SDimitry Andric 
35670b57cec5SDimitry Andric bool MIParser::parseStringConstant(std::string &Result) {
35680b57cec5SDimitry Andric   if (Token.isNot(MIToken::StringConstant))
35690b57cec5SDimitry Andric     return error("expected string constant");
35705ffd83dbSDimitry Andric   Result = std::string(Token.stringValue());
35710b57cec5SDimitry Andric   lex();
35720b57cec5SDimitry Andric   return false;
35730b57cec5SDimitry Andric }
35740b57cec5SDimitry Andric 
35750b57cec5SDimitry Andric bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
35760b57cec5SDimitry Andric                                              StringRef Src,
35770b57cec5SDimitry Andric                                              SMDiagnostic &Error) {
35780b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots);
35790b57cec5SDimitry Andric }
35800b57cec5SDimitry Andric 
35810b57cec5SDimitry Andric bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS,
35820b57cec5SDimitry Andric                                     StringRef Src, SMDiagnostic &Error) {
35830b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseBasicBlocks();
35840b57cec5SDimitry Andric }
35850b57cec5SDimitry Andric 
35860b57cec5SDimitry Andric bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS,
35870b57cec5SDimitry Andric                              MachineBasicBlock *&MBB, StringRef Src,
35880b57cec5SDimitry Andric                              SMDiagnostic &Error) {
35890b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB);
35900b57cec5SDimitry Andric }
35910b57cec5SDimitry Andric 
35920b57cec5SDimitry Andric bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS,
35935ffd83dbSDimitry Andric                                   Register &Reg, StringRef Src,
35940b57cec5SDimitry Andric                                   SMDiagnostic &Error) {
35950b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg);
35960b57cec5SDimitry Andric }
35970b57cec5SDimitry Andric 
35980b57cec5SDimitry Andric bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS,
35995ffd83dbSDimitry Andric                                        Register &Reg, StringRef Src,
36000b57cec5SDimitry Andric                                        SMDiagnostic &Error) {
36010b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg);
36020b57cec5SDimitry Andric }
36030b57cec5SDimitry Andric 
36040b57cec5SDimitry Andric bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
36050b57cec5SDimitry Andric                                          VRegInfo *&Info, StringRef Src,
36060b57cec5SDimitry Andric                                          SMDiagnostic &Error) {
36070b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info);
36080b57cec5SDimitry Andric }
36090b57cec5SDimitry Andric 
36100b57cec5SDimitry Andric bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS,
36110b57cec5SDimitry Andric                                      int &FI, StringRef Src,
36120b57cec5SDimitry Andric                                      SMDiagnostic &Error) {
36130b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI);
36140b57cec5SDimitry Andric }
36150b57cec5SDimitry Andric 
36160b57cec5SDimitry Andric bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
36170b57cec5SDimitry Andric                        MDNode *&Node, StringRef Src, SMDiagnostic &Error) {
36180b57cec5SDimitry Andric   return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
36190b57cec5SDimitry Andric }
3620480093f4SDimitry Andric 
3621fe6060f1SDimitry Andric bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src,
3622fe6060f1SDimitry Andric                                 SMRange SrcRange, SMDiagnostic &Error) {
3623fe6060f1SDimitry Andric   return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata();
3624fe6060f1SDimitry Andric }
3625fe6060f1SDimitry Andric 
3626480093f4SDimitry Andric bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF,
3627480093f4SDimitry Andric                                 PerFunctionMIParsingState &PFS, const Value *&V,
3628480093f4SDimitry Andric                                 ErrorCallbackType ErrorCallback) {
3629480093f4SDimitry Andric   MIToken Token;
3630480093f4SDimitry Andric   Src = lexMIToken(Src, Token, [&](StringRef::iterator Loc, const Twine &Msg) {
3631480093f4SDimitry Andric     ErrorCallback(Loc, Msg);
3632480093f4SDimitry Andric   });
3633480093f4SDimitry Andric   V = nullptr;
3634480093f4SDimitry Andric 
3635480093f4SDimitry Andric   return ::parseIRValue(Token, PFS, V, ErrorCallback);
3636480093f4SDimitry Andric }
3637