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