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"
27fe013be4SDimitry Andric #include "llvm/CodeGen/LowLevelType.h"
28480093f4SDimitry Andric #include "llvm/CodeGen/MIRFormatter.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h"
300b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
310b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
320b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
330b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
340b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h"
350b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
360b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
370b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
38*c9157d92SDimitry Andric #include "llvm/CodeGen/PseudoSourceValueManager.h"
3981ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBank.h"
4081ad6265SDimitry Andric #include "llvm/CodeGen/RegisterBankInfo.h"
410b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
420b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
430b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.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
setTarget(const TargetSubtargetInfo & NewSubtarget)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
initNames2Regs()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
getRegisterByName(StringRef RegName,Register & Reg)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
initNames2InstrOpCodes()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
parseInstrName(StringRef InstrName,unsigned & OpCode)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
initNames2RegMasks()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
getRegMask(StringRef Identifier)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
initNames2SubRegIndices()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
getSubRegIndex(StringRef Name)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
initNames2TargetIndices()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
getTargetIndex(StringRef Name,int & Index)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
initNames2DirectTargetFlags()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
getDirectTargetFlag(StringRef Name,unsigned & Flag)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
initNames2BitmaskTargetFlags()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
getBitmaskTargetFlag(StringRef Name,unsigned & Flag)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
initNames2MMOTargetFlags()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
getMMOTargetFlag(StringRef Name,MachineMemOperand::Flags & Flag)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
initNames2RegClasses()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
initNames2RegBanks()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 *
getRegClass(StringRef Name)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
getRegBank(StringRef Name)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
PerFunctionMIParsingState(MachineFunction & MF,SourceMgr & SM,const SlotMapping & IRSlots,PerTargetMIParsingState & T)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
getVRegInfo(Register Num)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
getVRegInfoNamed(StringRef RegName)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
mapValueToSlot(const Value * V,ModuleSlotTracker & MST,DenseMap<unsigned,const Value * > & Slots2Values)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.
initSlots2Values(const Function & F,DenseMap<unsigned,const Value * > & Slots2Values)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
getIRValue(unsigned Slot)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
ParsedMachineOperand__anon0daf8f910111::ParsedMachineOperand3810b57cec5SDimitry 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);
474fe013be4SDimitry 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);
504*c9157d92SDimitry Andric bool parseBBID(std::optional<UniqueBBID> &BBID);
505*c9157d92SDimitry 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
MIParser(PerFunctionMIParsingState & PFS,SMDiagnostic & Error,StringRef Source)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
MIParser(PerFunctionMIParsingState & PFS,SMDiagnostic & Error,StringRef Source,SMRange SourceRange)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
lex(unsigned SkipChar)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
error(const Twine & Msg)5870b57cec5SDimitry Andric bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); }
5880b57cec5SDimitry Andric
error(StringRef::iterator Loc,const Twine & Msg)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
mapSMLoc(StringRef::iterator Loc)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
toString(MIToken::TokenKind TokenKind)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
expectAndConsume(MIToken::TokenKind TokenKind)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
consumeIfPresent(MIToken::TokenKind TokenKind)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.
parseSectionID(std::optional<MBBSectionID> & SID)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.
parseBBID(std::optional<UniqueBBID> & BBID)670*c9157d92SDimitry Andric bool MIParser::parseBBID(std::optional<UniqueBBID> &BBID) {
671bdd1243dSDimitry Andric assert(Token.is(MIToken::kw_bb_id));
672bdd1243dSDimitry Andric lex();
673*c9157d92SDimitry Andric unsigned BaseID = 0;
674*c9157d92SDimitry Andric unsigned CloneID = 0;
675*c9157d92SDimitry Andric if (getUnsigned(BaseID))
676*c9157d92SDimitry Andric return error("Unknown BB ID");
677*c9157d92SDimitry Andric lex();
678*c9157d92SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
679*c9157d92SDimitry Andric if (getUnsigned(CloneID))
680*c9157d92SDimitry Andric return error("Unknown Clone ID");
681*c9157d92SDimitry Andric lex();
682*c9157d92SDimitry Andric }
683*c9157d92SDimitry Andric BBID = {BaseID, CloneID};
684*c9157d92SDimitry Andric return false;
685*c9157d92SDimitry Andric }
686*c9157d92SDimitry Andric
687*c9157d92SDimitry Andric // Parse basic block call frame size.
parseCallFrameSize(unsigned & CallFrameSize)688*c9157d92SDimitry Andric bool MIParser::parseCallFrameSize(unsigned &CallFrameSize) {
689*c9157d92SDimitry Andric assert(Token.is(MIToken::kw_call_frame_size));
690*c9157d92SDimitry Andric lex();
691bdd1243dSDimitry Andric unsigned Value = 0;
692bdd1243dSDimitry Andric if (getUnsigned(Value))
693*c9157d92SDimitry Andric return error("Unknown call frame size");
694*c9157d92SDimitry Andric CallFrameSize = Value;
695bdd1243dSDimitry Andric lex();
696bdd1243dSDimitry Andric return false;
697bdd1243dSDimitry Andric }
698bdd1243dSDimitry Andric
parseBasicBlockDefinition(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)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;
715*c9157d92SDimitry Andric std::optional<UniqueBBID> BBID;
716*c9157d92SDimitry 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;
761*c9157d92SDimitry Andric case MIToken::kw_call_frame_size:
762*c9157d92SDimitry Andric if (parseCallFrameSize(CallFrameSize))
763*c9157d92SDimitry Andric return true;
764*c9157d92SDimitry 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 }
809*c9157d92SDimitry Andric MBB->setCallFrameSize(CallFrameSize);
8100b57cec5SDimitry Andric return false;
8110b57cec5SDimitry Andric }
8120b57cec5SDimitry Andric
parseBasicBlockDefinitions(DenseMap<unsigned,MachineBasicBlock * > & MBBSlots)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
parseBasicBlockLiveins(MachineBasicBlock & MBB)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
parseBasicBlockSuccessors(MachineBasicBlock & MBB)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
parseBasicBlock(MachineBasicBlock & MBB,MachineBasicBlock * & AddFalthroughFrom)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
parseBasicBlocks()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
parse(MachineInstr * & MI)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
1179*c9157d92SDimitry Andric // Don't check the operands make sense, let the verifier catch any
1180*c9157d92SDimitry Andric // improprieties.
1181*c9157d92SDimitry 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
parseStandaloneMBB(MachineBasicBlock * & MBB)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
parseStandaloneNamedRegister(Register & Reg)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
parseStandaloneVirtualRegister(VRegInfo * & Info)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
parseStandaloneRegister(Register & Reg)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
parseStandaloneStackObject(int & FI)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
parseStandaloneMDNode(MDNode * & Node)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
parseMachineMetadata()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
parseMDTuple(MDNode * & MD,bool IsDistinct)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
parseMDNodeVector(SmallVectorImpl<Metadata * > & Elts)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"
parseMetadata(Metadata * & MD)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
printImplicitRegisterFlag(const MachineOperand & MO)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
getRegisterName(const TargetRegisterInfo * TRI,Register Reg)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.
isImplicitOperandIn(const MachineOperand & ImplicitOperand,ArrayRef<ParsedMachineOperand> Operands)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
verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands,const MCInstrDesc & MCID)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
parseInstruction(unsigned & OpCode,unsigned & Flags)14570b57cec5SDimitry Andric bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) {
14580b57cec5SDimitry Andric // Allow frame and fast math flags for OPCODE
1459*c9157d92SDimitry 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) ||
1472fe013be4SDimitry Andric Token.is(MIToken::kw_nofpexcept) ||
1473*c9157d92SDimitry Andric Token.is(MIToken::kw_noconvergent) ||
1474fe013be4SDimitry Andric Token.is(MIToken::kw_unpredictable)) {
1475*c9157d92SDimitry Andric // clang-format on
14760b57cec5SDimitry Andric // Mine frame and fast math flags
14770b57cec5SDimitry Andric if (Token.is(MIToken::kw_frame_setup))
14780b57cec5SDimitry Andric Flags |= MachineInstr::FrameSetup;
14790b57cec5SDimitry Andric if (Token.is(MIToken::kw_frame_destroy))
14800b57cec5SDimitry Andric Flags |= MachineInstr::FrameDestroy;
14810b57cec5SDimitry Andric if (Token.is(MIToken::kw_nnan))
14820b57cec5SDimitry Andric Flags |= MachineInstr::FmNoNans;
14830b57cec5SDimitry Andric if (Token.is(MIToken::kw_ninf))
14840b57cec5SDimitry Andric Flags |= MachineInstr::FmNoInfs;
14850b57cec5SDimitry Andric if (Token.is(MIToken::kw_nsz))
14860b57cec5SDimitry Andric Flags |= MachineInstr::FmNsz;
14870b57cec5SDimitry Andric if (Token.is(MIToken::kw_arcp))
14880b57cec5SDimitry Andric Flags |= MachineInstr::FmArcp;
14890b57cec5SDimitry Andric if (Token.is(MIToken::kw_contract))
14900b57cec5SDimitry Andric Flags |= MachineInstr::FmContract;
14910b57cec5SDimitry Andric if (Token.is(MIToken::kw_afn))
14920b57cec5SDimitry Andric Flags |= MachineInstr::FmAfn;
14930b57cec5SDimitry Andric if (Token.is(MIToken::kw_reassoc))
14940b57cec5SDimitry Andric Flags |= MachineInstr::FmReassoc;
14950b57cec5SDimitry Andric if (Token.is(MIToken::kw_nuw))
14960b57cec5SDimitry Andric Flags |= MachineInstr::NoUWrap;
14970b57cec5SDimitry Andric if (Token.is(MIToken::kw_nsw))
14980b57cec5SDimitry Andric Flags |= MachineInstr::NoSWrap;
14990b57cec5SDimitry Andric if (Token.is(MIToken::kw_exact))
15000b57cec5SDimitry Andric Flags |= MachineInstr::IsExact;
1501480093f4SDimitry Andric if (Token.is(MIToken::kw_nofpexcept))
1502480093f4SDimitry Andric Flags |= MachineInstr::NoFPExcept;
1503fe013be4SDimitry Andric if (Token.is(MIToken::kw_unpredictable))
1504fe013be4SDimitry Andric Flags |= MachineInstr::Unpredictable;
1505*c9157d92SDimitry Andric if (Token.is(MIToken::kw_noconvergent))
1506*c9157d92SDimitry Andric Flags |= MachineInstr::NoConvergent;
15070b57cec5SDimitry Andric
15080b57cec5SDimitry Andric lex();
15090b57cec5SDimitry Andric }
15100b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
15110b57cec5SDimitry Andric return error("expected a machine instruction");
15120b57cec5SDimitry Andric StringRef InstrName = Token.stringValue();
15130b57cec5SDimitry Andric if (PFS.Target.parseInstrName(InstrName, OpCode))
15140b57cec5SDimitry Andric return error(Twine("unknown machine instruction name '") + InstrName + "'");
15150b57cec5SDimitry Andric lex();
15160b57cec5SDimitry Andric return false;
15170b57cec5SDimitry Andric }
15180b57cec5SDimitry Andric
parseNamedRegister(Register & Reg)15195ffd83dbSDimitry Andric bool MIParser::parseNamedRegister(Register &Reg) {
15200b57cec5SDimitry Andric assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token");
15210b57cec5SDimitry Andric StringRef Name = Token.stringValue();
15220b57cec5SDimitry Andric if (PFS.Target.getRegisterByName(Name, Reg))
15230b57cec5SDimitry Andric return error(Twine("unknown register name '") + Name + "'");
15240b57cec5SDimitry Andric return false;
15250b57cec5SDimitry Andric }
15260b57cec5SDimitry Andric
parseNamedVirtualRegister(VRegInfo * & Info)15270b57cec5SDimitry Andric bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) {
15280b57cec5SDimitry Andric assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token");
15290b57cec5SDimitry Andric StringRef Name = Token.stringValue();
15300b57cec5SDimitry Andric // TODO: Check that the VReg name is not the same as a physical register name.
15310b57cec5SDimitry Andric // If it is, then print a warning (when warnings are implemented).
15320b57cec5SDimitry Andric Info = &PFS.getVRegInfoNamed(Name);
15330b57cec5SDimitry Andric return false;
15340b57cec5SDimitry Andric }
15350b57cec5SDimitry Andric
parseVirtualRegister(VRegInfo * & Info)15360b57cec5SDimitry Andric bool MIParser::parseVirtualRegister(VRegInfo *&Info) {
15370b57cec5SDimitry Andric if (Token.is(MIToken::NamedVirtualRegister))
15380b57cec5SDimitry Andric return parseNamedVirtualRegister(Info);
15390b57cec5SDimitry Andric assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token");
15400b57cec5SDimitry Andric unsigned ID;
15410b57cec5SDimitry Andric if (getUnsigned(ID))
15420b57cec5SDimitry Andric return true;
15430b57cec5SDimitry Andric Info = &PFS.getVRegInfo(ID);
15440b57cec5SDimitry Andric return false;
15450b57cec5SDimitry Andric }
15460b57cec5SDimitry Andric
parseRegister(Register & Reg,VRegInfo * & Info)15475ffd83dbSDimitry Andric bool MIParser::parseRegister(Register &Reg, VRegInfo *&Info) {
15480b57cec5SDimitry Andric switch (Token.kind()) {
15490b57cec5SDimitry Andric case MIToken::underscore:
15500b57cec5SDimitry Andric Reg = 0;
15510b57cec5SDimitry Andric return false;
15520b57cec5SDimitry Andric case MIToken::NamedRegister:
15530b57cec5SDimitry Andric return parseNamedRegister(Reg);
15540b57cec5SDimitry Andric case MIToken::NamedVirtualRegister:
15550b57cec5SDimitry Andric case MIToken::VirtualRegister:
15560b57cec5SDimitry Andric if (parseVirtualRegister(Info))
15570b57cec5SDimitry Andric return true;
15580b57cec5SDimitry Andric Reg = Info->VReg;
15590b57cec5SDimitry Andric return false;
15600b57cec5SDimitry Andric // TODO: Parse other register kinds.
15610b57cec5SDimitry Andric default:
15620b57cec5SDimitry Andric llvm_unreachable("The current token should be a register");
15630b57cec5SDimitry Andric }
15640b57cec5SDimitry Andric }
15650b57cec5SDimitry Andric
parseRegisterClassOrBank(VRegInfo & RegInfo)15660b57cec5SDimitry Andric bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) {
15670b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore))
15680b57cec5SDimitry Andric return error("expected '_', register class, or register bank name");
15690b57cec5SDimitry Andric StringRef::iterator Loc = Token.location();
15700b57cec5SDimitry Andric StringRef Name = Token.stringValue();
15710b57cec5SDimitry Andric
15720b57cec5SDimitry Andric // Was it a register class?
15730b57cec5SDimitry Andric const TargetRegisterClass *RC = PFS.Target.getRegClass(Name);
15740b57cec5SDimitry Andric if (RC) {
15750b57cec5SDimitry Andric lex();
15760b57cec5SDimitry Andric
15770b57cec5SDimitry Andric switch (RegInfo.Kind) {
15780b57cec5SDimitry Andric case VRegInfo::UNKNOWN:
15790b57cec5SDimitry Andric case VRegInfo::NORMAL:
15800b57cec5SDimitry Andric RegInfo.Kind = VRegInfo::NORMAL;
15810b57cec5SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RC != RC) {
15820b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
15830b57cec5SDimitry Andric return error(Loc, Twine("conflicting register classes, previously: ") +
15840b57cec5SDimitry Andric Twine(TRI.getRegClassName(RegInfo.D.RC)));
15850b57cec5SDimitry Andric }
15860b57cec5SDimitry Andric RegInfo.D.RC = RC;
15870b57cec5SDimitry Andric RegInfo.Explicit = true;
15880b57cec5SDimitry Andric return false;
15890b57cec5SDimitry Andric
15900b57cec5SDimitry Andric case VRegInfo::GENERIC:
15910b57cec5SDimitry Andric case VRegInfo::REGBANK:
15920b57cec5SDimitry Andric return error(Loc, "register class specification on generic register");
15930b57cec5SDimitry Andric }
15940b57cec5SDimitry Andric llvm_unreachable("Unexpected register kind");
15950b57cec5SDimitry Andric }
15960b57cec5SDimitry Andric
15970b57cec5SDimitry Andric // Should be a register bank or a generic register.
15980b57cec5SDimitry Andric const RegisterBank *RegBank = nullptr;
15990b57cec5SDimitry Andric if (Name != "_") {
16000b57cec5SDimitry Andric RegBank = PFS.Target.getRegBank(Name);
16010b57cec5SDimitry Andric if (!RegBank)
16020b57cec5SDimitry Andric return error(Loc, "expected '_', register class, or register bank name");
16030b57cec5SDimitry Andric }
16040b57cec5SDimitry Andric
16050b57cec5SDimitry Andric lex();
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andric switch (RegInfo.Kind) {
16080b57cec5SDimitry Andric case VRegInfo::UNKNOWN:
16090b57cec5SDimitry Andric case VRegInfo::GENERIC:
16100b57cec5SDimitry Andric case VRegInfo::REGBANK:
16110b57cec5SDimitry Andric RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC;
16120b57cec5SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank)
16130b57cec5SDimitry Andric return error(Loc, "conflicting generic register banks");
16140b57cec5SDimitry Andric RegInfo.D.RegBank = RegBank;
16150b57cec5SDimitry Andric RegInfo.Explicit = true;
16160b57cec5SDimitry Andric return false;
16170b57cec5SDimitry Andric
16180b57cec5SDimitry Andric case VRegInfo::NORMAL:
16190b57cec5SDimitry Andric return error(Loc, "register bank specification on normal register");
16200b57cec5SDimitry Andric }
16210b57cec5SDimitry Andric llvm_unreachable("Unexpected register kind");
16220b57cec5SDimitry Andric }
16230b57cec5SDimitry Andric
parseRegisterFlag(unsigned & Flags)16240b57cec5SDimitry Andric bool MIParser::parseRegisterFlag(unsigned &Flags) {
16250b57cec5SDimitry Andric const unsigned OldFlags = Flags;
16260b57cec5SDimitry Andric switch (Token.kind()) {
16270b57cec5SDimitry Andric case MIToken::kw_implicit:
16280b57cec5SDimitry Andric Flags |= RegState::Implicit;
16290b57cec5SDimitry Andric break;
16300b57cec5SDimitry Andric case MIToken::kw_implicit_define:
16310b57cec5SDimitry Andric Flags |= RegState::ImplicitDefine;
16320b57cec5SDimitry Andric break;
16330b57cec5SDimitry Andric case MIToken::kw_def:
16340b57cec5SDimitry Andric Flags |= RegState::Define;
16350b57cec5SDimitry Andric break;
16360b57cec5SDimitry Andric case MIToken::kw_dead:
16370b57cec5SDimitry Andric Flags |= RegState::Dead;
16380b57cec5SDimitry Andric break;
16390b57cec5SDimitry Andric case MIToken::kw_killed:
16400b57cec5SDimitry Andric Flags |= RegState::Kill;
16410b57cec5SDimitry Andric break;
16420b57cec5SDimitry Andric case MIToken::kw_undef:
16430b57cec5SDimitry Andric Flags |= RegState::Undef;
16440b57cec5SDimitry Andric break;
16450b57cec5SDimitry Andric case MIToken::kw_internal:
16460b57cec5SDimitry Andric Flags |= RegState::InternalRead;
16470b57cec5SDimitry Andric break;
16480b57cec5SDimitry Andric case MIToken::kw_early_clobber:
16490b57cec5SDimitry Andric Flags |= RegState::EarlyClobber;
16500b57cec5SDimitry Andric break;
16510b57cec5SDimitry Andric case MIToken::kw_debug_use:
16520b57cec5SDimitry Andric Flags |= RegState::Debug;
16530b57cec5SDimitry Andric break;
16540b57cec5SDimitry Andric case MIToken::kw_renamable:
16550b57cec5SDimitry Andric Flags |= RegState::Renamable;
16560b57cec5SDimitry Andric break;
16570b57cec5SDimitry Andric default:
16580b57cec5SDimitry Andric llvm_unreachable("The current token should be a register flag");
16590b57cec5SDimitry Andric }
16600b57cec5SDimitry Andric if (OldFlags == Flags)
16610b57cec5SDimitry Andric // We know that the same flag is specified more than once when the flags
16620b57cec5SDimitry Andric // weren't modified.
16630b57cec5SDimitry Andric return error("duplicate '" + Token.stringValue() + "' register flag");
16640b57cec5SDimitry Andric lex();
16650b57cec5SDimitry Andric return false;
16660b57cec5SDimitry Andric }
16670b57cec5SDimitry Andric
parseSubRegisterIndex(unsigned & SubReg)16680b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndex(unsigned &SubReg) {
16690b57cec5SDimitry Andric assert(Token.is(MIToken::dot));
16700b57cec5SDimitry Andric lex();
16710b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
16720b57cec5SDimitry Andric return error("expected a subregister index after '.'");
16730b57cec5SDimitry Andric auto Name = Token.stringValue();
16740b57cec5SDimitry Andric SubReg = PFS.Target.getSubRegIndex(Name);
16750b57cec5SDimitry Andric if (!SubReg)
16760b57cec5SDimitry Andric return error(Twine("use of unknown subregister index '") + Name + "'");
16770b57cec5SDimitry Andric lex();
16780b57cec5SDimitry Andric return false;
16790b57cec5SDimitry Andric }
16800b57cec5SDimitry Andric
parseRegisterTiedDefIndex(unsigned & TiedDefIdx)16810b57cec5SDimitry Andric bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) {
16820b57cec5SDimitry Andric if (!consumeIfPresent(MIToken::kw_tied_def))
16830b57cec5SDimitry Andric return true;
16840b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
16850b57cec5SDimitry Andric return error("expected an integer literal after 'tied-def'");
16860b57cec5SDimitry Andric if (getUnsigned(TiedDefIdx))
16870b57cec5SDimitry Andric return true;
16880b57cec5SDimitry Andric lex();
16890b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
16900b57cec5SDimitry Andric return true;
16910b57cec5SDimitry Andric return false;
16920b57cec5SDimitry Andric }
16930b57cec5SDimitry Andric
assignRegisterTies(MachineInstr & MI,ArrayRef<ParsedMachineOperand> Operands)16940b57cec5SDimitry Andric bool MIParser::assignRegisterTies(MachineInstr &MI,
16950b57cec5SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) {
16960b57cec5SDimitry Andric SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs;
16970b57cec5SDimitry Andric for (unsigned I = 0, E = Operands.size(); I != E; ++I) {
16980b57cec5SDimitry Andric if (!Operands[I].TiedDefIdx)
16990b57cec5SDimitry Andric continue;
17000b57cec5SDimitry Andric // The parser ensures that this operand is a register use, so we just have
17010b57cec5SDimitry Andric // to check the tied-def operand.
170281ad6265SDimitry Andric unsigned DefIdx = *Operands[I].TiedDefIdx;
17030b57cec5SDimitry Andric if (DefIdx >= E)
17040b57cec5SDimitry Andric return error(Operands[I].Begin,
17050b57cec5SDimitry Andric Twine("use of invalid tied-def operand index '" +
17060b57cec5SDimitry Andric Twine(DefIdx) + "'; instruction has only ") +
17070b57cec5SDimitry Andric Twine(E) + " operands");
17080b57cec5SDimitry Andric const auto &DefOperand = Operands[DefIdx].Operand;
17090b57cec5SDimitry Andric if (!DefOperand.isReg() || !DefOperand.isDef())
17100b57cec5SDimitry Andric // FIXME: add note with the def operand.
17110b57cec5SDimitry Andric return error(Operands[I].Begin,
17120b57cec5SDimitry Andric Twine("use of invalid tied-def operand index '") +
17130b57cec5SDimitry Andric Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) +
17140b57cec5SDimitry Andric " isn't a defined register");
17150b57cec5SDimitry Andric // Check that the tied-def operand wasn't tied elsewhere.
17160b57cec5SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs) {
17170b57cec5SDimitry Andric if (TiedPair.first == DefIdx)
17180b57cec5SDimitry Andric return error(Operands[I].Begin,
17190b57cec5SDimitry Andric Twine("the tied-def operand #") + Twine(DefIdx) +
17200b57cec5SDimitry Andric " is already tied with another register operand");
17210b57cec5SDimitry Andric }
17220b57cec5SDimitry Andric TiedRegisterPairs.push_back(std::make_pair(DefIdx, I));
17230b57cec5SDimitry Andric }
17240b57cec5SDimitry Andric // FIXME: Verify that for non INLINEASM instructions, the def and use tied
17250b57cec5SDimitry Andric // indices must be less than tied max.
17260b57cec5SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs)
17270b57cec5SDimitry Andric MI.tieOperands(TiedPair.first, TiedPair.second);
17280b57cec5SDimitry Andric return false;
17290b57cec5SDimitry Andric }
17300b57cec5SDimitry Andric
parseRegisterOperand(MachineOperand & Dest,std::optional<unsigned> & TiedDefIdx,bool IsDef)17310b57cec5SDimitry Andric bool MIParser::parseRegisterOperand(MachineOperand &Dest,
1732bdd1243dSDimitry Andric std::optional<unsigned> &TiedDefIdx,
17330b57cec5SDimitry Andric bool IsDef) {
17340b57cec5SDimitry Andric unsigned Flags = IsDef ? RegState::Define : 0;
17350b57cec5SDimitry Andric while (Token.isRegisterFlag()) {
17360b57cec5SDimitry Andric if (parseRegisterFlag(Flags))
17370b57cec5SDimitry Andric return true;
17380b57cec5SDimitry Andric }
17390b57cec5SDimitry Andric if (!Token.isRegister())
17400b57cec5SDimitry Andric return error("expected a register after register flags");
17415ffd83dbSDimitry Andric Register Reg;
17420b57cec5SDimitry Andric VRegInfo *RegInfo;
17430b57cec5SDimitry Andric if (parseRegister(Reg, RegInfo))
17440b57cec5SDimitry Andric return true;
17450b57cec5SDimitry Andric lex();
17460b57cec5SDimitry Andric unsigned SubReg = 0;
17470b57cec5SDimitry Andric if (Token.is(MIToken::dot)) {
17480b57cec5SDimitry Andric if (parseSubRegisterIndex(SubReg))
17490b57cec5SDimitry Andric return true;
1750bdd1243dSDimitry Andric if (!Reg.isVirtual())
17510b57cec5SDimitry Andric return error("subregister index expects a virtual register");
17520b57cec5SDimitry Andric }
17530b57cec5SDimitry Andric if (Token.is(MIToken::colon)) {
1754bdd1243dSDimitry Andric if (!Reg.isVirtual())
17550b57cec5SDimitry Andric return error("register class specification expects a virtual register");
17560b57cec5SDimitry Andric lex();
17570b57cec5SDimitry Andric if (parseRegisterClassOrBank(*RegInfo))
17580b57cec5SDimitry Andric return true;
17590b57cec5SDimitry Andric }
17600b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo();
17610b57cec5SDimitry Andric if ((Flags & RegState::Define) == 0) {
17620b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) {
17630b57cec5SDimitry Andric unsigned Idx;
17640b57cec5SDimitry Andric if (!parseRegisterTiedDefIndex(Idx))
17650b57cec5SDimitry Andric TiedDefIdx = Idx;
17660b57cec5SDimitry Andric else {
17670b57cec5SDimitry Andric // Try a redundant low-level type.
17680b57cec5SDimitry Andric LLT Ty;
17690b57cec5SDimitry Andric if (parseLowLevelType(Token.location(), Ty))
17700b57cec5SDimitry Andric return error("expected tied-def or low-level type after '('");
17710b57cec5SDimitry Andric
17720b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
17730b57cec5SDimitry Andric return true;
17740b57cec5SDimitry Andric
17750b57cec5SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
17760b57cec5SDimitry Andric return error("inconsistent type for generic virtual register");
17770b57cec5SDimitry Andric
17788bcb0991SDimitry Andric MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
17790b57cec5SDimitry Andric MRI.setType(Reg, Ty);
17800b57cec5SDimitry Andric }
17810b57cec5SDimitry Andric }
17820b57cec5SDimitry Andric } else if (consumeIfPresent(MIToken::lparen)) {
17830b57cec5SDimitry Andric // Virtual registers may have a tpe with GlobalISel.
1784bdd1243dSDimitry Andric if (!Reg.isVirtual())
17850b57cec5SDimitry Andric return error("unexpected type on physical register");
17860b57cec5SDimitry Andric
17870b57cec5SDimitry Andric LLT Ty;
17880b57cec5SDimitry Andric if (parseLowLevelType(Token.location(), Ty))
17890b57cec5SDimitry Andric return true;
17900b57cec5SDimitry Andric
17910b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
17920b57cec5SDimitry Andric return true;
17930b57cec5SDimitry Andric
17940b57cec5SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty)
17950b57cec5SDimitry Andric return error("inconsistent type for generic virtual register");
17960b57cec5SDimitry Andric
17978bcb0991SDimitry Andric MRI.setRegClassOrRegBank(Reg, static_cast<RegisterBank *>(nullptr));
17980b57cec5SDimitry Andric MRI.setType(Reg, Ty);
1799bdd1243dSDimitry Andric } else if (Reg.isVirtual()) {
18000b57cec5SDimitry Andric // Generic virtual registers must have a type.
18010b57cec5SDimitry Andric // If we end up here this means the type hasn't been specified and
18020b57cec5SDimitry Andric // this is bad!
18030b57cec5SDimitry Andric if (RegInfo->Kind == VRegInfo::GENERIC ||
18040b57cec5SDimitry Andric RegInfo->Kind == VRegInfo::REGBANK)
18050b57cec5SDimitry Andric return error("generic virtual registers must have a type");
18060b57cec5SDimitry Andric }
180781ad6265SDimitry Andric
180881ad6265SDimitry Andric if (Flags & RegState::Define) {
180981ad6265SDimitry Andric if (Flags & RegState::Kill)
181081ad6265SDimitry Andric return error("cannot have a killed def operand");
181181ad6265SDimitry Andric } else {
181281ad6265SDimitry Andric if (Flags & RegState::Dead)
181381ad6265SDimitry Andric return error("cannot have a dead use operand");
181481ad6265SDimitry Andric }
181581ad6265SDimitry Andric
18160b57cec5SDimitry Andric Dest = MachineOperand::CreateReg(
18170b57cec5SDimitry Andric Reg, Flags & RegState::Define, Flags & RegState::Implicit,
18180b57cec5SDimitry Andric Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef,
18190b57cec5SDimitry Andric Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug,
18200b57cec5SDimitry Andric Flags & RegState::InternalRead, Flags & RegState::Renamable);
18210b57cec5SDimitry Andric
18220b57cec5SDimitry Andric return false;
18230b57cec5SDimitry Andric }
18240b57cec5SDimitry Andric
parseImmediateOperand(MachineOperand & Dest)18250b57cec5SDimitry Andric bool MIParser::parseImmediateOperand(MachineOperand &Dest) {
18260b57cec5SDimitry Andric assert(Token.is(MIToken::IntegerLiteral));
18270b57cec5SDimitry Andric const APSInt &Int = Token.integerValue();
1828bdd1243dSDimitry Andric if (auto SImm = Int.trySExtValue(); Int.isSigned() && SImm.has_value())
1829bdd1243dSDimitry Andric Dest = MachineOperand::CreateImm(*SImm);
1830bdd1243dSDimitry Andric else if (auto UImm = Int.tryZExtValue(); !Int.isSigned() && UImm.has_value())
1831bdd1243dSDimitry Andric Dest = MachineOperand::CreateImm(*UImm);
1832bdd1243dSDimitry Andric else
18330b57cec5SDimitry Andric return error("integer literal is too large to be an immediate operand");
18340b57cec5SDimitry Andric lex();
18350b57cec5SDimitry Andric return false;
18360b57cec5SDimitry Andric }
18370b57cec5SDimitry Andric
parseTargetImmMnemonic(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,const MIRFormatter & MF)1838480093f4SDimitry Andric bool MIParser::parseTargetImmMnemonic(const unsigned OpCode,
1839480093f4SDimitry Andric const unsigned OpIdx,
1840480093f4SDimitry Andric MachineOperand &Dest,
1841480093f4SDimitry Andric const MIRFormatter &MF) {
1842480093f4SDimitry Andric assert(Token.is(MIToken::dot));
1843480093f4SDimitry Andric auto Loc = Token.location(); // record start position
1844480093f4SDimitry Andric size_t Len = 1; // for "."
1845480093f4SDimitry Andric lex();
1846480093f4SDimitry Andric
1847480093f4SDimitry Andric // Handle the case that mnemonic starts with number.
1848480093f4SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
1849480093f4SDimitry Andric Len += Token.range().size();
1850480093f4SDimitry Andric lex();
1851480093f4SDimitry Andric }
1852480093f4SDimitry Andric
1853480093f4SDimitry Andric StringRef Src;
1854480093f4SDimitry Andric if (Token.is(MIToken::comma))
1855480093f4SDimitry Andric Src = StringRef(Loc, Len);
1856480093f4SDimitry Andric else {
1857480093f4SDimitry Andric assert(Token.is(MIToken::Identifier));
1858480093f4SDimitry Andric Src = StringRef(Loc, Len + Token.stringValue().size());
1859480093f4SDimitry Andric }
1860480093f4SDimitry Andric int64_t Val;
1861480093f4SDimitry Andric if (MF.parseImmMnemonic(OpCode, OpIdx, Src, Val,
1862480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg)
1863480093f4SDimitry Andric -> bool { return error(Loc, Msg); }))
1864480093f4SDimitry Andric return true;
1865480093f4SDimitry Andric
1866480093f4SDimitry Andric Dest = MachineOperand::CreateImm(Val);
1867480093f4SDimitry Andric if (!Token.is(MIToken::comma))
1868480093f4SDimitry Andric lex();
1869480093f4SDimitry Andric return false;
1870480093f4SDimitry Andric }
1871480093f4SDimitry Andric
parseIRConstant(StringRef::iterator Loc,StringRef StringValue,PerFunctionMIParsingState & PFS,const Constant * & C,ErrorCallbackType ErrCB)1872480093f4SDimitry Andric static bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1873480093f4SDimitry Andric PerFunctionMIParsingState &PFS, const Constant *&C,
1874480093f4SDimitry Andric ErrorCallbackType ErrCB) {
18750b57cec5SDimitry Andric auto Source = StringValue.str(); // The source has to be null terminated.
18760b57cec5SDimitry Andric SMDiagnostic Err;
1877480093f4SDimitry Andric C = parseConstantValue(Source, Err, *PFS.MF.getFunction().getParent(),
18780b57cec5SDimitry Andric &PFS.IRSlots);
18790b57cec5SDimitry Andric if (!C)
1880480093f4SDimitry Andric return ErrCB(Loc + Err.getColumnNo(), Err.getMessage());
18810b57cec5SDimitry Andric return false;
18820b57cec5SDimitry Andric }
18830b57cec5SDimitry Andric
parseIRConstant(StringRef::iterator Loc,StringRef StringValue,const Constant * & C)1884480093f4SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue,
1885480093f4SDimitry Andric const Constant *&C) {
1886480093f4SDimitry Andric return ::parseIRConstant(
1887480093f4SDimitry Andric Loc, StringValue, PFS, C,
1888480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
1889480093f4SDimitry Andric return error(Loc, Msg);
1890480093f4SDimitry Andric });
1891480093f4SDimitry Andric }
1892480093f4SDimitry Andric
parseIRConstant(StringRef::iterator Loc,const Constant * & C)18930b57cec5SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) {
18940b57cec5SDimitry Andric if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C))
18950b57cec5SDimitry Andric return true;
18960b57cec5SDimitry Andric lex();
18970b57cec5SDimitry Andric return false;
18980b57cec5SDimitry Andric }
18990b57cec5SDimitry Andric
1900bdd1243dSDimitry Andric // See LLT implementation for bit size limits.
verifyScalarSize(uint64_t Size)19010b57cec5SDimitry Andric static bool verifyScalarSize(uint64_t Size) {
19020b57cec5SDimitry Andric return Size != 0 && isUInt<16>(Size);
19030b57cec5SDimitry Andric }
19040b57cec5SDimitry Andric
verifyVectorElementCount(uint64_t NumElts)19050b57cec5SDimitry Andric static bool verifyVectorElementCount(uint64_t NumElts) {
19060b57cec5SDimitry Andric return NumElts != 0 && isUInt<16>(NumElts);
19070b57cec5SDimitry Andric }
19080b57cec5SDimitry Andric
verifyAddrSpace(uint64_t AddrSpace)19090b57cec5SDimitry Andric static bool verifyAddrSpace(uint64_t AddrSpace) {
19100b57cec5SDimitry Andric return isUInt<24>(AddrSpace);
19110b57cec5SDimitry Andric }
19120b57cec5SDimitry Andric
parseLowLevelType(StringRef::iterator Loc,LLT & Ty)19130b57cec5SDimitry Andric bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) {
19140b57cec5SDimitry Andric if (Token.range().front() == 's' || Token.range().front() == 'p') {
19150b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
19160b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
19170b57cec5SDimitry Andric return error("expected integers after 's'/'p' type character");
19180b57cec5SDimitry Andric }
19190b57cec5SDimitry Andric
19200b57cec5SDimitry Andric if (Token.range().front() == 's') {
19210b57cec5SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
19220b57cec5SDimitry Andric if (!verifyScalarSize(ScalarSize))
19230b57cec5SDimitry Andric return error("invalid size for scalar type");
19240b57cec5SDimitry Andric
19250b57cec5SDimitry Andric Ty = LLT::scalar(ScalarSize);
19260b57cec5SDimitry Andric lex();
19270b57cec5SDimitry Andric return false;
19280b57cec5SDimitry Andric } else if (Token.range().front() == 'p') {
19290b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
19300b57cec5SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
19310b57cec5SDimitry Andric if (!verifyAddrSpace(AS))
19320b57cec5SDimitry Andric return error("invalid address space number");
19330b57cec5SDimitry Andric
19340b57cec5SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
19350b57cec5SDimitry Andric lex();
19360b57cec5SDimitry Andric return false;
19370b57cec5SDimitry Andric }
19380b57cec5SDimitry Andric
19390b57cec5SDimitry Andric // Now we're looking for a vector.
19400b57cec5SDimitry Andric if (Token.isNot(MIToken::less))
1941*c9157d92SDimitry Andric return error(Loc, "expected sN, pA, <M x sN>, <M x pA>, <vscale x M x sN>, "
1942*c9157d92SDimitry Andric "or <vscale x M x pA> for GlobalISel type");
19430b57cec5SDimitry Andric lex();
19440b57cec5SDimitry Andric
1945*c9157d92SDimitry Andric bool HasVScale =
1946*c9157d92SDimitry Andric Token.is(MIToken::Identifier) && Token.stringValue() == "vscale";
1947*c9157d92SDimitry Andric if (HasVScale) {
1948*c9157d92SDimitry Andric lex();
1949*c9157d92SDimitry Andric if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
1950*c9157d92SDimitry Andric return error("expected <vscale x M x sN> or <vscale x M x pA>");
1951*c9157d92SDimitry Andric lex();
1952*c9157d92SDimitry Andric }
1953*c9157d92SDimitry Andric
1954*c9157d92SDimitry Andric auto GetError = [this, &HasVScale, Loc]() {
1955*c9157d92SDimitry Andric if (HasVScale)
1956*c9157d92SDimitry Andric return error(
1957*c9157d92SDimitry Andric Loc, "expected <vscale x M x sN> or <vscale M x pA> for vector type");
19580b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type");
1959*c9157d92SDimitry Andric };
1960*c9157d92SDimitry Andric
1961*c9157d92SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
1962*c9157d92SDimitry Andric return GetError();
19630b57cec5SDimitry Andric uint64_t NumElements = Token.integerValue().getZExtValue();
19640b57cec5SDimitry Andric if (!verifyVectorElementCount(NumElements))
19650b57cec5SDimitry Andric return error("invalid number of vector elements");
19660b57cec5SDimitry Andric
19670b57cec5SDimitry Andric lex();
19680b57cec5SDimitry Andric
19690b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x")
1970*c9157d92SDimitry Andric return GetError();
19710b57cec5SDimitry Andric lex();
19720b57cec5SDimitry Andric
19730b57cec5SDimitry Andric if (Token.range().front() != 's' && Token.range().front() != 'p')
1974*c9157d92SDimitry Andric return GetError();
1975*c9157d92SDimitry Andric
19760b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
19770b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
19780b57cec5SDimitry Andric return error("expected integers after 's'/'p' type character");
19790b57cec5SDimitry Andric
19800b57cec5SDimitry Andric if (Token.range().front() == 's') {
19810b57cec5SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue();
19820b57cec5SDimitry Andric if (!verifyScalarSize(ScalarSize))
19830b57cec5SDimitry Andric return error("invalid size for scalar type");
19840b57cec5SDimitry Andric Ty = LLT::scalar(ScalarSize);
19850b57cec5SDimitry Andric } else if (Token.range().front() == 'p') {
19860b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout();
19870b57cec5SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue();
19880b57cec5SDimitry Andric if (!verifyAddrSpace(AS))
19890b57cec5SDimitry Andric return error("invalid address space number");
19900b57cec5SDimitry Andric
19910b57cec5SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS));
19920b57cec5SDimitry Andric } else
1993*c9157d92SDimitry Andric return GetError();
19940b57cec5SDimitry Andric lex();
19950b57cec5SDimitry Andric
19960b57cec5SDimitry Andric if (Token.isNot(MIToken::greater))
1997*c9157d92SDimitry Andric return GetError();
1998*c9157d92SDimitry Andric
19990b57cec5SDimitry Andric lex();
20000b57cec5SDimitry Andric
2001*c9157d92SDimitry Andric Ty = LLT::vector(ElementCount::get(NumElements, HasVScale), Ty);
20020b57cec5SDimitry Andric return false;
20030b57cec5SDimitry Andric }
20040b57cec5SDimitry Andric
parseTypedImmediateOperand(MachineOperand & Dest)20050b57cec5SDimitry Andric bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) {
20060b57cec5SDimitry Andric assert(Token.is(MIToken::Identifier));
20070b57cec5SDimitry Andric StringRef TypeStr = Token.range();
20080b57cec5SDimitry Andric if (TypeStr.front() != 'i' && TypeStr.front() != 's' &&
20090b57cec5SDimitry Andric TypeStr.front() != 'p')
20100b57cec5SDimitry Andric return error(
20110b57cec5SDimitry Andric "a typed immediate operand should start with one of 'i', 's', or 'p'");
20120b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front();
20130b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit))
20140b57cec5SDimitry Andric return error("expected integers after 'i'/'s'/'p' type character");
20150b57cec5SDimitry Andric
20160b57cec5SDimitry Andric auto Loc = Token.location();
20170b57cec5SDimitry Andric lex();
20180b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) {
20190b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
20200b57cec5SDimitry Andric !(Token.range() == "true" || Token.range() == "false"))
20210b57cec5SDimitry Andric return error("expected an integer literal");
20220b57cec5SDimitry Andric }
20230b57cec5SDimitry Andric const Constant *C = nullptr;
20240b57cec5SDimitry Andric if (parseIRConstant(Loc, C))
20250b57cec5SDimitry Andric return true;
20260b57cec5SDimitry Andric Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C));
20270b57cec5SDimitry Andric return false;
20280b57cec5SDimitry Andric }
20290b57cec5SDimitry Andric
parseFPImmediateOperand(MachineOperand & Dest)20300b57cec5SDimitry Andric bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) {
20310b57cec5SDimitry Andric auto Loc = Token.location();
20320b57cec5SDimitry Andric lex();
20330b57cec5SDimitry Andric if (Token.isNot(MIToken::FloatingPointLiteral) &&
20340b57cec5SDimitry Andric Token.isNot(MIToken::HexLiteral))
20350b57cec5SDimitry Andric return error("expected a floating point literal");
20360b57cec5SDimitry Andric const Constant *C = nullptr;
20370b57cec5SDimitry Andric if (parseIRConstant(Loc, C))
20380b57cec5SDimitry Andric return true;
20390b57cec5SDimitry Andric Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C));
20400b57cec5SDimitry Andric return false;
20410b57cec5SDimitry Andric }
20420b57cec5SDimitry Andric
getHexUint(const MIToken & Token,APInt & Result)2043480093f4SDimitry Andric static bool getHexUint(const MIToken &Token, APInt &Result) {
2044480093f4SDimitry Andric assert(Token.is(MIToken::HexLiteral));
2045480093f4SDimitry Andric StringRef S = Token.range();
2046480093f4SDimitry Andric assert(S[0] == '0' && tolower(S[1]) == 'x');
2047480093f4SDimitry Andric // This could be a floating point literal with a special prefix.
2048480093f4SDimitry Andric if (!isxdigit(S[2]))
2049480093f4SDimitry Andric return true;
2050480093f4SDimitry Andric StringRef V = S.substr(2);
2051480093f4SDimitry Andric APInt A(V.size()*4, V, 16);
2052480093f4SDimitry Andric
2053480093f4SDimitry Andric // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make
2054480093f4SDimitry Andric // sure it isn't the case before constructing result.
2055480093f4SDimitry Andric unsigned NumBits = (A == 0) ? 32 : A.getActiveBits();
2056480093f4SDimitry Andric Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
2057480093f4SDimitry Andric return false;
2058480093f4SDimitry Andric }
2059480093f4SDimitry Andric
getUnsigned(const MIToken & Token,unsigned & Result,ErrorCallbackType ErrCB)2060480093f4SDimitry Andric static bool getUnsigned(const MIToken &Token, unsigned &Result,
2061480093f4SDimitry Andric ErrorCallbackType ErrCB) {
20620b57cec5SDimitry Andric if (Token.hasIntegerValue()) {
20630b57cec5SDimitry Andric const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1;
20640b57cec5SDimitry Andric uint64_t Val64 = Token.integerValue().getLimitedValue(Limit);
20650b57cec5SDimitry Andric if (Val64 == Limit)
2066480093f4SDimitry Andric return ErrCB(Token.location(), "expected 32-bit integer (too large)");
20670b57cec5SDimitry Andric Result = Val64;
20680b57cec5SDimitry Andric return false;
20690b57cec5SDimitry Andric }
20700b57cec5SDimitry Andric if (Token.is(MIToken::HexLiteral)) {
20710b57cec5SDimitry Andric APInt A;
2072480093f4SDimitry Andric if (getHexUint(Token, A))
20730b57cec5SDimitry Andric return true;
20740b57cec5SDimitry Andric if (A.getBitWidth() > 32)
2075480093f4SDimitry Andric return ErrCB(Token.location(), "expected 32-bit integer (too large)");
20760b57cec5SDimitry Andric Result = A.getZExtValue();
20770b57cec5SDimitry Andric return false;
20780b57cec5SDimitry Andric }
20790b57cec5SDimitry Andric return true;
20800b57cec5SDimitry Andric }
20810b57cec5SDimitry Andric
getUnsigned(unsigned & Result)2082480093f4SDimitry Andric bool MIParser::getUnsigned(unsigned &Result) {
2083480093f4SDimitry Andric return ::getUnsigned(
2084480093f4SDimitry Andric Token, Result, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2085480093f4SDimitry Andric return error(Loc, Msg);
2086480093f4SDimitry Andric });
2087480093f4SDimitry Andric }
2088480093f4SDimitry Andric
parseMBBReference(MachineBasicBlock * & MBB)20890b57cec5SDimitry Andric bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) {
20900b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlock) ||
20910b57cec5SDimitry Andric Token.is(MIToken::MachineBasicBlockLabel));
20920b57cec5SDimitry Andric unsigned Number;
20930b57cec5SDimitry Andric if (getUnsigned(Number))
20940b57cec5SDimitry Andric return true;
20950b57cec5SDimitry Andric auto MBBInfo = PFS.MBBSlots.find(Number);
20960b57cec5SDimitry Andric if (MBBInfo == PFS.MBBSlots.end())
20970b57cec5SDimitry Andric return error(Twine("use of undefined machine basic block #") +
20980b57cec5SDimitry Andric Twine(Number));
20990b57cec5SDimitry Andric MBB = MBBInfo->second;
21000b57cec5SDimitry Andric // TODO: Only parse the name if it's a MachineBasicBlockLabel. Deprecate once
21010b57cec5SDimitry Andric // we drop the <irname> from the bb.<id>.<irname> format.
21020b57cec5SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName())
21030b57cec5SDimitry Andric return error(Twine("the name of machine basic block #") + Twine(Number) +
21040b57cec5SDimitry Andric " isn't '" + Token.stringValue() + "'");
21050b57cec5SDimitry Andric return false;
21060b57cec5SDimitry Andric }
21070b57cec5SDimitry Andric
parseMBBOperand(MachineOperand & Dest)21080b57cec5SDimitry Andric bool MIParser::parseMBBOperand(MachineOperand &Dest) {
21090b57cec5SDimitry Andric MachineBasicBlock *MBB;
21100b57cec5SDimitry Andric if (parseMBBReference(MBB))
21110b57cec5SDimitry Andric return true;
21120b57cec5SDimitry Andric Dest = MachineOperand::CreateMBB(MBB);
21130b57cec5SDimitry Andric lex();
21140b57cec5SDimitry Andric return false;
21150b57cec5SDimitry Andric }
21160b57cec5SDimitry Andric
parseStackFrameIndex(int & FI)21170b57cec5SDimitry Andric bool MIParser::parseStackFrameIndex(int &FI) {
21180b57cec5SDimitry Andric assert(Token.is(MIToken::StackObject));
21190b57cec5SDimitry Andric unsigned ID;
21200b57cec5SDimitry Andric if (getUnsigned(ID))
21210b57cec5SDimitry Andric return true;
21220b57cec5SDimitry Andric auto ObjectInfo = PFS.StackObjectSlots.find(ID);
21230b57cec5SDimitry Andric if (ObjectInfo == PFS.StackObjectSlots.end())
21240b57cec5SDimitry Andric return error(Twine("use of undefined stack object '%stack.") + Twine(ID) +
21250b57cec5SDimitry Andric "'");
21260b57cec5SDimitry Andric StringRef Name;
21270b57cec5SDimitry Andric if (const auto *Alloca =
21280b57cec5SDimitry Andric MF.getFrameInfo().getObjectAllocation(ObjectInfo->second))
21290b57cec5SDimitry Andric Name = Alloca->getName();
21300b57cec5SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != Name)
21310b57cec5SDimitry Andric return error(Twine("the name of the stack object '%stack.") + Twine(ID) +
21320b57cec5SDimitry Andric "' isn't '" + Token.stringValue() + "'");
21330b57cec5SDimitry Andric lex();
21340b57cec5SDimitry Andric FI = ObjectInfo->second;
21350b57cec5SDimitry Andric return false;
21360b57cec5SDimitry Andric }
21370b57cec5SDimitry Andric
parseStackObjectOperand(MachineOperand & Dest)21380b57cec5SDimitry Andric bool MIParser::parseStackObjectOperand(MachineOperand &Dest) {
21390b57cec5SDimitry Andric int FI;
21400b57cec5SDimitry Andric if (parseStackFrameIndex(FI))
21410b57cec5SDimitry Andric return true;
21420b57cec5SDimitry Andric Dest = MachineOperand::CreateFI(FI);
21430b57cec5SDimitry Andric return false;
21440b57cec5SDimitry Andric }
21450b57cec5SDimitry Andric
parseFixedStackFrameIndex(int & FI)21460b57cec5SDimitry Andric bool MIParser::parseFixedStackFrameIndex(int &FI) {
21470b57cec5SDimitry Andric assert(Token.is(MIToken::FixedStackObject));
21480b57cec5SDimitry Andric unsigned ID;
21490b57cec5SDimitry Andric if (getUnsigned(ID))
21500b57cec5SDimitry Andric return true;
21510b57cec5SDimitry Andric auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID);
21520b57cec5SDimitry Andric if (ObjectInfo == PFS.FixedStackObjectSlots.end())
21530b57cec5SDimitry Andric return error(Twine("use of undefined fixed stack object '%fixed-stack.") +
21540b57cec5SDimitry Andric Twine(ID) + "'");
21550b57cec5SDimitry Andric lex();
21560b57cec5SDimitry Andric FI = ObjectInfo->second;
21570b57cec5SDimitry Andric return false;
21580b57cec5SDimitry Andric }
21590b57cec5SDimitry Andric
parseFixedStackObjectOperand(MachineOperand & Dest)21600b57cec5SDimitry Andric bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
21610b57cec5SDimitry Andric int FI;
21620b57cec5SDimitry Andric if (parseFixedStackFrameIndex(FI))
21630b57cec5SDimitry Andric return true;
21640b57cec5SDimitry Andric Dest = MachineOperand::CreateFI(FI);
21650b57cec5SDimitry Andric return false;
21660b57cec5SDimitry Andric }
21670b57cec5SDimitry Andric
parseGlobalValue(const MIToken & Token,PerFunctionMIParsingState & PFS,GlobalValue * & GV,ErrorCallbackType ErrCB)2168480093f4SDimitry Andric static bool parseGlobalValue(const MIToken &Token,
2169480093f4SDimitry Andric PerFunctionMIParsingState &PFS, GlobalValue *&GV,
2170480093f4SDimitry Andric ErrorCallbackType ErrCB) {
21710b57cec5SDimitry Andric switch (Token.kind()) {
21720b57cec5SDimitry Andric case MIToken::NamedGlobalValue: {
2173480093f4SDimitry Andric const Module *M = PFS.MF.getFunction().getParent();
21740b57cec5SDimitry Andric GV = M->getNamedValue(Token.stringValue());
21750b57cec5SDimitry Andric if (!GV)
2176480093f4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined global value '") +
2177480093f4SDimitry Andric Token.range() + "'");
21780b57cec5SDimitry Andric break;
21790b57cec5SDimitry Andric }
21800b57cec5SDimitry Andric case MIToken::GlobalValue: {
21810b57cec5SDimitry Andric unsigned GVIdx;
2182480093f4SDimitry Andric if (getUnsigned(Token, GVIdx, ErrCB))
21830b57cec5SDimitry Andric return true;
21840b57cec5SDimitry Andric if (GVIdx >= PFS.IRSlots.GlobalValues.size())
2185480093f4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined global value '@") +
2186480093f4SDimitry Andric Twine(GVIdx) + "'");
21870b57cec5SDimitry Andric GV = PFS.IRSlots.GlobalValues[GVIdx];
21880b57cec5SDimitry Andric break;
21890b57cec5SDimitry Andric }
21900b57cec5SDimitry Andric default:
21910b57cec5SDimitry Andric llvm_unreachable("The current token should be a global value");
21920b57cec5SDimitry Andric }
21930b57cec5SDimitry Andric return false;
21940b57cec5SDimitry Andric }
21950b57cec5SDimitry Andric
parseGlobalValue(GlobalValue * & GV)2196480093f4SDimitry Andric bool MIParser::parseGlobalValue(GlobalValue *&GV) {
2197480093f4SDimitry Andric return ::parseGlobalValue(
2198480093f4SDimitry Andric Token, PFS, GV,
2199480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
2200480093f4SDimitry Andric return error(Loc, Msg);
2201480093f4SDimitry Andric });
2202480093f4SDimitry Andric }
2203480093f4SDimitry Andric
parseGlobalAddressOperand(MachineOperand & Dest)22040b57cec5SDimitry Andric bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
22050b57cec5SDimitry Andric GlobalValue *GV = nullptr;
22060b57cec5SDimitry Andric if (parseGlobalValue(GV))
22070b57cec5SDimitry Andric return true;
22080b57cec5SDimitry Andric lex();
22090b57cec5SDimitry Andric Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
22100b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
22110b57cec5SDimitry Andric return true;
22120b57cec5SDimitry Andric return false;
22130b57cec5SDimitry Andric }
22140b57cec5SDimitry Andric
parseConstantPoolIndexOperand(MachineOperand & Dest)22150b57cec5SDimitry Andric bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) {
22160b57cec5SDimitry Andric assert(Token.is(MIToken::ConstantPoolItem));
22170b57cec5SDimitry Andric unsigned ID;
22180b57cec5SDimitry Andric if (getUnsigned(ID))
22190b57cec5SDimitry Andric return true;
22200b57cec5SDimitry Andric auto ConstantInfo = PFS.ConstantPoolSlots.find(ID);
22210b57cec5SDimitry Andric if (ConstantInfo == PFS.ConstantPoolSlots.end())
22220b57cec5SDimitry Andric return error("use of undefined constant '%const." + Twine(ID) + "'");
22230b57cec5SDimitry Andric lex();
22240b57cec5SDimitry Andric Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0);
22250b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
22260b57cec5SDimitry Andric return true;
22270b57cec5SDimitry Andric return false;
22280b57cec5SDimitry Andric }
22290b57cec5SDimitry Andric
parseJumpTableIndexOperand(MachineOperand & Dest)22300b57cec5SDimitry Andric bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) {
22310b57cec5SDimitry Andric assert(Token.is(MIToken::JumpTableIndex));
22320b57cec5SDimitry Andric unsigned ID;
22330b57cec5SDimitry Andric if (getUnsigned(ID))
22340b57cec5SDimitry Andric return true;
22350b57cec5SDimitry Andric auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID);
22360b57cec5SDimitry Andric if (JumpTableEntryInfo == PFS.JumpTableSlots.end())
22370b57cec5SDimitry Andric return error("use of undefined jump table '%jump-table." + Twine(ID) + "'");
22380b57cec5SDimitry Andric lex();
22390b57cec5SDimitry Andric Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second);
22400b57cec5SDimitry Andric return false;
22410b57cec5SDimitry Andric }
22420b57cec5SDimitry Andric
parseExternalSymbolOperand(MachineOperand & Dest)22430b57cec5SDimitry Andric bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) {
22440b57cec5SDimitry Andric assert(Token.is(MIToken::ExternalSymbol));
22450b57cec5SDimitry Andric const char *Symbol = MF.createExternalSymbolName(Token.stringValue());
22460b57cec5SDimitry Andric lex();
22470b57cec5SDimitry Andric Dest = MachineOperand::CreateES(Symbol);
22480b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
22490b57cec5SDimitry Andric return true;
22500b57cec5SDimitry Andric return false;
22510b57cec5SDimitry Andric }
22520b57cec5SDimitry Andric
parseMCSymbolOperand(MachineOperand & Dest)22530b57cec5SDimitry Andric bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) {
22540b57cec5SDimitry Andric assert(Token.is(MIToken::MCSymbol));
22550b57cec5SDimitry Andric MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue());
22560b57cec5SDimitry Andric lex();
22570b57cec5SDimitry Andric Dest = MachineOperand::CreateMCSymbol(Symbol);
22580b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
22590b57cec5SDimitry Andric return true;
22600b57cec5SDimitry Andric return false;
22610b57cec5SDimitry Andric }
22620b57cec5SDimitry Andric
parseSubRegisterIndexOperand(MachineOperand & Dest)22630b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) {
22640b57cec5SDimitry Andric assert(Token.is(MIToken::SubRegisterIndex));
22650b57cec5SDimitry Andric StringRef Name = Token.stringValue();
22660b57cec5SDimitry Andric unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue());
22670b57cec5SDimitry Andric if (SubRegIndex == 0)
22680b57cec5SDimitry Andric return error(Twine("unknown subregister index '") + Name + "'");
22690b57cec5SDimitry Andric lex();
22700b57cec5SDimitry Andric Dest = MachineOperand::CreateImm(SubRegIndex);
22710b57cec5SDimitry Andric return false;
22720b57cec5SDimitry Andric }
22730b57cec5SDimitry Andric
parseMDNode(MDNode * & Node)22740b57cec5SDimitry Andric bool MIParser::parseMDNode(MDNode *&Node) {
22750b57cec5SDimitry Andric assert(Token.is(MIToken::exclaim));
22760b57cec5SDimitry Andric
22770b57cec5SDimitry Andric auto Loc = Token.location();
22780b57cec5SDimitry Andric lex();
22790b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
22800b57cec5SDimitry Andric return error("expected metadata id after '!'");
22810b57cec5SDimitry Andric unsigned ID;
22820b57cec5SDimitry Andric if (getUnsigned(ID))
22830b57cec5SDimitry Andric return true;
22840b57cec5SDimitry Andric auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID);
2285fe6060f1SDimitry Andric if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) {
2286fe6060f1SDimitry Andric NodeInfo = PFS.MachineMetadataNodes.find(ID);
2287fe6060f1SDimitry Andric if (NodeInfo == PFS.MachineMetadataNodes.end())
22880b57cec5SDimitry Andric return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'");
2289fe6060f1SDimitry Andric }
22900b57cec5SDimitry Andric lex();
22910b57cec5SDimitry Andric Node = NodeInfo->second.get();
22920b57cec5SDimitry Andric return false;
22930b57cec5SDimitry Andric }
22940b57cec5SDimitry Andric
parseDIExpression(MDNode * & Expr)22950b57cec5SDimitry Andric bool MIParser::parseDIExpression(MDNode *&Expr) {
22960b57cec5SDimitry Andric assert(Token.is(MIToken::md_diexpr));
22970b57cec5SDimitry Andric lex();
22980b57cec5SDimitry Andric
22990b57cec5SDimitry Andric // FIXME: Share this parsing with the IL parser.
23000b57cec5SDimitry Andric SmallVector<uint64_t, 8> Elements;
23010b57cec5SDimitry Andric
23020b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
23030b57cec5SDimitry Andric return true;
23040b57cec5SDimitry Andric
23050b57cec5SDimitry Andric if (Token.isNot(MIToken::rparen)) {
23060b57cec5SDimitry Andric do {
23070b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) {
23080b57cec5SDimitry Andric if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) {
23090b57cec5SDimitry Andric lex();
23100b57cec5SDimitry Andric Elements.push_back(Op);
23110b57cec5SDimitry Andric continue;
23120b57cec5SDimitry Andric }
23130b57cec5SDimitry Andric if (unsigned Enc = dwarf::getAttributeEncoding(Token.stringValue())) {
23140b57cec5SDimitry Andric lex();
23150b57cec5SDimitry Andric Elements.push_back(Enc);
23160b57cec5SDimitry Andric continue;
23170b57cec5SDimitry Andric }
23180b57cec5SDimitry Andric return error(Twine("invalid DWARF op '") + Token.stringValue() + "'");
23190b57cec5SDimitry Andric }
23200b57cec5SDimitry Andric
23210b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
23220b57cec5SDimitry Andric Token.integerValue().isSigned())
23230b57cec5SDimitry Andric return error("expected unsigned integer");
23240b57cec5SDimitry Andric
23250b57cec5SDimitry Andric auto &U = Token.integerValue();
23260b57cec5SDimitry Andric if (U.ugt(UINT64_MAX))
23270b57cec5SDimitry Andric return error("element too large, limit is " + Twine(UINT64_MAX));
23280b57cec5SDimitry Andric Elements.push_back(U.getZExtValue());
23290b57cec5SDimitry Andric lex();
23300b57cec5SDimitry Andric
23310b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
23320b57cec5SDimitry Andric }
23330b57cec5SDimitry Andric
23340b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
23350b57cec5SDimitry Andric return true;
23360b57cec5SDimitry Andric
23370b57cec5SDimitry Andric Expr = DIExpression::get(MF.getFunction().getContext(), Elements);
23380b57cec5SDimitry Andric return false;
23390b57cec5SDimitry Andric }
23400b57cec5SDimitry Andric
parseDILocation(MDNode * & Loc)23410b57cec5SDimitry Andric bool MIParser::parseDILocation(MDNode *&Loc) {
23420b57cec5SDimitry Andric assert(Token.is(MIToken::md_dilocation));
23430b57cec5SDimitry Andric lex();
23440b57cec5SDimitry Andric
23450b57cec5SDimitry Andric bool HaveLine = false;
23460b57cec5SDimitry Andric unsigned Line = 0;
23470b57cec5SDimitry Andric unsigned Column = 0;
23480b57cec5SDimitry Andric MDNode *Scope = nullptr;
23490b57cec5SDimitry Andric MDNode *InlinedAt = nullptr;
23500b57cec5SDimitry Andric bool ImplicitCode = false;
23510b57cec5SDimitry Andric
23520b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
23530b57cec5SDimitry Andric return true;
23540b57cec5SDimitry Andric
23550b57cec5SDimitry Andric if (Token.isNot(MIToken::rparen)) {
23560b57cec5SDimitry Andric do {
23570b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) {
23580b57cec5SDimitry Andric if (Token.stringValue() == "line") {
23590b57cec5SDimitry Andric lex();
23600b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
23610b57cec5SDimitry Andric return true;
23620b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
23630b57cec5SDimitry Andric Token.integerValue().isSigned())
23640b57cec5SDimitry Andric return error("expected unsigned integer");
23650b57cec5SDimitry Andric Line = Token.integerValue().getZExtValue();
23660b57cec5SDimitry Andric HaveLine = true;
23670b57cec5SDimitry Andric lex();
23680b57cec5SDimitry Andric continue;
23690b57cec5SDimitry Andric }
23700b57cec5SDimitry Andric if (Token.stringValue() == "column") {
23710b57cec5SDimitry Andric lex();
23720b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
23730b57cec5SDimitry Andric return true;
23740b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) ||
23750b57cec5SDimitry Andric Token.integerValue().isSigned())
23760b57cec5SDimitry Andric return error("expected unsigned integer");
23770b57cec5SDimitry Andric Column = Token.integerValue().getZExtValue();
23780b57cec5SDimitry Andric lex();
23790b57cec5SDimitry Andric continue;
23800b57cec5SDimitry Andric }
23810b57cec5SDimitry Andric if (Token.stringValue() == "scope") {
23820b57cec5SDimitry Andric lex();
23830b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
23840b57cec5SDimitry Andric return true;
23850b57cec5SDimitry Andric if (parseMDNode(Scope))
23860b57cec5SDimitry Andric return error("expected metadata node");
23870b57cec5SDimitry Andric if (!isa<DIScope>(Scope))
23880b57cec5SDimitry Andric return error("expected DIScope node");
23890b57cec5SDimitry Andric continue;
23900b57cec5SDimitry Andric }
23910b57cec5SDimitry Andric if (Token.stringValue() == "inlinedAt") {
23920b57cec5SDimitry Andric lex();
23930b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
23940b57cec5SDimitry Andric return true;
23950b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) {
23960b57cec5SDimitry Andric if (parseMDNode(InlinedAt))
23970b57cec5SDimitry Andric return true;
23980b57cec5SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) {
23990b57cec5SDimitry Andric if (parseDILocation(InlinedAt))
24000b57cec5SDimitry Andric return true;
24010b57cec5SDimitry Andric } else
24020b57cec5SDimitry Andric return error("expected metadata node");
24030b57cec5SDimitry Andric if (!isa<DILocation>(InlinedAt))
24040b57cec5SDimitry Andric return error("expected DILocation node");
24050b57cec5SDimitry Andric continue;
24060b57cec5SDimitry Andric }
24070b57cec5SDimitry Andric if (Token.stringValue() == "isImplicitCode") {
24080b57cec5SDimitry Andric lex();
24090b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon))
24100b57cec5SDimitry Andric return true;
24110b57cec5SDimitry Andric if (!Token.is(MIToken::Identifier))
24120b57cec5SDimitry Andric return error("expected true/false");
24130b57cec5SDimitry Andric // As far as I can see, we don't have any existing need for parsing
24140b57cec5SDimitry Andric // true/false in MIR yet. Do it ad-hoc until there's something else
24150b57cec5SDimitry Andric // that needs it.
24160b57cec5SDimitry Andric if (Token.stringValue() == "true")
24170b57cec5SDimitry Andric ImplicitCode = true;
24180b57cec5SDimitry Andric else if (Token.stringValue() == "false")
24190b57cec5SDimitry Andric ImplicitCode = false;
24200b57cec5SDimitry Andric else
24210b57cec5SDimitry Andric return error("expected true/false");
24220b57cec5SDimitry Andric lex();
24230b57cec5SDimitry Andric continue;
24240b57cec5SDimitry Andric }
24250b57cec5SDimitry Andric }
24260b57cec5SDimitry Andric return error(Twine("invalid DILocation argument '") +
24270b57cec5SDimitry Andric Token.stringValue() + "'");
24280b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
24290b57cec5SDimitry Andric }
24300b57cec5SDimitry Andric
24310b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
24320b57cec5SDimitry Andric return true;
24330b57cec5SDimitry Andric
24340b57cec5SDimitry Andric if (!HaveLine)
24350b57cec5SDimitry Andric return error("DILocation requires line number");
24360b57cec5SDimitry Andric if (!Scope)
24370b57cec5SDimitry Andric return error("DILocation requires a scope");
24380b57cec5SDimitry Andric
24390b57cec5SDimitry Andric Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope,
24400b57cec5SDimitry Andric InlinedAt, ImplicitCode);
24410b57cec5SDimitry Andric return false;
24420b57cec5SDimitry Andric }
24430b57cec5SDimitry Andric
parseMetadataOperand(MachineOperand & Dest)24440b57cec5SDimitry Andric bool MIParser::parseMetadataOperand(MachineOperand &Dest) {
24450b57cec5SDimitry Andric MDNode *Node = nullptr;
24460b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) {
24470b57cec5SDimitry Andric if (parseMDNode(Node))
24480b57cec5SDimitry Andric return true;
24490b57cec5SDimitry Andric } else if (Token.is(MIToken::md_diexpr)) {
24500b57cec5SDimitry Andric if (parseDIExpression(Node))
24510b57cec5SDimitry Andric return true;
24520b57cec5SDimitry Andric }
24530b57cec5SDimitry Andric Dest = MachineOperand::CreateMetadata(Node);
24540b57cec5SDimitry Andric return false;
24550b57cec5SDimitry Andric }
24560b57cec5SDimitry Andric
parseCFIOffset(int & Offset)24570b57cec5SDimitry Andric bool MIParser::parseCFIOffset(int &Offset) {
24580b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
24590b57cec5SDimitry Andric return error("expected a cfi offset");
2460fe013be4SDimitry Andric if (Token.integerValue().getSignificantBits() > 32)
24610b57cec5SDimitry Andric return error("expected a 32 bit integer (the cfi offset is too large)");
24620b57cec5SDimitry Andric Offset = (int)Token.integerValue().getExtValue();
24630b57cec5SDimitry Andric lex();
24640b57cec5SDimitry Andric return false;
24650b57cec5SDimitry Andric }
24660b57cec5SDimitry Andric
parseCFIRegister(Register & Reg)24675ffd83dbSDimitry Andric bool MIParser::parseCFIRegister(Register &Reg) {
24680b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
24690b57cec5SDimitry Andric return error("expected a cfi register");
24705ffd83dbSDimitry Andric Register LLVMReg;
24710b57cec5SDimitry Andric if (parseNamedRegister(LLVMReg))
24720b57cec5SDimitry Andric return true;
24730b57cec5SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo();
24740b57cec5SDimitry Andric assert(TRI && "Expected target register info");
24750b57cec5SDimitry Andric int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true);
24760b57cec5SDimitry Andric if (DwarfReg < 0)
24770b57cec5SDimitry Andric return error("invalid DWARF register");
24780b57cec5SDimitry Andric Reg = (unsigned)DwarfReg;
24790b57cec5SDimitry Andric lex();
24800b57cec5SDimitry Andric return false;
24810b57cec5SDimitry Andric }
24820b57cec5SDimitry Andric
parseCFIAddressSpace(unsigned & AddressSpace)2483fe6060f1SDimitry Andric bool MIParser::parseCFIAddressSpace(unsigned &AddressSpace) {
2484fe6060f1SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
2485fe6060f1SDimitry Andric return error("expected a cfi address space literal");
2486fe6060f1SDimitry Andric if (Token.integerValue().isSigned())
2487fe6060f1SDimitry Andric return error("expected an unsigned integer (cfi address space)");
2488fe6060f1SDimitry Andric AddressSpace = Token.integerValue().getZExtValue();
2489fe6060f1SDimitry Andric lex();
2490fe6060f1SDimitry Andric return false;
2491fe6060f1SDimitry Andric }
2492fe6060f1SDimitry Andric
parseCFIEscapeValues(std::string & Values)24930b57cec5SDimitry Andric bool MIParser::parseCFIEscapeValues(std::string &Values) {
24940b57cec5SDimitry Andric do {
24950b57cec5SDimitry Andric if (Token.isNot(MIToken::HexLiteral))
24960b57cec5SDimitry Andric return error("expected a hexadecimal literal");
24970b57cec5SDimitry Andric unsigned Value;
24980b57cec5SDimitry Andric if (getUnsigned(Value))
24990b57cec5SDimitry Andric return true;
25000b57cec5SDimitry Andric if (Value > UINT8_MAX)
25010b57cec5SDimitry Andric return error("expected a 8-bit integer (too large)");
25020b57cec5SDimitry Andric Values.push_back(static_cast<uint8_t>(Value));
25030b57cec5SDimitry Andric lex();
25040b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma));
25050b57cec5SDimitry Andric return false;
25060b57cec5SDimitry Andric }
25070b57cec5SDimitry Andric
parseCFIOperand(MachineOperand & Dest)25080b57cec5SDimitry Andric bool MIParser::parseCFIOperand(MachineOperand &Dest) {
25090b57cec5SDimitry Andric auto Kind = Token.kind();
25100b57cec5SDimitry Andric lex();
25110b57cec5SDimitry Andric int Offset;
25125ffd83dbSDimitry Andric Register Reg;
2513fe6060f1SDimitry Andric unsigned AddressSpace;
25140b57cec5SDimitry Andric unsigned CFIIndex;
25150b57cec5SDimitry Andric switch (Kind) {
25160b57cec5SDimitry Andric case MIToken::kw_cfi_same_value:
25170b57cec5SDimitry Andric if (parseCFIRegister(Reg))
25180b57cec5SDimitry Andric return true;
25190b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg));
25200b57cec5SDimitry Andric break;
25210b57cec5SDimitry Andric case MIToken::kw_cfi_offset:
25220b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
25230b57cec5SDimitry Andric parseCFIOffset(Offset))
25240b57cec5SDimitry Andric return true;
25250b57cec5SDimitry Andric CFIIndex =
25260b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset));
25270b57cec5SDimitry Andric break;
25280b57cec5SDimitry Andric case MIToken::kw_cfi_rel_offset:
25290b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
25300b57cec5SDimitry Andric parseCFIOffset(Offset))
25310b57cec5SDimitry Andric return true;
25320b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
25330b57cec5SDimitry Andric MCCFIInstruction::createRelOffset(nullptr, Reg, Offset));
25340b57cec5SDimitry Andric break;
25350b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
25360b57cec5SDimitry Andric if (parseCFIRegister(Reg))
25370b57cec5SDimitry Andric return true;
25380b57cec5SDimitry Andric CFIIndex =
25390b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg));
25400b57cec5SDimitry Andric break;
25410b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
25420b57cec5SDimitry Andric if (parseCFIOffset(Offset))
25430b57cec5SDimitry Andric return true;
25445ffd83dbSDimitry Andric CFIIndex =
25455ffd83dbSDimitry Andric MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, Offset));
25460b57cec5SDimitry Andric break;
25470b57cec5SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
25480b57cec5SDimitry Andric if (parseCFIOffset(Offset))
25490b57cec5SDimitry Andric return true;
25500b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(
25510b57cec5SDimitry Andric MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset));
25520b57cec5SDimitry Andric break;
25530b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa:
25540b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
25550b57cec5SDimitry Andric parseCFIOffset(Offset))
25560b57cec5SDimitry Andric return true;
25570b57cec5SDimitry Andric CFIIndex =
25585ffd83dbSDimitry Andric MF.addFrameInst(MCCFIInstruction::cfiDefCfa(nullptr, Reg, Offset));
25590b57cec5SDimitry Andric break;
2560fe6060f1SDimitry Andric case MIToken::kw_cfi_llvm_def_aspace_cfa:
2561fe6060f1SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
2562fe6060f1SDimitry Andric parseCFIOffset(Offset) || expectAndConsume(MIToken::comma) ||
2563fe6060f1SDimitry Andric parseCFIAddressSpace(AddressSpace))
2564fe6060f1SDimitry Andric return true;
2565fe6060f1SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createLLVMDefAspaceCfa(
2566fe013be4SDimitry Andric nullptr, Reg, Offset, AddressSpace, SMLoc()));
2567fe6060f1SDimitry Andric break;
25680b57cec5SDimitry Andric case MIToken::kw_cfi_remember_state:
25690b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr));
25700b57cec5SDimitry Andric break;
25710b57cec5SDimitry Andric case MIToken::kw_cfi_restore:
25720b57cec5SDimitry Andric if (parseCFIRegister(Reg))
25730b57cec5SDimitry Andric return true;
25740b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg));
25750b57cec5SDimitry Andric break;
25760b57cec5SDimitry Andric case MIToken::kw_cfi_restore_state:
25770b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr));
25780b57cec5SDimitry Andric break;
25790b57cec5SDimitry Andric case MIToken::kw_cfi_undefined:
25800b57cec5SDimitry Andric if (parseCFIRegister(Reg))
25810b57cec5SDimitry Andric return true;
25820b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg));
25830b57cec5SDimitry Andric break;
25840b57cec5SDimitry Andric case MIToken::kw_cfi_register: {
25855ffd83dbSDimitry Andric Register Reg2;
25860b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) ||
25870b57cec5SDimitry Andric parseCFIRegister(Reg2))
25880b57cec5SDimitry Andric return true;
25890b57cec5SDimitry Andric
25900b57cec5SDimitry Andric CFIIndex =
25910b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2));
25920b57cec5SDimitry Andric break;
25930b57cec5SDimitry Andric }
25940b57cec5SDimitry Andric case MIToken::kw_cfi_window_save:
25950b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr));
25960b57cec5SDimitry Andric break;
25970b57cec5SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
25980b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
25990b57cec5SDimitry Andric break;
26000b57cec5SDimitry Andric case MIToken::kw_cfi_escape: {
26010b57cec5SDimitry Andric std::string Values;
26020b57cec5SDimitry Andric if (parseCFIEscapeValues(Values))
26030b57cec5SDimitry Andric return true;
26040b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values));
26050b57cec5SDimitry Andric break;
26060b57cec5SDimitry Andric }
26070b57cec5SDimitry Andric default:
26080b57cec5SDimitry Andric // TODO: Parse the other CFI operands.
26090b57cec5SDimitry Andric llvm_unreachable("The current token should be a cfi operand");
26100b57cec5SDimitry Andric }
26110b57cec5SDimitry Andric Dest = MachineOperand::CreateCFIIndex(CFIIndex);
26120b57cec5SDimitry Andric return false;
26130b57cec5SDimitry Andric }
26140b57cec5SDimitry Andric
parseIRBlock(BasicBlock * & BB,const Function & F)26150b57cec5SDimitry Andric bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) {
26160b57cec5SDimitry Andric switch (Token.kind()) {
26170b57cec5SDimitry Andric case MIToken::NamedIRBlock: {
26180b57cec5SDimitry Andric BB = dyn_cast_or_null<BasicBlock>(
26190b57cec5SDimitry Andric F.getValueSymbolTable()->lookup(Token.stringValue()));
26200b57cec5SDimitry Andric if (!BB)
26210b57cec5SDimitry Andric return error(Twine("use of undefined IR block '") + Token.range() + "'");
26220b57cec5SDimitry Andric break;
26230b57cec5SDimitry Andric }
26240b57cec5SDimitry Andric case MIToken::IRBlock: {
26250b57cec5SDimitry Andric unsigned SlotNumber = 0;
26260b57cec5SDimitry Andric if (getUnsigned(SlotNumber))
26270b57cec5SDimitry Andric return true;
26280b57cec5SDimitry Andric BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F));
26290b57cec5SDimitry Andric if (!BB)
26300b57cec5SDimitry Andric return error(Twine("use of undefined IR block '%ir-block.") +
26310b57cec5SDimitry Andric Twine(SlotNumber) + "'");
26320b57cec5SDimitry Andric break;
26330b57cec5SDimitry Andric }
26340b57cec5SDimitry Andric default:
26350b57cec5SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
26360b57cec5SDimitry Andric }
26370b57cec5SDimitry Andric return false;
26380b57cec5SDimitry Andric }
26390b57cec5SDimitry Andric
parseBlockAddressOperand(MachineOperand & Dest)26400b57cec5SDimitry Andric bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) {
26410b57cec5SDimitry Andric assert(Token.is(MIToken::kw_blockaddress));
26420b57cec5SDimitry Andric lex();
26430b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
26440b57cec5SDimitry Andric return true;
26450b57cec5SDimitry Andric if (Token.isNot(MIToken::GlobalValue) &&
26460b57cec5SDimitry Andric Token.isNot(MIToken::NamedGlobalValue))
26470b57cec5SDimitry Andric return error("expected a global value");
26480b57cec5SDimitry Andric GlobalValue *GV = nullptr;
26490b57cec5SDimitry Andric if (parseGlobalValue(GV))
26500b57cec5SDimitry Andric return true;
26510b57cec5SDimitry Andric auto *F = dyn_cast<Function>(GV);
26520b57cec5SDimitry Andric if (!F)
26530b57cec5SDimitry Andric return error("expected an IR function reference");
26540b57cec5SDimitry Andric lex();
26550b57cec5SDimitry Andric if (expectAndConsume(MIToken::comma))
26560b57cec5SDimitry Andric return true;
26570b57cec5SDimitry Andric BasicBlock *BB = nullptr;
26580b57cec5SDimitry Andric if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
26590b57cec5SDimitry Andric return error("expected an IR block reference");
26600b57cec5SDimitry Andric if (parseIRBlock(BB, *F))
26610b57cec5SDimitry Andric return true;
26620b57cec5SDimitry Andric lex();
26630b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
26640b57cec5SDimitry Andric return true;
26650b57cec5SDimitry Andric Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0);
26660b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
26670b57cec5SDimitry Andric return true;
26680b57cec5SDimitry Andric return false;
26690b57cec5SDimitry Andric }
26700b57cec5SDimitry Andric
parseIntrinsicOperand(MachineOperand & Dest)26710b57cec5SDimitry Andric bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) {
26720b57cec5SDimitry Andric assert(Token.is(MIToken::kw_intrinsic));
26730b57cec5SDimitry Andric lex();
26740b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
26750b57cec5SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
26760b57cec5SDimitry Andric
26770b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedGlobalValue))
26780b57cec5SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)");
26790b57cec5SDimitry Andric
26805ffd83dbSDimitry Andric std::string Name = std::string(Token.stringValue());
26810b57cec5SDimitry Andric lex();
26820b57cec5SDimitry Andric
26830b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
26840b57cec5SDimitry Andric return error("expected ')' to terminate intrinsic name");
26850b57cec5SDimitry Andric
26860b57cec5SDimitry Andric // Find out what intrinsic we're dealing with, first try the global namespace
26870b57cec5SDimitry Andric // and then the target's private intrinsics if that fails.
26880b57cec5SDimitry Andric const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo();
26890b57cec5SDimitry Andric Intrinsic::ID ID = Function::lookupIntrinsicID(Name);
26900b57cec5SDimitry Andric if (ID == Intrinsic::not_intrinsic && TII)
26910b57cec5SDimitry Andric ID = static_cast<Intrinsic::ID>(TII->lookupName(Name));
26920b57cec5SDimitry Andric
26930b57cec5SDimitry Andric if (ID == Intrinsic::not_intrinsic)
26940b57cec5SDimitry Andric return error("unknown intrinsic name");
26950b57cec5SDimitry Andric Dest = MachineOperand::CreateIntrinsicID(ID);
26960b57cec5SDimitry Andric
26970b57cec5SDimitry Andric return false;
26980b57cec5SDimitry Andric }
26990b57cec5SDimitry Andric
parsePredicateOperand(MachineOperand & Dest)27000b57cec5SDimitry Andric bool MIParser::parsePredicateOperand(MachineOperand &Dest) {
27010b57cec5SDimitry Andric assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred));
27020b57cec5SDimitry Andric bool IsFloat = Token.is(MIToken::kw_floatpred);
27030b57cec5SDimitry Andric lex();
27040b57cec5SDimitry Andric
27050b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
27060b57cec5SDimitry Andric return error("expected syntax intpred(whatever) or floatpred(whatever");
27070b57cec5SDimitry Andric
27080b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
27090b57cec5SDimitry Andric return error("whatever");
27100b57cec5SDimitry Andric
27110b57cec5SDimitry Andric CmpInst::Predicate Pred;
27120b57cec5SDimitry Andric if (IsFloat) {
27130b57cec5SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
27140b57cec5SDimitry Andric .Case("false", CmpInst::FCMP_FALSE)
27150b57cec5SDimitry Andric .Case("oeq", CmpInst::FCMP_OEQ)
27160b57cec5SDimitry Andric .Case("ogt", CmpInst::FCMP_OGT)
27170b57cec5SDimitry Andric .Case("oge", CmpInst::FCMP_OGE)
27180b57cec5SDimitry Andric .Case("olt", CmpInst::FCMP_OLT)
27190b57cec5SDimitry Andric .Case("ole", CmpInst::FCMP_OLE)
27200b57cec5SDimitry Andric .Case("one", CmpInst::FCMP_ONE)
27210b57cec5SDimitry Andric .Case("ord", CmpInst::FCMP_ORD)
27220b57cec5SDimitry Andric .Case("uno", CmpInst::FCMP_UNO)
27230b57cec5SDimitry Andric .Case("ueq", CmpInst::FCMP_UEQ)
27240b57cec5SDimitry Andric .Case("ugt", CmpInst::FCMP_UGT)
27250b57cec5SDimitry Andric .Case("uge", CmpInst::FCMP_UGE)
27260b57cec5SDimitry Andric .Case("ult", CmpInst::FCMP_ULT)
27270b57cec5SDimitry Andric .Case("ule", CmpInst::FCMP_ULE)
27280b57cec5SDimitry Andric .Case("une", CmpInst::FCMP_UNE)
27290b57cec5SDimitry Andric .Case("true", CmpInst::FCMP_TRUE)
27300b57cec5SDimitry Andric .Default(CmpInst::BAD_FCMP_PREDICATE);
27310b57cec5SDimitry Andric if (!CmpInst::isFPPredicate(Pred))
27320b57cec5SDimitry Andric return error("invalid floating-point predicate");
27330b57cec5SDimitry Andric } else {
27340b57cec5SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue())
27350b57cec5SDimitry Andric .Case("eq", CmpInst::ICMP_EQ)
27360b57cec5SDimitry Andric .Case("ne", CmpInst::ICMP_NE)
27370b57cec5SDimitry Andric .Case("sgt", CmpInst::ICMP_SGT)
27380b57cec5SDimitry Andric .Case("sge", CmpInst::ICMP_SGE)
27390b57cec5SDimitry Andric .Case("slt", CmpInst::ICMP_SLT)
27400b57cec5SDimitry Andric .Case("sle", CmpInst::ICMP_SLE)
27410b57cec5SDimitry Andric .Case("ugt", CmpInst::ICMP_UGT)
27420b57cec5SDimitry Andric .Case("uge", CmpInst::ICMP_UGE)
27430b57cec5SDimitry Andric .Case("ult", CmpInst::ICMP_ULT)
27440b57cec5SDimitry Andric .Case("ule", CmpInst::ICMP_ULE)
27450b57cec5SDimitry Andric .Default(CmpInst::BAD_ICMP_PREDICATE);
27460b57cec5SDimitry Andric if (!CmpInst::isIntPredicate(Pred))
27470b57cec5SDimitry Andric return error("invalid integer predicate");
27480b57cec5SDimitry Andric }
27490b57cec5SDimitry Andric
27500b57cec5SDimitry Andric lex();
27510b57cec5SDimitry Andric Dest = MachineOperand::CreatePredicate(Pred);
27520b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
27530b57cec5SDimitry Andric return error("predicate should be terminated by ')'.");
27540b57cec5SDimitry Andric
27550b57cec5SDimitry Andric return false;
27560b57cec5SDimitry Andric }
27570b57cec5SDimitry Andric
parseShuffleMaskOperand(MachineOperand & Dest)27588bcb0991SDimitry Andric bool MIParser::parseShuffleMaskOperand(MachineOperand &Dest) {
27598bcb0991SDimitry Andric assert(Token.is(MIToken::kw_shufflemask));
27608bcb0991SDimitry Andric
27618bcb0991SDimitry Andric lex();
27628bcb0991SDimitry Andric if (expectAndConsume(MIToken::lparen))
27638bcb0991SDimitry Andric return error("expected syntax shufflemask(<integer or undef>, ...)");
27648bcb0991SDimitry Andric
2765480093f4SDimitry Andric SmallVector<int, 32> ShufMask;
27668bcb0991SDimitry Andric do {
27678bcb0991SDimitry Andric if (Token.is(MIToken::kw_undef)) {
2768480093f4SDimitry Andric ShufMask.push_back(-1);
27698bcb0991SDimitry Andric } else if (Token.is(MIToken::IntegerLiteral)) {
27708bcb0991SDimitry Andric const APSInt &Int = Token.integerValue();
2771480093f4SDimitry Andric ShufMask.push_back(Int.getExtValue());
27728bcb0991SDimitry Andric } else
27738bcb0991SDimitry Andric return error("expected integer constant");
27748bcb0991SDimitry Andric
27758bcb0991SDimitry Andric lex();
27768bcb0991SDimitry Andric } while (consumeIfPresent(MIToken::comma));
27778bcb0991SDimitry Andric
27788bcb0991SDimitry Andric if (expectAndConsume(MIToken::rparen))
27798bcb0991SDimitry Andric return error("shufflemask should be terminated by ')'.");
27808bcb0991SDimitry Andric
2781480093f4SDimitry Andric ArrayRef<int> MaskAlloc = MF.allocateShuffleMask(ShufMask);
2782480093f4SDimitry Andric Dest = MachineOperand::CreateShuffleMask(MaskAlloc);
27838bcb0991SDimitry Andric return false;
27848bcb0991SDimitry Andric }
27858bcb0991SDimitry Andric
parseDbgInstrRefOperand(MachineOperand & Dest)2786bdd1243dSDimitry Andric bool MIParser::parseDbgInstrRefOperand(MachineOperand &Dest) {
2787bdd1243dSDimitry Andric assert(Token.is(MIToken::kw_dbg_instr_ref));
2788bdd1243dSDimitry Andric
2789bdd1243dSDimitry Andric lex();
2790bdd1243dSDimitry Andric if (expectAndConsume(MIToken::lparen))
2791bdd1243dSDimitry Andric return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2792bdd1243dSDimitry Andric
2793bdd1243dSDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
2794bdd1243dSDimitry Andric return error("expected unsigned integer for instruction index");
2795bdd1243dSDimitry Andric uint64_t InstrIdx = Token.integerValue().getZExtValue();
2796bdd1243dSDimitry Andric assert(InstrIdx <= std::numeric_limits<unsigned>::max() &&
2797bdd1243dSDimitry Andric "Instruction reference's instruction index is too large");
2798bdd1243dSDimitry Andric lex();
2799bdd1243dSDimitry Andric
2800bdd1243dSDimitry Andric if (expectAndConsume(MIToken::comma))
2801bdd1243dSDimitry Andric return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2802bdd1243dSDimitry Andric
2803bdd1243dSDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isNegative())
2804bdd1243dSDimitry Andric return error("expected unsigned integer for operand index");
2805bdd1243dSDimitry Andric uint64_t OpIdx = Token.integerValue().getZExtValue();
2806bdd1243dSDimitry Andric assert(OpIdx <= std::numeric_limits<unsigned>::max() &&
2807bdd1243dSDimitry Andric "Instruction reference's operand index is too large");
2808bdd1243dSDimitry Andric lex();
2809bdd1243dSDimitry Andric
2810bdd1243dSDimitry Andric if (expectAndConsume(MIToken::rparen))
2811bdd1243dSDimitry Andric return error("expected syntax dbg-instr-ref(<unsigned>, <unsigned>)");
2812bdd1243dSDimitry Andric
2813bdd1243dSDimitry Andric Dest = MachineOperand::CreateDbgInstrRef(InstrIdx, OpIdx);
2814bdd1243dSDimitry Andric return false;
2815bdd1243dSDimitry Andric }
2816bdd1243dSDimitry Andric
parseTargetIndexOperand(MachineOperand & Dest)28170b57cec5SDimitry Andric bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) {
28180b57cec5SDimitry Andric assert(Token.is(MIToken::kw_target_index));
28190b57cec5SDimitry Andric lex();
28200b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
28210b57cec5SDimitry Andric return true;
28220b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
28230b57cec5SDimitry Andric return error("expected the name of the target index");
28240b57cec5SDimitry Andric int Index = 0;
28250b57cec5SDimitry Andric if (PFS.Target.getTargetIndex(Token.stringValue(), Index))
28260b57cec5SDimitry Andric return error("use of undefined target index '" + Token.stringValue() + "'");
28270b57cec5SDimitry Andric lex();
28280b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
28290b57cec5SDimitry Andric return true;
28300b57cec5SDimitry Andric Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0);
28310b57cec5SDimitry Andric if (parseOperandsOffset(Dest))
28320b57cec5SDimitry Andric return true;
28330b57cec5SDimitry Andric return false;
28340b57cec5SDimitry Andric }
28350b57cec5SDimitry Andric
parseCustomRegisterMaskOperand(MachineOperand & Dest)28360b57cec5SDimitry Andric bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) {
28370b57cec5SDimitry Andric assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask");
28380b57cec5SDimitry Andric lex();
28390b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
28400b57cec5SDimitry Andric return true;
28410b57cec5SDimitry Andric
28420b57cec5SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
284381ad6265SDimitry Andric do {
284481ad6265SDimitry Andric if (Token.isNot(MIToken::rparen)) {
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 }
28530b57cec5SDimitry Andric
285481ad6265SDimitry Andric // TODO: Report an error if the same register is used more than once.
285581ad6265SDimitry Andric } while (consumeIfPresent(MIToken::comma));
285681ad6265SDimitry Andric
28570b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
28580b57cec5SDimitry Andric return true;
28590b57cec5SDimitry Andric Dest = MachineOperand::CreateRegMask(Mask);
28600b57cec5SDimitry Andric return false;
28610b57cec5SDimitry Andric }
28620b57cec5SDimitry Andric
parseLiveoutRegisterMaskOperand(MachineOperand & Dest)28630b57cec5SDimitry Andric bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) {
28640b57cec5SDimitry Andric assert(Token.is(MIToken::kw_liveout));
28650b57cec5SDimitry Andric uint32_t *Mask = MF.allocateRegMask();
28660b57cec5SDimitry Andric lex();
28670b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
28680b57cec5SDimitry Andric return true;
28690b57cec5SDimitry Andric while (true) {
28700b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister))
28710b57cec5SDimitry Andric return error("expected a named register");
28725ffd83dbSDimitry Andric Register Reg;
28730b57cec5SDimitry Andric if (parseNamedRegister(Reg))
28740b57cec5SDimitry Andric return true;
28750b57cec5SDimitry Andric lex();
28760b57cec5SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32);
28770b57cec5SDimitry Andric // TODO: Report an error if the same register is used more than once.
28780b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
28790b57cec5SDimitry Andric break;
28800b57cec5SDimitry Andric lex();
28810b57cec5SDimitry Andric }
28820b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
28830b57cec5SDimitry Andric return true;
28840b57cec5SDimitry Andric Dest = MachineOperand::CreateRegLiveOut(Mask);
28850b57cec5SDimitry Andric return false;
28860b57cec5SDimitry Andric }
28870b57cec5SDimitry Andric
parseMachineOperand(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,std::optional<unsigned> & TiedDefIdx)2888480093f4SDimitry Andric bool MIParser::parseMachineOperand(const unsigned OpCode, const unsigned OpIdx,
2889480093f4SDimitry Andric MachineOperand &Dest,
2890bdd1243dSDimitry Andric std::optional<unsigned> &TiedDefIdx) {
28910b57cec5SDimitry Andric switch (Token.kind()) {
28920b57cec5SDimitry Andric case MIToken::kw_implicit:
28930b57cec5SDimitry Andric case MIToken::kw_implicit_define:
28940b57cec5SDimitry Andric case MIToken::kw_def:
28950b57cec5SDimitry Andric case MIToken::kw_dead:
28960b57cec5SDimitry Andric case MIToken::kw_killed:
28970b57cec5SDimitry Andric case MIToken::kw_undef:
28980b57cec5SDimitry Andric case MIToken::kw_internal:
28990b57cec5SDimitry Andric case MIToken::kw_early_clobber:
29000b57cec5SDimitry Andric case MIToken::kw_debug_use:
29010b57cec5SDimitry Andric case MIToken::kw_renamable:
29020b57cec5SDimitry Andric case MIToken::underscore:
29030b57cec5SDimitry Andric case MIToken::NamedRegister:
29040b57cec5SDimitry Andric case MIToken::VirtualRegister:
29050b57cec5SDimitry Andric case MIToken::NamedVirtualRegister:
29060b57cec5SDimitry Andric return parseRegisterOperand(Dest, TiedDefIdx);
29070b57cec5SDimitry Andric case MIToken::IntegerLiteral:
29080b57cec5SDimitry Andric return parseImmediateOperand(Dest);
29090b57cec5SDimitry Andric case MIToken::kw_half:
29100b57cec5SDimitry Andric case MIToken::kw_float:
29110b57cec5SDimitry Andric case MIToken::kw_double:
29120b57cec5SDimitry Andric case MIToken::kw_x86_fp80:
29130b57cec5SDimitry Andric case MIToken::kw_fp128:
29140b57cec5SDimitry Andric case MIToken::kw_ppc_fp128:
29150b57cec5SDimitry Andric return parseFPImmediateOperand(Dest);
29160b57cec5SDimitry Andric case MIToken::MachineBasicBlock:
29170b57cec5SDimitry Andric return parseMBBOperand(Dest);
29180b57cec5SDimitry Andric case MIToken::StackObject:
29190b57cec5SDimitry Andric return parseStackObjectOperand(Dest);
29200b57cec5SDimitry Andric case MIToken::FixedStackObject:
29210b57cec5SDimitry Andric return parseFixedStackObjectOperand(Dest);
29220b57cec5SDimitry Andric case MIToken::GlobalValue:
29230b57cec5SDimitry Andric case MIToken::NamedGlobalValue:
29240b57cec5SDimitry Andric return parseGlobalAddressOperand(Dest);
29250b57cec5SDimitry Andric case MIToken::ConstantPoolItem:
29260b57cec5SDimitry Andric return parseConstantPoolIndexOperand(Dest);
29270b57cec5SDimitry Andric case MIToken::JumpTableIndex:
29280b57cec5SDimitry Andric return parseJumpTableIndexOperand(Dest);
29290b57cec5SDimitry Andric case MIToken::ExternalSymbol:
29300b57cec5SDimitry Andric return parseExternalSymbolOperand(Dest);
29310b57cec5SDimitry Andric case MIToken::MCSymbol:
29320b57cec5SDimitry Andric return parseMCSymbolOperand(Dest);
29330b57cec5SDimitry Andric case MIToken::SubRegisterIndex:
29340b57cec5SDimitry Andric return parseSubRegisterIndexOperand(Dest);
29350b57cec5SDimitry Andric case MIToken::md_diexpr:
29360b57cec5SDimitry Andric case MIToken::exclaim:
29370b57cec5SDimitry Andric return parseMetadataOperand(Dest);
29380b57cec5SDimitry Andric case MIToken::kw_cfi_same_value:
29390b57cec5SDimitry Andric case MIToken::kw_cfi_offset:
29400b57cec5SDimitry Andric case MIToken::kw_cfi_rel_offset:
29410b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_register:
29420b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_offset:
29430b57cec5SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset:
29440b57cec5SDimitry Andric case MIToken::kw_cfi_escape:
29450b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa:
2946fe6060f1SDimitry Andric case MIToken::kw_cfi_llvm_def_aspace_cfa:
29470b57cec5SDimitry Andric case MIToken::kw_cfi_register:
29480b57cec5SDimitry Andric case MIToken::kw_cfi_remember_state:
29490b57cec5SDimitry Andric case MIToken::kw_cfi_restore:
29500b57cec5SDimitry Andric case MIToken::kw_cfi_restore_state:
29510b57cec5SDimitry Andric case MIToken::kw_cfi_undefined:
29520b57cec5SDimitry Andric case MIToken::kw_cfi_window_save:
29530b57cec5SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state:
29540b57cec5SDimitry Andric return parseCFIOperand(Dest);
29550b57cec5SDimitry Andric case MIToken::kw_blockaddress:
29560b57cec5SDimitry Andric return parseBlockAddressOperand(Dest);
29570b57cec5SDimitry Andric case MIToken::kw_intrinsic:
29580b57cec5SDimitry Andric return parseIntrinsicOperand(Dest);
29590b57cec5SDimitry Andric case MIToken::kw_target_index:
29600b57cec5SDimitry Andric return parseTargetIndexOperand(Dest);
29610b57cec5SDimitry Andric case MIToken::kw_liveout:
29620b57cec5SDimitry Andric return parseLiveoutRegisterMaskOperand(Dest);
29630b57cec5SDimitry Andric case MIToken::kw_floatpred:
29640b57cec5SDimitry Andric case MIToken::kw_intpred:
29650b57cec5SDimitry Andric return parsePredicateOperand(Dest);
29668bcb0991SDimitry Andric case MIToken::kw_shufflemask:
29678bcb0991SDimitry Andric return parseShuffleMaskOperand(Dest);
2968bdd1243dSDimitry Andric case MIToken::kw_dbg_instr_ref:
2969bdd1243dSDimitry Andric return parseDbgInstrRefOperand(Dest);
29700b57cec5SDimitry Andric case MIToken::Error:
29710b57cec5SDimitry Andric return true;
29720b57cec5SDimitry Andric case MIToken::Identifier:
29730b57cec5SDimitry Andric if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) {
29740b57cec5SDimitry Andric Dest = MachineOperand::CreateRegMask(RegMask);
29750b57cec5SDimitry Andric lex();
29760b57cec5SDimitry Andric break;
29770b57cec5SDimitry Andric } else if (Token.stringValue() == "CustomRegMask") {
29780b57cec5SDimitry Andric return parseCustomRegisterMaskOperand(Dest);
29790b57cec5SDimitry Andric } else
29800b57cec5SDimitry Andric return parseTypedImmediateOperand(Dest);
2981480093f4SDimitry Andric case MIToken::dot: {
2982480093f4SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
2983480093f4SDimitry Andric if (const auto *Formatter = TII->getMIRFormatter()) {
2984480093f4SDimitry Andric return parseTargetImmMnemonic(OpCode, OpIdx, Dest, *Formatter);
2985480093f4SDimitry Andric }
2986bdd1243dSDimitry Andric [[fallthrough]];
2987480093f4SDimitry Andric }
29880b57cec5SDimitry Andric default:
29890b57cec5SDimitry Andric // FIXME: Parse the MCSymbol machine operand.
29900b57cec5SDimitry Andric return error("expected a machine operand");
29910b57cec5SDimitry Andric }
29920b57cec5SDimitry Andric return false;
29930b57cec5SDimitry Andric }
29940b57cec5SDimitry Andric
parseMachineOperandAndTargetFlags(const unsigned OpCode,const unsigned OpIdx,MachineOperand & Dest,std::optional<unsigned> & TiedDefIdx)29950b57cec5SDimitry Andric bool MIParser::parseMachineOperandAndTargetFlags(
2996480093f4SDimitry Andric const unsigned OpCode, const unsigned OpIdx, MachineOperand &Dest,
2997bdd1243dSDimitry Andric std::optional<unsigned> &TiedDefIdx) {
29980b57cec5SDimitry Andric unsigned TF = 0;
29990b57cec5SDimitry Andric bool HasTargetFlags = false;
30000b57cec5SDimitry Andric if (Token.is(MIToken::kw_target_flags)) {
30010b57cec5SDimitry Andric HasTargetFlags = true;
30020b57cec5SDimitry Andric lex();
30030b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
30040b57cec5SDimitry Andric return true;
30050b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
30060b57cec5SDimitry Andric return error("expected the name of the target flag");
30070b57cec5SDimitry Andric if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) {
30080b57cec5SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF))
30090b57cec5SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
30100b57cec5SDimitry Andric "'");
30110b57cec5SDimitry Andric }
30120b57cec5SDimitry Andric lex();
30130b57cec5SDimitry Andric while (Token.is(MIToken::comma)) {
30140b57cec5SDimitry Andric lex();
30150b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
30160b57cec5SDimitry Andric return error("expected the name of the target flag");
30170b57cec5SDimitry Andric unsigned BitFlag = 0;
30180b57cec5SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag))
30190b57cec5SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() +
30200b57cec5SDimitry Andric "'");
30210b57cec5SDimitry Andric // TODO: Report an error when using a duplicate bit target flag.
30220b57cec5SDimitry Andric TF |= BitFlag;
30230b57cec5SDimitry Andric lex();
30240b57cec5SDimitry Andric }
30250b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
30260b57cec5SDimitry Andric return true;
30270b57cec5SDimitry Andric }
30280b57cec5SDimitry Andric auto Loc = Token.location();
3029480093f4SDimitry Andric if (parseMachineOperand(OpCode, OpIdx, Dest, TiedDefIdx))
30300b57cec5SDimitry Andric return true;
30310b57cec5SDimitry Andric if (!HasTargetFlags)
30320b57cec5SDimitry Andric return false;
30330b57cec5SDimitry Andric if (Dest.isReg())
30340b57cec5SDimitry Andric return error(Loc, "register operands can't have target flags");
30350b57cec5SDimitry Andric Dest.setTargetFlags(TF);
30360b57cec5SDimitry Andric return false;
30370b57cec5SDimitry Andric }
30380b57cec5SDimitry Andric
parseOffset(int64_t & Offset)30390b57cec5SDimitry Andric bool MIParser::parseOffset(int64_t &Offset) {
30400b57cec5SDimitry Andric if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus))
30410b57cec5SDimitry Andric return false;
30420b57cec5SDimitry Andric StringRef Sign = Token.range();
30430b57cec5SDimitry Andric bool IsNegative = Token.is(MIToken::minus);
30440b57cec5SDimitry Andric lex();
30450b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral))
30460b57cec5SDimitry Andric return error("expected an integer literal after '" + Sign + "'");
3047fe013be4SDimitry Andric if (Token.integerValue().getSignificantBits() > 64)
30480b57cec5SDimitry Andric return error("expected 64-bit integer (too large)");
30490b57cec5SDimitry Andric Offset = Token.integerValue().getExtValue();
30500b57cec5SDimitry Andric if (IsNegative)
30510b57cec5SDimitry Andric Offset = -Offset;
30520b57cec5SDimitry Andric lex();
30530b57cec5SDimitry Andric return false;
30540b57cec5SDimitry Andric }
30550b57cec5SDimitry Andric
parseIRBlockAddressTaken(BasicBlock * & BB)3056bdd1243dSDimitry Andric bool MIParser::parseIRBlockAddressTaken(BasicBlock *&BB) {
3057bdd1243dSDimitry Andric assert(Token.is(MIToken::kw_ir_block_address_taken));
3058bdd1243dSDimitry Andric lex();
3059bdd1243dSDimitry Andric if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock))
3060bdd1243dSDimitry Andric return error("expected basic block after 'ir_block_address_taken'");
3061bdd1243dSDimitry Andric
3062bdd1243dSDimitry Andric if (parseIRBlock(BB, MF.getFunction()))
3063bdd1243dSDimitry Andric return true;
3064bdd1243dSDimitry Andric
3065bdd1243dSDimitry Andric lex();
3066bdd1243dSDimitry Andric return false;
3067bdd1243dSDimitry Andric }
3068bdd1243dSDimitry Andric
parseAlignment(uint64_t & Alignment)3069349cc55cSDimitry Andric bool MIParser::parseAlignment(uint64_t &Alignment) {
3070e8d8bef9SDimitry Andric assert(Token.is(MIToken::kw_align) || Token.is(MIToken::kw_basealign));
30710b57cec5SDimitry Andric lex();
30720b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
30730b57cec5SDimitry Andric return error("expected an integer literal after 'align'");
3074349cc55cSDimitry Andric if (getUint64(Alignment))
30750b57cec5SDimitry Andric return true;
30760b57cec5SDimitry Andric lex();
30770b57cec5SDimitry Andric
3078349cc55cSDimitry Andric if (!isPowerOf2_64(Alignment))
30790b57cec5SDimitry Andric return error("expected a power-of-2 literal after 'align'");
30800b57cec5SDimitry Andric
30810b57cec5SDimitry Andric return false;
30820b57cec5SDimitry Andric }
30830b57cec5SDimitry Andric
parseAddrspace(unsigned & Addrspace)30840b57cec5SDimitry Andric bool MIParser::parseAddrspace(unsigned &Addrspace) {
30850b57cec5SDimitry Andric assert(Token.is(MIToken::kw_addrspace));
30860b57cec5SDimitry Andric lex();
30870b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned())
30880b57cec5SDimitry Andric return error("expected an integer literal after 'addrspace'");
30890b57cec5SDimitry Andric if (getUnsigned(Addrspace))
30900b57cec5SDimitry Andric return true;
30910b57cec5SDimitry Andric lex();
30920b57cec5SDimitry Andric return false;
30930b57cec5SDimitry Andric }
30940b57cec5SDimitry Andric
parseOperandsOffset(MachineOperand & Op)30950b57cec5SDimitry Andric bool MIParser::parseOperandsOffset(MachineOperand &Op) {
30960b57cec5SDimitry Andric int64_t Offset = 0;
30970b57cec5SDimitry Andric if (parseOffset(Offset))
30980b57cec5SDimitry Andric return true;
30990b57cec5SDimitry Andric Op.setOffset(Offset);
31000b57cec5SDimitry Andric return false;
31010b57cec5SDimitry Andric }
31020b57cec5SDimitry Andric
parseIRValue(const MIToken & Token,PerFunctionMIParsingState & PFS,const Value * & V,ErrorCallbackType ErrCB)3103480093f4SDimitry Andric static bool parseIRValue(const MIToken &Token, PerFunctionMIParsingState &PFS,
3104480093f4SDimitry Andric const Value *&V, ErrorCallbackType ErrCB) {
31050b57cec5SDimitry Andric switch (Token.kind()) {
31060b57cec5SDimitry Andric case MIToken::NamedIRValue: {
3107480093f4SDimitry Andric V = PFS.MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue());
31080b57cec5SDimitry Andric break;
31090b57cec5SDimitry Andric }
31100b57cec5SDimitry Andric case MIToken::IRValue: {
31110b57cec5SDimitry Andric unsigned SlotNumber = 0;
3112480093f4SDimitry Andric if (getUnsigned(Token, SlotNumber, ErrCB))
31130b57cec5SDimitry Andric return true;
3114480093f4SDimitry Andric V = PFS.getIRValue(SlotNumber);
31150b57cec5SDimitry Andric break;
31160b57cec5SDimitry Andric }
31170b57cec5SDimitry Andric case MIToken::NamedGlobalValue:
31180b57cec5SDimitry Andric case MIToken::GlobalValue: {
31190b57cec5SDimitry Andric GlobalValue *GV = nullptr;
3120480093f4SDimitry Andric if (parseGlobalValue(Token, PFS, GV, ErrCB))
31210b57cec5SDimitry Andric return true;
31220b57cec5SDimitry Andric V = GV;
31230b57cec5SDimitry Andric break;
31240b57cec5SDimitry Andric }
31250b57cec5SDimitry Andric case MIToken::QuotedIRValue: {
31260b57cec5SDimitry Andric const Constant *C = nullptr;
3127480093f4SDimitry Andric if (parseIRConstant(Token.location(), Token.stringValue(), PFS, C, ErrCB))
31280b57cec5SDimitry Andric return true;
31290b57cec5SDimitry Andric V = C;
31300b57cec5SDimitry Andric break;
31310b57cec5SDimitry Andric }
3132fe6060f1SDimitry Andric case MIToken::kw_unknown_address:
3133fe6060f1SDimitry Andric V = nullptr;
3134fe6060f1SDimitry Andric return false;
31350b57cec5SDimitry Andric default:
31360b57cec5SDimitry Andric llvm_unreachable("The current token should be an IR block reference");
31370b57cec5SDimitry Andric }
31380b57cec5SDimitry Andric if (!V)
3139480093f4SDimitry Andric return ErrCB(Token.location(), Twine("use of undefined IR value '") + Token.range() + "'");
31400b57cec5SDimitry Andric return false;
31410b57cec5SDimitry Andric }
31420b57cec5SDimitry Andric
parseIRValue(const Value * & V)3143480093f4SDimitry Andric bool MIParser::parseIRValue(const Value *&V) {
3144480093f4SDimitry Andric return ::parseIRValue(
3145480093f4SDimitry Andric Token, PFS, V, [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
3146480093f4SDimitry Andric return error(Loc, Msg);
3147480093f4SDimitry Andric });
3148480093f4SDimitry Andric }
3149480093f4SDimitry Andric
getUint64(uint64_t & Result)31500b57cec5SDimitry Andric bool MIParser::getUint64(uint64_t &Result) {
31510b57cec5SDimitry Andric if (Token.hasIntegerValue()) {
31520b57cec5SDimitry Andric if (Token.integerValue().getActiveBits() > 64)
31530b57cec5SDimitry Andric return error("expected 64-bit integer (too large)");
31540b57cec5SDimitry Andric Result = Token.integerValue().getZExtValue();
31550b57cec5SDimitry Andric return false;
31560b57cec5SDimitry Andric }
31570b57cec5SDimitry Andric if (Token.is(MIToken::HexLiteral)) {
31580b57cec5SDimitry Andric APInt A;
31590b57cec5SDimitry Andric if (getHexUint(A))
31600b57cec5SDimitry Andric return true;
31610b57cec5SDimitry Andric if (A.getBitWidth() > 64)
31620b57cec5SDimitry Andric return error("expected 64-bit integer (too large)");
31630b57cec5SDimitry Andric Result = A.getZExtValue();
31640b57cec5SDimitry Andric return false;
31650b57cec5SDimitry Andric }
31660b57cec5SDimitry Andric return true;
31670b57cec5SDimitry Andric }
31680b57cec5SDimitry Andric
getHexUint(APInt & Result)31690b57cec5SDimitry Andric bool MIParser::getHexUint(APInt &Result) {
3170480093f4SDimitry Andric return ::getHexUint(Token, Result);
31710b57cec5SDimitry Andric }
31720b57cec5SDimitry Andric
parseMemoryOperandFlag(MachineMemOperand::Flags & Flags)31730b57cec5SDimitry Andric bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) {
31740b57cec5SDimitry Andric const auto OldFlags = Flags;
31750b57cec5SDimitry Andric switch (Token.kind()) {
31760b57cec5SDimitry Andric case MIToken::kw_volatile:
31770b57cec5SDimitry Andric Flags |= MachineMemOperand::MOVolatile;
31780b57cec5SDimitry Andric break;
31790b57cec5SDimitry Andric case MIToken::kw_non_temporal:
31800b57cec5SDimitry Andric Flags |= MachineMemOperand::MONonTemporal;
31810b57cec5SDimitry Andric break;
31820b57cec5SDimitry Andric case MIToken::kw_dereferenceable:
31830b57cec5SDimitry Andric Flags |= MachineMemOperand::MODereferenceable;
31840b57cec5SDimitry Andric break;
31850b57cec5SDimitry Andric case MIToken::kw_invariant:
31860b57cec5SDimitry Andric Flags |= MachineMemOperand::MOInvariant;
31870b57cec5SDimitry Andric break;
31880b57cec5SDimitry Andric case MIToken::StringConstant: {
31890b57cec5SDimitry Andric MachineMemOperand::Flags TF;
31900b57cec5SDimitry Andric if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF))
31910b57cec5SDimitry Andric return error("use of undefined target MMO flag '" + Token.stringValue() +
31920b57cec5SDimitry Andric "'");
31930b57cec5SDimitry Andric Flags |= TF;
31940b57cec5SDimitry Andric break;
31950b57cec5SDimitry Andric }
31960b57cec5SDimitry Andric default:
31970b57cec5SDimitry Andric llvm_unreachable("The current token should be a memory operand flag");
31980b57cec5SDimitry Andric }
31990b57cec5SDimitry Andric if (OldFlags == Flags)
32000b57cec5SDimitry Andric // We know that the same flag is specified more than once when the flags
32010b57cec5SDimitry Andric // weren't modified.
32020b57cec5SDimitry Andric return error("duplicate '" + Token.stringValue() + "' memory operand flag");
32030b57cec5SDimitry Andric lex();
32040b57cec5SDimitry Andric return false;
32050b57cec5SDimitry Andric }
32060b57cec5SDimitry Andric
parseMemoryPseudoSourceValue(const PseudoSourceValue * & PSV)32070b57cec5SDimitry Andric bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) {
32080b57cec5SDimitry Andric switch (Token.kind()) {
32090b57cec5SDimitry Andric case MIToken::kw_stack:
32100b57cec5SDimitry Andric PSV = MF.getPSVManager().getStack();
32110b57cec5SDimitry Andric break;
32120b57cec5SDimitry Andric case MIToken::kw_got:
32130b57cec5SDimitry Andric PSV = MF.getPSVManager().getGOT();
32140b57cec5SDimitry Andric break;
32150b57cec5SDimitry Andric case MIToken::kw_jump_table:
32160b57cec5SDimitry Andric PSV = MF.getPSVManager().getJumpTable();
32170b57cec5SDimitry Andric break;
32180b57cec5SDimitry Andric case MIToken::kw_constant_pool:
32190b57cec5SDimitry Andric PSV = MF.getPSVManager().getConstantPool();
32200b57cec5SDimitry Andric break;
32210b57cec5SDimitry Andric case MIToken::FixedStackObject: {
32220b57cec5SDimitry Andric int FI;
32230b57cec5SDimitry Andric if (parseFixedStackFrameIndex(FI))
32240b57cec5SDimitry Andric return true;
32250b57cec5SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
32260b57cec5SDimitry Andric // The token was already consumed, so use return here instead of break.
32270b57cec5SDimitry Andric return false;
32280b57cec5SDimitry Andric }
32290b57cec5SDimitry Andric case MIToken::StackObject: {
32300b57cec5SDimitry Andric int FI;
32310b57cec5SDimitry Andric if (parseStackFrameIndex(FI))
32320b57cec5SDimitry Andric return true;
32330b57cec5SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI);
32340b57cec5SDimitry Andric // The token was already consumed, so use return here instead of break.
32350b57cec5SDimitry Andric return false;
32360b57cec5SDimitry Andric }
32370b57cec5SDimitry Andric case MIToken::kw_call_entry:
32380b57cec5SDimitry Andric lex();
32390b57cec5SDimitry Andric switch (Token.kind()) {
32400b57cec5SDimitry Andric case MIToken::GlobalValue:
32410b57cec5SDimitry Andric case MIToken::NamedGlobalValue: {
32420b57cec5SDimitry Andric GlobalValue *GV = nullptr;
32430b57cec5SDimitry Andric if (parseGlobalValue(GV))
32440b57cec5SDimitry Andric return true;
32450b57cec5SDimitry Andric PSV = MF.getPSVManager().getGlobalValueCallEntry(GV);
32460b57cec5SDimitry Andric break;
32470b57cec5SDimitry Andric }
32480b57cec5SDimitry Andric case MIToken::ExternalSymbol:
32490b57cec5SDimitry Andric PSV = MF.getPSVManager().getExternalSymbolCallEntry(
32500b57cec5SDimitry Andric MF.createExternalSymbolName(Token.stringValue()));
32510b57cec5SDimitry Andric break;
32520b57cec5SDimitry Andric default:
32530b57cec5SDimitry Andric return error(
32540b57cec5SDimitry Andric "expected a global value or an external symbol after 'call-entry'");
32550b57cec5SDimitry Andric }
32560b57cec5SDimitry Andric break;
3257480093f4SDimitry Andric case MIToken::kw_custom: {
3258480093f4SDimitry Andric lex();
3259480093f4SDimitry Andric const auto *TII = MF.getSubtarget().getInstrInfo();
3260480093f4SDimitry Andric if (const auto *Formatter = TII->getMIRFormatter()) {
3261480093f4SDimitry Andric if (Formatter->parseCustomPseudoSourceValue(
3262480093f4SDimitry Andric Token.stringValue(), MF, PFS, PSV,
3263480093f4SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) -> bool {
3264480093f4SDimitry Andric return error(Loc, Msg);
3265480093f4SDimitry Andric }))
3266480093f4SDimitry Andric return true;
3267480093f4SDimitry Andric } else
3268480093f4SDimitry Andric return error("unable to parse target custom pseudo source value");
3269480093f4SDimitry Andric break;
3270480093f4SDimitry Andric }
32710b57cec5SDimitry Andric default:
32720b57cec5SDimitry Andric llvm_unreachable("The current token should be pseudo source value");
32730b57cec5SDimitry Andric }
32740b57cec5SDimitry Andric lex();
32750b57cec5SDimitry Andric return false;
32760b57cec5SDimitry Andric }
32770b57cec5SDimitry Andric
parseMachinePointerInfo(MachinePointerInfo & Dest)32780b57cec5SDimitry Andric bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) {
32790b57cec5SDimitry Andric if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) ||
32800b57cec5SDimitry Andric Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) ||
32810b57cec5SDimitry Andric Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) ||
3282480093f4SDimitry Andric Token.is(MIToken::kw_call_entry) || Token.is(MIToken::kw_custom)) {
32830b57cec5SDimitry Andric const PseudoSourceValue *PSV = nullptr;
32840b57cec5SDimitry Andric if (parseMemoryPseudoSourceValue(PSV))
32850b57cec5SDimitry Andric return true;
32860b57cec5SDimitry Andric int64_t Offset = 0;
32870b57cec5SDimitry Andric if (parseOffset(Offset))
32880b57cec5SDimitry Andric return true;
32890b57cec5SDimitry Andric Dest = MachinePointerInfo(PSV, Offset);
32900b57cec5SDimitry Andric return false;
32910b57cec5SDimitry Andric }
32920b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) &&
32930b57cec5SDimitry Andric Token.isNot(MIToken::GlobalValue) &&
32940b57cec5SDimitry Andric Token.isNot(MIToken::NamedGlobalValue) &&
3295fe6060f1SDimitry Andric Token.isNot(MIToken::QuotedIRValue) &&
3296fe6060f1SDimitry Andric Token.isNot(MIToken::kw_unknown_address))
32970b57cec5SDimitry Andric return error("expected an IR value reference");
32980b57cec5SDimitry Andric const Value *V = nullptr;
32990b57cec5SDimitry Andric if (parseIRValue(V))
33000b57cec5SDimitry Andric return true;
3301fe6060f1SDimitry Andric if (V && !V->getType()->isPointerTy())
33020b57cec5SDimitry Andric return error("expected a pointer IR value");
33030b57cec5SDimitry Andric lex();
33040b57cec5SDimitry Andric int64_t Offset = 0;
33050b57cec5SDimitry Andric if (parseOffset(Offset))
33060b57cec5SDimitry Andric return true;
33070b57cec5SDimitry Andric Dest = MachinePointerInfo(V, Offset);
33080b57cec5SDimitry Andric return false;
33090b57cec5SDimitry Andric }
33100b57cec5SDimitry Andric
parseOptionalScope(LLVMContext & Context,SyncScope::ID & SSID)33110b57cec5SDimitry Andric bool MIParser::parseOptionalScope(LLVMContext &Context,
33120b57cec5SDimitry Andric SyncScope::ID &SSID) {
33130b57cec5SDimitry Andric SSID = SyncScope::System;
33140b57cec5SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") {
33150b57cec5SDimitry Andric lex();
33160b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
33170b57cec5SDimitry Andric return error("expected '(' in syncscope");
33180b57cec5SDimitry Andric
33190b57cec5SDimitry Andric std::string SSN;
33200b57cec5SDimitry Andric if (parseStringConstant(SSN))
33210b57cec5SDimitry Andric return true;
33220b57cec5SDimitry Andric
33230b57cec5SDimitry Andric SSID = Context.getOrInsertSyncScopeID(SSN);
33240b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
33250b57cec5SDimitry Andric return error("expected ')' in syncscope");
33260b57cec5SDimitry Andric }
33270b57cec5SDimitry Andric
33280b57cec5SDimitry Andric return false;
33290b57cec5SDimitry Andric }
33300b57cec5SDimitry Andric
parseOptionalAtomicOrdering(AtomicOrdering & Order)33310b57cec5SDimitry Andric bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) {
33320b57cec5SDimitry Andric Order = AtomicOrdering::NotAtomic;
33330b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier))
33340b57cec5SDimitry Andric return false;
33350b57cec5SDimitry Andric
33360b57cec5SDimitry Andric Order = StringSwitch<AtomicOrdering>(Token.stringValue())
33370b57cec5SDimitry Andric .Case("unordered", AtomicOrdering::Unordered)
33380b57cec5SDimitry Andric .Case("monotonic", AtomicOrdering::Monotonic)
33390b57cec5SDimitry Andric .Case("acquire", AtomicOrdering::Acquire)
33400b57cec5SDimitry Andric .Case("release", AtomicOrdering::Release)
33410b57cec5SDimitry Andric .Case("acq_rel", AtomicOrdering::AcquireRelease)
33420b57cec5SDimitry Andric .Case("seq_cst", AtomicOrdering::SequentiallyConsistent)
33430b57cec5SDimitry Andric .Default(AtomicOrdering::NotAtomic);
33440b57cec5SDimitry Andric
33450b57cec5SDimitry Andric if (Order != AtomicOrdering::NotAtomic) {
33460b57cec5SDimitry Andric lex();
33470b57cec5SDimitry Andric return false;
33480b57cec5SDimitry Andric }
33490b57cec5SDimitry Andric
33500b57cec5SDimitry Andric return error("expected an atomic scope, ordering or a size specification");
33510b57cec5SDimitry Andric }
33520b57cec5SDimitry Andric
parseMachineMemoryOperand(MachineMemOperand * & Dest)33530b57cec5SDimitry Andric bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) {
33540b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen))
33550b57cec5SDimitry Andric return true;
33560b57cec5SDimitry Andric MachineMemOperand::Flags Flags = MachineMemOperand::MONone;
33570b57cec5SDimitry Andric while (Token.isMemoryOperandFlag()) {
33580b57cec5SDimitry Andric if (parseMemoryOperandFlag(Flags))
33590b57cec5SDimitry Andric return true;
33600b57cec5SDimitry Andric }
33610b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) ||
33620b57cec5SDimitry Andric (Token.stringValue() != "load" && Token.stringValue() != "store"))
33630b57cec5SDimitry Andric return error("expected 'load' or 'store' memory operation");
33640b57cec5SDimitry Andric if (Token.stringValue() == "load")
33650b57cec5SDimitry Andric Flags |= MachineMemOperand::MOLoad;
33660b57cec5SDimitry Andric else
33670b57cec5SDimitry Andric Flags |= MachineMemOperand::MOStore;
33680b57cec5SDimitry Andric lex();
33690b57cec5SDimitry Andric
33700b57cec5SDimitry Andric // Optional 'store' for operands that both load and store.
33710b57cec5SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") {
33720b57cec5SDimitry Andric Flags |= MachineMemOperand::MOStore;
33730b57cec5SDimitry Andric lex();
33740b57cec5SDimitry Andric }
33750b57cec5SDimitry Andric
33760b57cec5SDimitry Andric // Optional synchronization scope.
33770b57cec5SDimitry Andric SyncScope::ID SSID;
33780b57cec5SDimitry Andric if (parseOptionalScope(MF.getFunction().getContext(), SSID))
33790b57cec5SDimitry Andric return true;
33800b57cec5SDimitry Andric
33810b57cec5SDimitry Andric // Up to two atomic orderings (cmpxchg provides guarantees on failure).
33820b57cec5SDimitry Andric AtomicOrdering Order, FailureOrder;
33830b57cec5SDimitry Andric if (parseOptionalAtomicOrdering(Order))
33840b57cec5SDimitry Andric return true;
33850b57cec5SDimitry Andric
33860b57cec5SDimitry Andric if (parseOptionalAtomicOrdering(FailureOrder))
33870b57cec5SDimitry Andric return true;
33880b57cec5SDimitry Andric
3389fe6060f1SDimitry Andric LLT MemoryType;
33900b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) &&
3391fe6060f1SDimitry Andric Token.isNot(MIToken::kw_unknown_size) &&
3392fe6060f1SDimitry Andric Token.isNot(MIToken::lparen))
3393fe6060f1SDimitry Andric return error("expected memory LLT, the size integer literal or 'unknown-size' after "
33940b57cec5SDimitry Andric "memory operation");
3395fe6060f1SDimitry Andric
3396fe6060f1SDimitry Andric uint64_t Size = MemoryLocation::UnknownSize;
33970b57cec5SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) {
33980b57cec5SDimitry Andric if (getUint64(Size))
33990b57cec5SDimitry Andric return true;
3400fe6060f1SDimitry Andric
3401fe6060f1SDimitry Andric // Convert from bytes to bits for storage.
3402fe6060f1SDimitry Andric MemoryType = LLT::scalar(8 * Size);
3403fe6060f1SDimitry Andric lex();
34040b57cec5SDimitry Andric } else if (Token.is(MIToken::kw_unknown_size)) {
34050b57cec5SDimitry Andric Size = MemoryLocation::UnknownSize;
34060b57cec5SDimitry Andric lex();
3407fe6060f1SDimitry Andric } else {
3408fe6060f1SDimitry Andric if (expectAndConsume(MIToken::lparen))
3409fe6060f1SDimitry Andric return true;
3410fe6060f1SDimitry Andric if (parseLowLevelType(Token.location(), MemoryType))
3411fe6060f1SDimitry Andric return true;
3412fe6060f1SDimitry Andric if (expectAndConsume(MIToken::rparen))
3413fe6060f1SDimitry Andric return true;
3414fe6060f1SDimitry Andric
3415fe6060f1SDimitry Andric Size = MemoryType.getSizeInBytes();
3416fe6060f1SDimitry Andric }
34170b57cec5SDimitry Andric
34180b57cec5SDimitry Andric MachinePointerInfo Ptr = MachinePointerInfo();
34190b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) {
34200b57cec5SDimitry Andric const char *Word =
34210b57cec5SDimitry Andric ((Flags & MachineMemOperand::MOLoad) &&
34220b57cec5SDimitry Andric (Flags & MachineMemOperand::MOStore))
34230b57cec5SDimitry Andric ? "on"
34240b57cec5SDimitry Andric : Flags & MachineMemOperand::MOLoad ? "from" : "into";
34250b57cec5SDimitry Andric if (Token.stringValue() != Word)
34260b57cec5SDimitry Andric return error(Twine("expected '") + Word + "'");
34270b57cec5SDimitry Andric lex();
34280b57cec5SDimitry Andric
34290b57cec5SDimitry Andric if (parseMachinePointerInfo(Ptr))
34300b57cec5SDimitry Andric return true;
34310b57cec5SDimitry Andric }
3432349cc55cSDimitry Andric uint64_t BaseAlignment =
3433fe6060f1SDimitry Andric (Size != MemoryLocation::UnknownSize ? PowerOf2Ceil(Size) : 1);
34340b57cec5SDimitry Andric AAMDNodes AAInfo;
34350b57cec5SDimitry Andric MDNode *Range = nullptr;
34360b57cec5SDimitry Andric while (consumeIfPresent(MIToken::comma)) {
34370b57cec5SDimitry Andric switch (Token.kind()) {
343881ad6265SDimitry Andric case MIToken::kw_align: {
3439e8d8bef9SDimitry Andric // align is printed if it is different than size.
344081ad6265SDimitry Andric uint64_t Alignment;
344181ad6265SDimitry Andric if (parseAlignment(Alignment))
3442e8d8bef9SDimitry Andric return true;
344381ad6265SDimitry Andric if (Ptr.Offset & (Alignment - 1)) {
344481ad6265SDimitry Andric // MachineMemOperand::getAlign never returns a value greater than the
344581ad6265SDimitry Andric // alignment of offset, so this just guards against hand-written MIR
344681ad6265SDimitry Andric // that specifies a large "align" value when it should probably use
344781ad6265SDimitry Andric // "basealign" instead.
344881ad6265SDimitry Andric return error("specified alignment is more aligned than offset");
344981ad6265SDimitry Andric }
345081ad6265SDimitry Andric BaseAlignment = Alignment;
3451e8d8bef9SDimitry Andric break;
345281ad6265SDimitry Andric }
3453e8d8bef9SDimitry Andric case MIToken::kw_basealign:
3454e8d8bef9SDimitry Andric // basealign is printed if it is different than align.
34550b57cec5SDimitry Andric if (parseAlignment(BaseAlignment))
34560b57cec5SDimitry Andric return true;
34570b57cec5SDimitry Andric break;
34580b57cec5SDimitry Andric case MIToken::kw_addrspace:
34590b57cec5SDimitry Andric if (parseAddrspace(Ptr.AddrSpace))
34600b57cec5SDimitry Andric return true;
34610b57cec5SDimitry Andric break;
34620b57cec5SDimitry Andric case MIToken::md_tbaa:
34630b57cec5SDimitry Andric lex();
34640b57cec5SDimitry Andric if (parseMDNode(AAInfo.TBAA))
34650b57cec5SDimitry Andric return true;
34660b57cec5SDimitry Andric break;
34670b57cec5SDimitry Andric case MIToken::md_alias_scope:
34680b57cec5SDimitry Andric lex();
34690b57cec5SDimitry Andric if (parseMDNode(AAInfo.Scope))
34700b57cec5SDimitry Andric return true;
34710b57cec5SDimitry Andric break;
34720b57cec5SDimitry Andric case MIToken::md_noalias:
34730b57cec5SDimitry Andric lex();
34740b57cec5SDimitry Andric if (parseMDNode(AAInfo.NoAlias))
34750b57cec5SDimitry Andric return true;
34760b57cec5SDimitry Andric break;
34770b57cec5SDimitry Andric case MIToken::md_range:
34780b57cec5SDimitry Andric lex();
34790b57cec5SDimitry Andric if (parseMDNode(Range))
34800b57cec5SDimitry Andric return true;
34810b57cec5SDimitry Andric break;
34820b57cec5SDimitry Andric // TODO: Report an error on duplicate metadata nodes.
34830b57cec5SDimitry Andric default:
34840b57cec5SDimitry Andric return error("expected 'align' or '!tbaa' or '!alias.scope' or "
34850b57cec5SDimitry Andric "'!noalias' or '!range'");
34860b57cec5SDimitry Andric }
34870b57cec5SDimitry Andric }
34880b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen))
34890b57cec5SDimitry Andric return true;
3490fe6060f1SDimitry Andric Dest = MF.getMachineMemOperand(Ptr, Flags, MemoryType, Align(BaseAlignment),
3491fe6060f1SDimitry Andric AAInfo, Range, SSID, Order, FailureOrder);
34920b57cec5SDimitry Andric return false;
34930b57cec5SDimitry Andric }
34940b57cec5SDimitry Andric
parsePreOrPostInstrSymbol(MCSymbol * & Symbol)34950b57cec5SDimitry Andric bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) {
34960b57cec5SDimitry Andric assert((Token.is(MIToken::kw_pre_instr_symbol) ||
34970b57cec5SDimitry Andric Token.is(MIToken::kw_post_instr_symbol)) &&
34980b57cec5SDimitry Andric "Invalid token for a pre- post-instruction symbol!");
34990b57cec5SDimitry Andric lex();
35000b57cec5SDimitry Andric if (Token.isNot(MIToken::MCSymbol))
35010b57cec5SDimitry Andric return error("expected a symbol after 'pre-instr-symbol'");
35020b57cec5SDimitry Andric Symbol = getOrCreateMCSymbol(Token.stringValue());
35030b57cec5SDimitry Andric lex();
35040b57cec5SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
35050b57cec5SDimitry Andric Token.is(MIToken::lbrace))
35060b57cec5SDimitry Andric return false;
35070b57cec5SDimitry Andric if (Token.isNot(MIToken::comma))
35080b57cec5SDimitry Andric return error("expected ',' before the next machine operand");
35090b57cec5SDimitry Andric lex();
35100b57cec5SDimitry Andric return false;
35110b57cec5SDimitry Andric }
35120b57cec5SDimitry Andric
parseHeapAllocMarker(MDNode * & Node)3513480093f4SDimitry Andric bool MIParser::parseHeapAllocMarker(MDNode *&Node) {
3514480093f4SDimitry Andric assert(Token.is(MIToken::kw_heap_alloc_marker) &&
3515480093f4SDimitry Andric "Invalid token for a heap alloc marker!");
3516480093f4SDimitry Andric lex();
3517fe013be4SDimitry Andric if (parseMDNode(Node))
3518fe013be4SDimitry Andric return true;
3519480093f4SDimitry Andric if (!Node)
3520480093f4SDimitry Andric return error("expected a MDNode after 'heap-alloc-marker'");
3521480093f4SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3522480093f4SDimitry Andric Token.is(MIToken::lbrace))
3523480093f4SDimitry Andric return false;
3524480093f4SDimitry Andric if (Token.isNot(MIToken::comma))
3525480093f4SDimitry Andric return error("expected ',' before the next machine operand");
3526480093f4SDimitry Andric lex();
3527480093f4SDimitry Andric return false;
3528480093f4SDimitry Andric }
3529480093f4SDimitry Andric
parsePCSections(MDNode * & Node)3530bdd1243dSDimitry Andric bool MIParser::parsePCSections(MDNode *&Node) {
3531bdd1243dSDimitry Andric assert(Token.is(MIToken::kw_pcsections) &&
3532bdd1243dSDimitry Andric "Invalid token for a PC sections!");
3533bdd1243dSDimitry Andric lex();
3534fe013be4SDimitry Andric if (parseMDNode(Node))
3535fe013be4SDimitry Andric return true;
3536bdd1243dSDimitry Andric if (!Node)
3537bdd1243dSDimitry Andric return error("expected a MDNode after 'pcsections'");
3538bdd1243dSDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) ||
3539bdd1243dSDimitry Andric Token.is(MIToken::lbrace))
3540bdd1243dSDimitry Andric return false;
3541bdd1243dSDimitry Andric if (Token.isNot(MIToken::comma))
3542bdd1243dSDimitry Andric return error("expected ',' before the next machine operand");
3543bdd1243dSDimitry Andric lex();
3544bdd1243dSDimitry Andric return false;
3545bdd1243dSDimitry Andric }
3546bdd1243dSDimitry Andric
initSlots2BasicBlocks(const Function & F,DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)35470b57cec5SDimitry Andric static void initSlots2BasicBlocks(
35480b57cec5SDimitry Andric const Function &F,
35490b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
35500b57cec5SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
35510b57cec5SDimitry Andric MST.incorporateFunction(F);
3552fcaf7f86SDimitry Andric for (const auto &BB : F) {
35530b57cec5SDimitry Andric if (BB.hasName())
35540b57cec5SDimitry Andric continue;
35550b57cec5SDimitry Andric int Slot = MST.getLocalSlot(&BB);
35560b57cec5SDimitry Andric if (Slot == -1)
35570b57cec5SDimitry Andric continue;
35580b57cec5SDimitry Andric Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB));
35590b57cec5SDimitry Andric }
35600b57cec5SDimitry Andric }
35610b57cec5SDimitry Andric
getIRBlockFromSlot(unsigned Slot,const DenseMap<unsigned,const BasicBlock * > & Slots2BasicBlocks)35620b57cec5SDimitry Andric static const BasicBlock *getIRBlockFromSlot(
35630b57cec5SDimitry Andric unsigned Slot,
35640b57cec5SDimitry Andric const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
3565e8d8bef9SDimitry Andric return Slots2BasicBlocks.lookup(Slot);
35660b57cec5SDimitry Andric }
35670b57cec5SDimitry Andric
getIRBlock(unsigned Slot)35680b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot) {
35690b57cec5SDimitry Andric if (Slots2BasicBlocks.empty())
35700b57cec5SDimitry Andric initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks);
35710b57cec5SDimitry Andric return getIRBlockFromSlot(Slot, Slots2BasicBlocks);
35720b57cec5SDimitry Andric }
35730b57cec5SDimitry Andric
getIRBlock(unsigned Slot,const Function & F)35740b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) {
35750b57cec5SDimitry Andric if (&F == &MF.getFunction())
35760b57cec5SDimitry Andric return getIRBlock(Slot);
35770b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks;
35780b57cec5SDimitry Andric initSlots2BasicBlocks(F, CustomSlots2BasicBlocks);
35790b57cec5SDimitry Andric return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks);
35800b57cec5SDimitry Andric }
35810b57cec5SDimitry Andric
getOrCreateMCSymbol(StringRef Name)35820b57cec5SDimitry Andric MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) {
35830b57cec5SDimitry Andric // FIXME: Currently we can't recognize temporary or local symbols and call all
35840b57cec5SDimitry Andric // of the appropriate forms to create them. However, this handles basic cases
35850b57cec5SDimitry Andric // well as most of the special aspects are recognized by a prefix on their
35860b57cec5SDimitry Andric // name, and the input names should already be unique. For test cases, keeping
35870b57cec5SDimitry Andric // the symbol name out of the symbol table isn't terribly important.
35880b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Name);
35890b57cec5SDimitry Andric }
35900b57cec5SDimitry Andric
parseStringConstant(std::string & Result)35910b57cec5SDimitry Andric bool MIParser::parseStringConstant(std::string &Result) {
35920b57cec5SDimitry Andric if (Token.isNot(MIToken::StringConstant))
35930b57cec5SDimitry Andric return error("expected string constant");
35945ffd83dbSDimitry Andric Result = std::string(Token.stringValue());
35950b57cec5SDimitry Andric lex();
35960b57cec5SDimitry Andric return false;
35970b57cec5SDimitry Andric }
35980b57cec5SDimitry Andric
parseMachineBasicBlockDefinitions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)35990b57cec5SDimitry Andric bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS,
36000b57cec5SDimitry Andric StringRef Src,
36010b57cec5SDimitry Andric SMDiagnostic &Error) {
36020b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots);
36030b57cec5SDimitry Andric }
36040b57cec5SDimitry Andric
parseMachineInstructions(PerFunctionMIParsingState & PFS,StringRef Src,SMDiagnostic & Error)36050b57cec5SDimitry Andric bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS,
36060b57cec5SDimitry Andric StringRef Src, SMDiagnostic &Error) {
36070b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlocks();
36080b57cec5SDimitry Andric }
36090b57cec5SDimitry Andric
parseMBBReference(PerFunctionMIParsingState & PFS,MachineBasicBlock * & MBB,StringRef Src,SMDiagnostic & Error)36100b57cec5SDimitry Andric bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS,
36110b57cec5SDimitry Andric MachineBasicBlock *&MBB, StringRef Src,
36120b57cec5SDimitry Andric SMDiagnostic &Error) {
36130b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB);
36140b57cec5SDimitry Andric }
36150b57cec5SDimitry Andric
parseRegisterReference(PerFunctionMIParsingState & PFS,Register & Reg,StringRef Src,SMDiagnostic & Error)36160b57cec5SDimitry Andric bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS,
36175ffd83dbSDimitry Andric Register &Reg, StringRef Src,
36180b57cec5SDimitry Andric SMDiagnostic &Error) {
36190b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg);
36200b57cec5SDimitry Andric }
36210b57cec5SDimitry Andric
parseNamedRegisterReference(PerFunctionMIParsingState & PFS,Register & Reg,StringRef Src,SMDiagnostic & Error)36220b57cec5SDimitry Andric bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS,
36235ffd83dbSDimitry Andric Register &Reg, StringRef Src,
36240b57cec5SDimitry Andric SMDiagnostic &Error) {
36250b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg);
36260b57cec5SDimitry Andric }
36270b57cec5SDimitry Andric
parseVirtualRegisterReference(PerFunctionMIParsingState & PFS,VRegInfo * & Info,StringRef Src,SMDiagnostic & Error)36280b57cec5SDimitry Andric bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS,
36290b57cec5SDimitry Andric VRegInfo *&Info, StringRef Src,
36300b57cec5SDimitry Andric SMDiagnostic &Error) {
36310b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info);
36320b57cec5SDimitry Andric }
36330b57cec5SDimitry Andric
parseStackObjectReference(PerFunctionMIParsingState & PFS,int & FI,StringRef Src,SMDiagnostic & Error)36340b57cec5SDimitry Andric bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS,
36350b57cec5SDimitry Andric int &FI, StringRef Src,
36360b57cec5SDimitry Andric SMDiagnostic &Error) {
36370b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI);
36380b57cec5SDimitry Andric }
36390b57cec5SDimitry Andric
parseMDNode(PerFunctionMIParsingState & PFS,MDNode * & Node,StringRef Src,SMDiagnostic & Error)36400b57cec5SDimitry Andric bool llvm::parseMDNode(PerFunctionMIParsingState &PFS,
36410b57cec5SDimitry Andric MDNode *&Node, StringRef Src, SMDiagnostic &Error) {
36420b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node);
36430b57cec5SDimitry Andric }
3644480093f4SDimitry Andric
parseMachineMetadata(PerFunctionMIParsingState & PFS,StringRef Src,SMRange SrcRange,SMDiagnostic & Error)3645fe6060f1SDimitry Andric bool llvm::parseMachineMetadata(PerFunctionMIParsingState &PFS, StringRef Src,
3646fe6060f1SDimitry Andric SMRange SrcRange, SMDiagnostic &Error) {
3647fe6060f1SDimitry Andric return MIParser(PFS, Error, Src, SrcRange).parseMachineMetadata();
3648fe6060f1SDimitry Andric }
3649fe6060f1SDimitry Andric
parseIRValue(StringRef Src,MachineFunction & MF,PerFunctionMIParsingState & PFS,const Value * & V,ErrorCallbackType ErrorCallback)3650480093f4SDimitry Andric bool MIRFormatter::parseIRValue(StringRef Src, MachineFunction &MF,
3651480093f4SDimitry Andric PerFunctionMIParsingState &PFS, const Value *&V,
3652480093f4SDimitry Andric ErrorCallbackType ErrorCallback) {
3653480093f4SDimitry Andric MIToken Token;
3654480093f4SDimitry Andric Src = lexMIToken(Src, Token, [&](StringRef::iterator Loc, const Twine &Msg) {
3655480093f4SDimitry Andric ErrorCallback(Loc, Msg);
3656480093f4SDimitry Andric });
3657480093f4SDimitry Andric V = nullptr;
3658480093f4SDimitry Andric
3659480093f4SDimitry Andric return ::parseIRValue(Token, PFS, V, ErrorCallback);
3660480093f4SDimitry Andric }
3661