1*0b57cec5SDimitry Andric //===- MIParser.cpp - Machine instructions parser implementation ----------===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file implements the parsing of machine instructions. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #include "llvm/CodeGen/MIRParser/MIParser.h" 14*0b57cec5SDimitry Andric #include "MILexer.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/APInt.h" 16*0b57cec5SDimitry Andric #include "llvm/ADT/APSInt.h" 17*0b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 18*0b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 19*0b57cec5SDimitry Andric #include "llvm/ADT/None.h" 20*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 21*0b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 22*0b57cec5SDimitry Andric #include "llvm/ADT/StringMap.h" 23*0b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 24*0b57cec5SDimitry Andric #include "llvm/ADT/StringSwitch.h" 25*0b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 26*0b57cec5SDimitry Andric #include "llvm/Analysis/MemoryLocation.h" 27*0b57cec5SDimitry Andric #include "llvm/AsmParser/Parser.h" 28*0b57cec5SDimitry Andric #include "llvm/AsmParser/SlotMapping.h" 29*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 30*0b57cec5SDimitry Andric #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 31*0b57cec5SDimitry Andric #include "llvm/CodeGen/MIRPrinter.h" 32*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 33*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 34*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 35*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 36*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 37*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h" 38*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 39*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 40*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 41*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 42*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 43*0b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 44*0b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 45*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 46*0b57cec5SDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 47*0b57cec5SDimitry Andric #include "llvm/IR/DebugLoc.h" 48*0b57cec5SDimitry Andric #include "llvm/IR/Function.h" 49*0b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h" 50*0b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 51*0b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 52*0b57cec5SDimitry Andric #include "llvm/IR/Metadata.h" 53*0b57cec5SDimitry Andric #include "llvm/IR/Module.h" 54*0b57cec5SDimitry Andric #include "llvm/IR/ModuleSlotTracker.h" 55*0b57cec5SDimitry Andric #include "llvm/IR/Type.h" 56*0b57cec5SDimitry Andric #include "llvm/IR/Value.h" 57*0b57cec5SDimitry Andric #include "llvm/IR/ValueSymbolTable.h" 58*0b57cec5SDimitry Andric #include "llvm/MC/LaneBitmask.h" 59*0b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 60*0b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 61*0b57cec5SDimitry Andric #include "llvm/MC/MCInstrDesc.h" 62*0b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 63*0b57cec5SDimitry Andric #include "llvm/Support/AtomicOrdering.h" 64*0b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h" 65*0b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 66*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 67*0b57cec5SDimitry Andric #include "llvm/Support/LowLevelTypeImpl.h" 68*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h" 69*0b57cec5SDimitry Andric #include "llvm/Support/SMLoc.h" 70*0b57cec5SDimitry Andric #include "llvm/Support/SourceMgr.h" 71*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 72*0b57cec5SDimitry Andric #include "llvm/Target/TargetIntrinsicInfo.h" 73*0b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h" 74*0b57cec5SDimitry Andric #include <algorithm> 75*0b57cec5SDimitry Andric #include <cassert> 76*0b57cec5SDimitry Andric #include <cctype> 77*0b57cec5SDimitry Andric #include <cstddef> 78*0b57cec5SDimitry Andric #include <cstdint> 79*0b57cec5SDimitry Andric #include <limits> 80*0b57cec5SDimitry Andric #include <string> 81*0b57cec5SDimitry Andric #include <utility> 82*0b57cec5SDimitry Andric 83*0b57cec5SDimitry Andric using namespace llvm; 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric void PerTargetMIParsingState::setTarget( 86*0b57cec5SDimitry Andric const TargetSubtargetInfo &NewSubtarget) { 87*0b57cec5SDimitry Andric 88*0b57cec5SDimitry Andric // If the subtarget changed, over conservatively assume everything is invalid. 89*0b57cec5SDimitry Andric if (&Subtarget == &NewSubtarget) 90*0b57cec5SDimitry Andric return; 91*0b57cec5SDimitry Andric 92*0b57cec5SDimitry Andric Names2InstrOpCodes.clear(); 93*0b57cec5SDimitry Andric Names2Regs.clear(); 94*0b57cec5SDimitry Andric Names2RegMasks.clear(); 95*0b57cec5SDimitry Andric Names2SubRegIndices.clear(); 96*0b57cec5SDimitry Andric Names2TargetIndices.clear(); 97*0b57cec5SDimitry Andric Names2DirectTargetFlags.clear(); 98*0b57cec5SDimitry Andric Names2BitmaskTargetFlags.clear(); 99*0b57cec5SDimitry Andric Names2MMOTargetFlags.clear(); 100*0b57cec5SDimitry Andric 101*0b57cec5SDimitry Andric initNames2RegClasses(); 102*0b57cec5SDimitry Andric initNames2RegBanks(); 103*0b57cec5SDimitry Andric } 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2Regs() { 106*0b57cec5SDimitry Andric if (!Names2Regs.empty()) 107*0b57cec5SDimitry Andric return; 108*0b57cec5SDimitry Andric 109*0b57cec5SDimitry Andric // The '%noreg' register is the register 0. 110*0b57cec5SDimitry Andric Names2Regs.insert(std::make_pair("noreg", 0)); 111*0b57cec5SDimitry Andric const auto *TRI = Subtarget.getRegisterInfo(); 112*0b57cec5SDimitry Andric assert(TRI && "Expected target register info"); 113*0b57cec5SDimitry Andric 114*0b57cec5SDimitry Andric for (unsigned I = 0, E = TRI->getNumRegs(); I < E; ++I) { 115*0b57cec5SDimitry Andric bool WasInserted = 116*0b57cec5SDimitry Andric Names2Regs.insert(std::make_pair(StringRef(TRI->getName(I)).lower(), I)) 117*0b57cec5SDimitry Andric .second; 118*0b57cec5SDimitry Andric (void)WasInserted; 119*0b57cec5SDimitry Andric assert(WasInserted && "Expected registers to be unique case-insensitively"); 120*0b57cec5SDimitry Andric } 121*0b57cec5SDimitry Andric } 122*0b57cec5SDimitry Andric 123*0b57cec5SDimitry Andric bool PerTargetMIParsingState::getRegisterByName(StringRef RegName, 124*0b57cec5SDimitry Andric unsigned &Reg) { 125*0b57cec5SDimitry Andric initNames2Regs(); 126*0b57cec5SDimitry Andric auto RegInfo = Names2Regs.find(RegName); 127*0b57cec5SDimitry Andric if (RegInfo == Names2Regs.end()) 128*0b57cec5SDimitry Andric return true; 129*0b57cec5SDimitry Andric Reg = RegInfo->getValue(); 130*0b57cec5SDimitry Andric return false; 131*0b57cec5SDimitry Andric } 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2InstrOpCodes() { 134*0b57cec5SDimitry Andric if (!Names2InstrOpCodes.empty()) 135*0b57cec5SDimitry Andric return; 136*0b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo(); 137*0b57cec5SDimitry Andric assert(TII && "Expected target instruction info"); 138*0b57cec5SDimitry Andric for (unsigned I = 0, E = TII->getNumOpcodes(); I < E; ++I) 139*0b57cec5SDimitry Andric Names2InstrOpCodes.insert(std::make_pair(StringRef(TII->getName(I)), I)); 140*0b57cec5SDimitry Andric } 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric bool PerTargetMIParsingState::parseInstrName(StringRef InstrName, 143*0b57cec5SDimitry Andric unsigned &OpCode) { 144*0b57cec5SDimitry Andric initNames2InstrOpCodes(); 145*0b57cec5SDimitry Andric auto InstrInfo = Names2InstrOpCodes.find(InstrName); 146*0b57cec5SDimitry Andric if (InstrInfo == Names2InstrOpCodes.end()) 147*0b57cec5SDimitry Andric return true; 148*0b57cec5SDimitry Andric OpCode = InstrInfo->getValue(); 149*0b57cec5SDimitry Andric return false; 150*0b57cec5SDimitry Andric } 151*0b57cec5SDimitry Andric 152*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegMasks() { 153*0b57cec5SDimitry Andric if (!Names2RegMasks.empty()) 154*0b57cec5SDimitry Andric return; 155*0b57cec5SDimitry Andric const auto *TRI = Subtarget.getRegisterInfo(); 156*0b57cec5SDimitry Andric assert(TRI && "Expected target register info"); 157*0b57cec5SDimitry Andric ArrayRef<const uint32_t *> RegMasks = TRI->getRegMasks(); 158*0b57cec5SDimitry Andric ArrayRef<const char *> RegMaskNames = TRI->getRegMaskNames(); 159*0b57cec5SDimitry Andric assert(RegMasks.size() == RegMaskNames.size()); 160*0b57cec5SDimitry Andric for (size_t I = 0, E = RegMasks.size(); I < E; ++I) 161*0b57cec5SDimitry Andric Names2RegMasks.insert( 162*0b57cec5SDimitry Andric std::make_pair(StringRef(RegMaskNames[I]).lower(), RegMasks[I])); 163*0b57cec5SDimitry Andric } 164*0b57cec5SDimitry Andric 165*0b57cec5SDimitry Andric const uint32_t *PerTargetMIParsingState::getRegMask(StringRef Identifier) { 166*0b57cec5SDimitry Andric initNames2RegMasks(); 167*0b57cec5SDimitry Andric auto RegMaskInfo = Names2RegMasks.find(Identifier); 168*0b57cec5SDimitry Andric if (RegMaskInfo == Names2RegMasks.end()) 169*0b57cec5SDimitry Andric return nullptr; 170*0b57cec5SDimitry Andric return RegMaskInfo->getValue(); 171*0b57cec5SDimitry Andric } 172*0b57cec5SDimitry Andric 173*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2SubRegIndices() { 174*0b57cec5SDimitry Andric if (!Names2SubRegIndices.empty()) 175*0b57cec5SDimitry Andric return; 176*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); 177*0b57cec5SDimitry Andric for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I) 178*0b57cec5SDimitry Andric Names2SubRegIndices.insert( 179*0b57cec5SDimitry Andric std::make_pair(TRI->getSubRegIndexName(I), I)); 180*0b57cec5SDimitry Andric } 181*0b57cec5SDimitry Andric 182*0b57cec5SDimitry Andric unsigned PerTargetMIParsingState::getSubRegIndex(StringRef Name) { 183*0b57cec5SDimitry Andric initNames2SubRegIndices(); 184*0b57cec5SDimitry Andric auto SubRegInfo = Names2SubRegIndices.find(Name); 185*0b57cec5SDimitry Andric if (SubRegInfo == Names2SubRegIndices.end()) 186*0b57cec5SDimitry Andric return 0; 187*0b57cec5SDimitry Andric return SubRegInfo->getValue(); 188*0b57cec5SDimitry Andric } 189*0b57cec5SDimitry Andric 190*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2TargetIndices() { 191*0b57cec5SDimitry Andric if (!Names2TargetIndices.empty()) 192*0b57cec5SDimitry Andric return; 193*0b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo(); 194*0b57cec5SDimitry Andric assert(TII && "Expected target instruction info"); 195*0b57cec5SDimitry Andric auto Indices = TII->getSerializableTargetIndices(); 196*0b57cec5SDimitry Andric for (const auto &I : Indices) 197*0b57cec5SDimitry Andric Names2TargetIndices.insert(std::make_pair(StringRef(I.second), I.first)); 198*0b57cec5SDimitry Andric } 199*0b57cec5SDimitry Andric 200*0b57cec5SDimitry Andric bool PerTargetMIParsingState::getTargetIndex(StringRef Name, int &Index) { 201*0b57cec5SDimitry Andric initNames2TargetIndices(); 202*0b57cec5SDimitry Andric auto IndexInfo = Names2TargetIndices.find(Name); 203*0b57cec5SDimitry Andric if (IndexInfo == Names2TargetIndices.end()) 204*0b57cec5SDimitry Andric return true; 205*0b57cec5SDimitry Andric Index = IndexInfo->second; 206*0b57cec5SDimitry Andric return false; 207*0b57cec5SDimitry Andric } 208*0b57cec5SDimitry Andric 209*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2DirectTargetFlags() { 210*0b57cec5SDimitry Andric if (!Names2DirectTargetFlags.empty()) 211*0b57cec5SDimitry Andric return; 212*0b57cec5SDimitry Andric 213*0b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo(); 214*0b57cec5SDimitry Andric assert(TII && "Expected target instruction info"); 215*0b57cec5SDimitry Andric auto Flags = TII->getSerializableDirectMachineOperandTargetFlags(); 216*0b57cec5SDimitry Andric for (const auto &I : Flags) 217*0b57cec5SDimitry Andric Names2DirectTargetFlags.insert( 218*0b57cec5SDimitry Andric std::make_pair(StringRef(I.second), I.first)); 219*0b57cec5SDimitry Andric } 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andric bool PerTargetMIParsingState::getDirectTargetFlag(StringRef Name, 222*0b57cec5SDimitry Andric unsigned &Flag) { 223*0b57cec5SDimitry Andric initNames2DirectTargetFlags(); 224*0b57cec5SDimitry Andric auto FlagInfo = Names2DirectTargetFlags.find(Name); 225*0b57cec5SDimitry Andric if (FlagInfo == Names2DirectTargetFlags.end()) 226*0b57cec5SDimitry Andric return true; 227*0b57cec5SDimitry Andric Flag = FlagInfo->second; 228*0b57cec5SDimitry Andric return false; 229*0b57cec5SDimitry Andric } 230*0b57cec5SDimitry Andric 231*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2BitmaskTargetFlags() { 232*0b57cec5SDimitry Andric if (!Names2BitmaskTargetFlags.empty()) 233*0b57cec5SDimitry Andric return; 234*0b57cec5SDimitry Andric 235*0b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo(); 236*0b57cec5SDimitry Andric assert(TII && "Expected target instruction info"); 237*0b57cec5SDimitry Andric auto Flags = TII->getSerializableBitmaskMachineOperandTargetFlags(); 238*0b57cec5SDimitry Andric for (const auto &I : Flags) 239*0b57cec5SDimitry Andric Names2BitmaskTargetFlags.insert( 240*0b57cec5SDimitry Andric std::make_pair(StringRef(I.second), I.first)); 241*0b57cec5SDimitry Andric } 242*0b57cec5SDimitry Andric 243*0b57cec5SDimitry Andric bool PerTargetMIParsingState::getBitmaskTargetFlag(StringRef Name, 244*0b57cec5SDimitry Andric unsigned &Flag) { 245*0b57cec5SDimitry Andric initNames2BitmaskTargetFlags(); 246*0b57cec5SDimitry Andric auto FlagInfo = Names2BitmaskTargetFlags.find(Name); 247*0b57cec5SDimitry Andric if (FlagInfo == Names2BitmaskTargetFlags.end()) 248*0b57cec5SDimitry Andric return true; 249*0b57cec5SDimitry Andric Flag = FlagInfo->second; 250*0b57cec5SDimitry Andric return false; 251*0b57cec5SDimitry Andric } 252*0b57cec5SDimitry Andric 253*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2MMOTargetFlags() { 254*0b57cec5SDimitry Andric if (!Names2MMOTargetFlags.empty()) 255*0b57cec5SDimitry Andric return; 256*0b57cec5SDimitry Andric 257*0b57cec5SDimitry Andric const auto *TII = Subtarget.getInstrInfo(); 258*0b57cec5SDimitry Andric assert(TII && "Expected target instruction info"); 259*0b57cec5SDimitry Andric auto Flags = TII->getSerializableMachineMemOperandTargetFlags(); 260*0b57cec5SDimitry Andric for (const auto &I : Flags) 261*0b57cec5SDimitry Andric Names2MMOTargetFlags.insert(std::make_pair(StringRef(I.second), I.first)); 262*0b57cec5SDimitry Andric } 263*0b57cec5SDimitry Andric 264*0b57cec5SDimitry Andric bool PerTargetMIParsingState::getMMOTargetFlag(StringRef Name, 265*0b57cec5SDimitry Andric MachineMemOperand::Flags &Flag) { 266*0b57cec5SDimitry Andric initNames2MMOTargetFlags(); 267*0b57cec5SDimitry Andric auto FlagInfo = Names2MMOTargetFlags.find(Name); 268*0b57cec5SDimitry Andric if (FlagInfo == Names2MMOTargetFlags.end()) 269*0b57cec5SDimitry Andric return true; 270*0b57cec5SDimitry Andric Flag = FlagInfo->second; 271*0b57cec5SDimitry Andric return false; 272*0b57cec5SDimitry Andric } 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegClasses() { 275*0b57cec5SDimitry Andric if (!Names2RegClasses.empty()) 276*0b57cec5SDimitry Andric return; 277*0b57cec5SDimitry Andric 278*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo(); 279*0b57cec5SDimitry Andric for (unsigned I = 0, E = TRI->getNumRegClasses(); I < E; ++I) { 280*0b57cec5SDimitry Andric const auto *RC = TRI->getRegClass(I); 281*0b57cec5SDimitry Andric Names2RegClasses.insert( 282*0b57cec5SDimitry Andric std::make_pair(StringRef(TRI->getRegClassName(RC)).lower(), RC)); 283*0b57cec5SDimitry Andric } 284*0b57cec5SDimitry Andric } 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric void PerTargetMIParsingState::initNames2RegBanks() { 287*0b57cec5SDimitry Andric if (!Names2RegBanks.empty()) 288*0b57cec5SDimitry Andric return; 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric const RegisterBankInfo *RBI = Subtarget.getRegBankInfo(); 291*0b57cec5SDimitry Andric // If the target does not support GlobalISel, we may not have a 292*0b57cec5SDimitry Andric // register bank info. 293*0b57cec5SDimitry Andric if (!RBI) 294*0b57cec5SDimitry Andric return; 295*0b57cec5SDimitry Andric 296*0b57cec5SDimitry Andric for (unsigned I = 0, E = RBI->getNumRegBanks(); I < E; ++I) { 297*0b57cec5SDimitry Andric const auto &RegBank = RBI->getRegBank(I); 298*0b57cec5SDimitry Andric Names2RegBanks.insert( 299*0b57cec5SDimitry Andric std::make_pair(StringRef(RegBank.getName()).lower(), &RegBank)); 300*0b57cec5SDimitry Andric } 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric 303*0b57cec5SDimitry Andric const TargetRegisterClass * 304*0b57cec5SDimitry Andric PerTargetMIParsingState::getRegClass(StringRef Name) { 305*0b57cec5SDimitry Andric auto RegClassInfo = Names2RegClasses.find(Name); 306*0b57cec5SDimitry Andric if (RegClassInfo == Names2RegClasses.end()) 307*0b57cec5SDimitry Andric return nullptr; 308*0b57cec5SDimitry Andric return RegClassInfo->getValue(); 309*0b57cec5SDimitry Andric } 310*0b57cec5SDimitry Andric 311*0b57cec5SDimitry Andric const RegisterBank *PerTargetMIParsingState::getRegBank(StringRef Name) { 312*0b57cec5SDimitry Andric auto RegBankInfo = Names2RegBanks.find(Name); 313*0b57cec5SDimitry Andric if (RegBankInfo == Names2RegBanks.end()) 314*0b57cec5SDimitry Andric return nullptr; 315*0b57cec5SDimitry Andric return RegBankInfo->getValue(); 316*0b57cec5SDimitry Andric } 317*0b57cec5SDimitry Andric 318*0b57cec5SDimitry Andric PerFunctionMIParsingState::PerFunctionMIParsingState(MachineFunction &MF, 319*0b57cec5SDimitry Andric SourceMgr &SM, const SlotMapping &IRSlots, PerTargetMIParsingState &T) 320*0b57cec5SDimitry Andric : MF(MF), SM(&SM), IRSlots(IRSlots), Target(T) { 321*0b57cec5SDimitry Andric } 322*0b57cec5SDimitry Andric 323*0b57cec5SDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfo(unsigned Num) { 324*0b57cec5SDimitry Andric auto I = VRegInfos.insert(std::make_pair(Num, nullptr)); 325*0b57cec5SDimitry Andric if (I.second) { 326*0b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 327*0b57cec5SDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo; 328*0b57cec5SDimitry Andric Info->VReg = MRI.createIncompleteVirtualRegister(); 329*0b57cec5SDimitry Andric I.first->second = Info; 330*0b57cec5SDimitry Andric } 331*0b57cec5SDimitry Andric return *I.first->second; 332*0b57cec5SDimitry Andric } 333*0b57cec5SDimitry Andric 334*0b57cec5SDimitry Andric VRegInfo &PerFunctionMIParsingState::getVRegInfoNamed(StringRef RegName) { 335*0b57cec5SDimitry Andric assert(RegName != "" && "Expected named reg."); 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric auto I = VRegInfosNamed.insert(std::make_pair(RegName.str(), nullptr)); 338*0b57cec5SDimitry Andric if (I.second) { 339*0b57cec5SDimitry Andric VRegInfo *Info = new (Allocator) VRegInfo; 340*0b57cec5SDimitry Andric Info->VReg = MF.getRegInfo().createIncompleteVirtualRegister(RegName); 341*0b57cec5SDimitry Andric I.first->second = Info; 342*0b57cec5SDimitry Andric } 343*0b57cec5SDimitry Andric return *I.first->second; 344*0b57cec5SDimitry Andric } 345*0b57cec5SDimitry Andric 346*0b57cec5SDimitry Andric namespace { 347*0b57cec5SDimitry Andric 348*0b57cec5SDimitry Andric /// A wrapper struct around the 'MachineOperand' struct that includes a source 349*0b57cec5SDimitry Andric /// range and other attributes. 350*0b57cec5SDimitry Andric struct ParsedMachineOperand { 351*0b57cec5SDimitry Andric MachineOperand Operand; 352*0b57cec5SDimitry Andric StringRef::iterator Begin; 353*0b57cec5SDimitry Andric StringRef::iterator End; 354*0b57cec5SDimitry Andric Optional<unsigned> TiedDefIdx; 355*0b57cec5SDimitry Andric 356*0b57cec5SDimitry Andric ParsedMachineOperand(const MachineOperand &Operand, StringRef::iterator Begin, 357*0b57cec5SDimitry Andric StringRef::iterator End, Optional<unsigned> &TiedDefIdx) 358*0b57cec5SDimitry Andric : Operand(Operand), Begin(Begin), End(End), TiedDefIdx(TiedDefIdx) { 359*0b57cec5SDimitry Andric if (TiedDefIdx) 360*0b57cec5SDimitry Andric assert(Operand.isReg() && Operand.isUse() && 361*0b57cec5SDimitry Andric "Only used register operands can be tied"); 362*0b57cec5SDimitry Andric } 363*0b57cec5SDimitry Andric }; 364*0b57cec5SDimitry Andric 365*0b57cec5SDimitry Andric class MIParser { 366*0b57cec5SDimitry Andric MachineFunction &MF; 367*0b57cec5SDimitry Andric SMDiagnostic &Error; 368*0b57cec5SDimitry Andric StringRef Source, CurrentSource; 369*0b57cec5SDimitry Andric MIToken Token; 370*0b57cec5SDimitry Andric PerFunctionMIParsingState &PFS; 371*0b57cec5SDimitry Andric /// Maps from slot numbers to function's unnamed basic blocks. 372*0b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> Slots2BasicBlocks; 373*0b57cec5SDimitry Andric /// Maps from slot numbers to function's unnamed values. 374*0b57cec5SDimitry Andric DenseMap<unsigned, const Value *> Slots2Values; 375*0b57cec5SDimitry Andric 376*0b57cec5SDimitry Andric public: 377*0b57cec5SDimitry Andric MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, 378*0b57cec5SDimitry Andric StringRef Source); 379*0b57cec5SDimitry Andric 380*0b57cec5SDimitry Andric /// \p SkipChar gives the number of characters to skip before looking 381*0b57cec5SDimitry Andric /// for the next token. 382*0b57cec5SDimitry Andric void lex(unsigned SkipChar = 0); 383*0b57cec5SDimitry Andric 384*0b57cec5SDimitry Andric /// Report an error at the current location with the given message. 385*0b57cec5SDimitry Andric /// 386*0b57cec5SDimitry Andric /// This function always return true. 387*0b57cec5SDimitry Andric bool error(const Twine &Msg); 388*0b57cec5SDimitry Andric 389*0b57cec5SDimitry Andric /// Report an error at the given location with the given message. 390*0b57cec5SDimitry Andric /// 391*0b57cec5SDimitry Andric /// This function always return true. 392*0b57cec5SDimitry Andric bool error(StringRef::iterator Loc, const Twine &Msg); 393*0b57cec5SDimitry Andric 394*0b57cec5SDimitry Andric bool 395*0b57cec5SDimitry Andric parseBasicBlockDefinitions(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); 396*0b57cec5SDimitry Andric bool parseBasicBlocks(); 397*0b57cec5SDimitry Andric bool parse(MachineInstr *&MI); 398*0b57cec5SDimitry Andric bool parseStandaloneMBB(MachineBasicBlock *&MBB); 399*0b57cec5SDimitry Andric bool parseStandaloneNamedRegister(unsigned &Reg); 400*0b57cec5SDimitry Andric bool parseStandaloneVirtualRegister(VRegInfo *&Info); 401*0b57cec5SDimitry Andric bool parseStandaloneRegister(unsigned &Reg); 402*0b57cec5SDimitry Andric bool parseStandaloneStackObject(int &FI); 403*0b57cec5SDimitry Andric bool parseStandaloneMDNode(MDNode *&Node); 404*0b57cec5SDimitry Andric 405*0b57cec5SDimitry Andric bool 406*0b57cec5SDimitry Andric parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots); 407*0b57cec5SDimitry Andric bool parseBasicBlock(MachineBasicBlock &MBB, 408*0b57cec5SDimitry Andric MachineBasicBlock *&AddFalthroughFrom); 409*0b57cec5SDimitry Andric bool parseBasicBlockLiveins(MachineBasicBlock &MBB); 410*0b57cec5SDimitry Andric bool parseBasicBlockSuccessors(MachineBasicBlock &MBB); 411*0b57cec5SDimitry Andric 412*0b57cec5SDimitry Andric bool parseNamedRegister(unsigned &Reg); 413*0b57cec5SDimitry Andric bool parseVirtualRegister(VRegInfo *&Info); 414*0b57cec5SDimitry Andric bool parseNamedVirtualRegister(VRegInfo *&Info); 415*0b57cec5SDimitry Andric bool parseRegister(unsigned &Reg, VRegInfo *&VRegInfo); 416*0b57cec5SDimitry Andric bool parseRegisterFlag(unsigned &Flags); 417*0b57cec5SDimitry Andric bool parseRegisterClassOrBank(VRegInfo &RegInfo); 418*0b57cec5SDimitry Andric bool parseSubRegisterIndex(unsigned &SubReg); 419*0b57cec5SDimitry Andric bool parseRegisterTiedDefIndex(unsigned &TiedDefIdx); 420*0b57cec5SDimitry Andric bool parseRegisterOperand(MachineOperand &Dest, 421*0b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx, bool IsDef = false); 422*0b57cec5SDimitry Andric bool parseImmediateOperand(MachineOperand &Dest); 423*0b57cec5SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, StringRef StringValue, 424*0b57cec5SDimitry Andric const Constant *&C); 425*0b57cec5SDimitry Andric bool parseIRConstant(StringRef::iterator Loc, const Constant *&C); 426*0b57cec5SDimitry Andric bool parseLowLevelType(StringRef::iterator Loc, LLT &Ty); 427*0b57cec5SDimitry Andric bool parseTypedImmediateOperand(MachineOperand &Dest); 428*0b57cec5SDimitry Andric bool parseFPImmediateOperand(MachineOperand &Dest); 429*0b57cec5SDimitry Andric bool parseMBBReference(MachineBasicBlock *&MBB); 430*0b57cec5SDimitry Andric bool parseMBBOperand(MachineOperand &Dest); 431*0b57cec5SDimitry Andric bool parseStackFrameIndex(int &FI); 432*0b57cec5SDimitry Andric bool parseStackObjectOperand(MachineOperand &Dest); 433*0b57cec5SDimitry Andric bool parseFixedStackFrameIndex(int &FI); 434*0b57cec5SDimitry Andric bool parseFixedStackObjectOperand(MachineOperand &Dest); 435*0b57cec5SDimitry Andric bool parseGlobalValue(GlobalValue *&GV); 436*0b57cec5SDimitry Andric bool parseGlobalAddressOperand(MachineOperand &Dest); 437*0b57cec5SDimitry Andric bool parseConstantPoolIndexOperand(MachineOperand &Dest); 438*0b57cec5SDimitry Andric bool parseSubRegisterIndexOperand(MachineOperand &Dest); 439*0b57cec5SDimitry Andric bool parseJumpTableIndexOperand(MachineOperand &Dest); 440*0b57cec5SDimitry Andric bool parseExternalSymbolOperand(MachineOperand &Dest); 441*0b57cec5SDimitry Andric bool parseMCSymbolOperand(MachineOperand &Dest); 442*0b57cec5SDimitry Andric bool parseMDNode(MDNode *&Node); 443*0b57cec5SDimitry Andric bool parseDIExpression(MDNode *&Expr); 444*0b57cec5SDimitry Andric bool parseDILocation(MDNode *&Expr); 445*0b57cec5SDimitry Andric bool parseMetadataOperand(MachineOperand &Dest); 446*0b57cec5SDimitry Andric bool parseCFIOffset(int &Offset); 447*0b57cec5SDimitry Andric bool parseCFIRegister(unsigned &Reg); 448*0b57cec5SDimitry Andric bool parseCFIEscapeValues(std::string& Values); 449*0b57cec5SDimitry Andric bool parseCFIOperand(MachineOperand &Dest); 450*0b57cec5SDimitry Andric bool parseIRBlock(BasicBlock *&BB, const Function &F); 451*0b57cec5SDimitry Andric bool parseBlockAddressOperand(MachineOperand &Dest); 452*0b57cec5SDimitry Andric bool parseIntrinsicOperand(MachineOperand &Dest); 453*0b57cec5SDimitry Andric bool parsePredicateOperand(MachineOperand &Dest); 454*0b57cec5SDimitry Andric bool parseTargetIndexOperand(MachineOperand &Dest); 455*0b57cec5SDimitry Andric bool parseCustomRegisterMaskOperand(MachineOperand &Dest); 456*0b57cec5SDimitry Andric bool parseLiveoutRegisterMaskOperand(MachineOperand &Dest); 457*0b57cec5SDimitry Andric bool parseMachineOperand(MachineOperand &Dest, 458*0b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx); 459*0b57cec5SDimitry Andric bool parseMachineOperandAndTargetFlags(MachineOperand &Dest, 460*0b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx); 461*0b57cec5SDimitry Andric bool parseOffset(int64_t &Offset); 462*0b57cec5SDimitry Andric bool parseAlignment(unsigned &Alignment); 463*0b57cec5SDimitry Andric bool parseAddrspace(unsigned &Addrspace); 464*0b57cec5SDimitry Andric bool parseOperandsOffset(MachineOperand &Op); 465*0b57cec5SDimitry Andric bool parseIRValue(const Value *&V); 466*0b57cec5SDimitry Andric bool parseMemoryOperandFlag(MachineMemOperand::Flags &Flags); 467*0b57cec5SDimitry Andric bool parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV); 468*0b57cec5SDimitry Andric bool parseMachinePointerInfo(MachinePointerInfo &Dest); 469*0b57cec5SDimitry Andric bool parseOptionalScope(LLVMContext &Context, SyncScope::ID &SSID); 470*0b57cec5SDimitry Andric bool parseOptionalAtomicOrdering(AtomicOrdering &Order); 471*0b57cec5SDimitry Andric bool parseMachineMemoryOperand(MachineMemOperand *&Dest); 472*0b57cec5SDimitry Andric bool parsePreOrPostInstrSymbol(MCSymbol *&Symbol); 473*0b57cec5SDimitry Andric 474*0b57cec5SDimitry Andric private: 475*0b57cec5SDimitry Andric /// Convert the integer literal in the current token into an unsigned integer. 476*0b57cec5SDimitry Andric /// 477*0b57cec5SDimitry Andric /// Return true if an error occurred. 478*0b57cec5SDimitry Andric bool getUnsigned(unsigned &Result); 479*0b57cec5SDimitry Andric 480*0b57cec5SDimitry Andric /// Convert the integer literal in the current token into an uint64. 481*0b57cec5SDimitry Andric /// 482*0b57cec5SDimitry Andric /// Return true if an error occurred. 483*0b57cec5SDimitry Andric bool getUint64(uint64_t &Result); 484*0b57cec5SDimitry Andric 485*0b57cec5SDimitry Andric /// Convert the hexadecimal literal in the current token into an unsigned 486*0b57cec5SDimitry Andric /// APInt with a minimum bitwidth required to represent the value. 487*0b57cec5SDimitry Andric /// 488*0b57cec5SDimitry Andric /// Return true if the literal does not represent an integer value. 489*0b57cec5SDimitry Andric bool getHexUint(APInt &Result); 490*0b57cec5SDimitry Andric 491*0b57cec5SDimitry Andric /// If the current token is of the given kind, consume it and return false. 492*0b57cec5SDimitry Andric /// Otherwise report an error and return true. 493*0b57cec5SDimitry Andric bool expectAndConsume(MIToken::TokenKind TokenKind); 494*0b57cec5SDimitry Andric 495*0b57cec5SDimitry Andric /// If the current token is of the given kind, consume it and return true. 496*0b57cec5SDimitry Andric /// Otherwise return false. 497*0b57cec5SDimitry Andric bool consumeIfPresent(MIToken::TokenKind TokenKind); 498*0b57cec5SDimitry Andric 499*0b57cec5SDimitry Andric bool parseInstruction(unsigned &OpCode, unsigned &Flags); 500*0b57cec5SDimitry Andric 501*0b57cec5SDimitry Andric bool assignRegisterTies(MachineInstr &MI, 502*0b57cec5SDimitry Andric ArrayRef<ParsedMachineOperand> Operands); 503*0b57cec5SDimitry Andric 504*0b57cec5SDimitry Andric bool verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, 505*0b57cec5SDimitry Andric const MCInstrDesc &MCID); 506*0b57cec5SDimitry Andric 507*0b57cec5SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot); 508*0b57cec5SDimitry Andric const BasicBlock *getIRBlock(unsigned Slot, const Function &F); 509*0b57cec5SDimitry Andric 510*0b57cec5SDimitry Andric const Value *getIRValue(unsigned Slot); 511*0b57cec5SDimitry Andric 512*0b57cec5SDimitry Andric /// Get or create an MCSymbol for a given name. 513*0b57cec5SDimitry Andric MCSymbol *getOrCreateMCSymbol(StringRef Name); 514*0b57cec5SDimitry Andric 515*0b57cec5SDimitry Andric /// parseStringConstant 516*0b57cec5SDimitry Andric /// ::= StringConstant 517*0b57cec5SDimitry Andric bool parseStringConstant(std::string &Result); 518*0b57cec5SDimitry Andric }; 519*0b57cec5SDimitry Andric 520*0b57cec5SDimitry Andric } // end anonymous namespace 521*0b57cec5SDimitry Andric 522*0b57cec5SDimitry Andric MIParser::MIParser(PerFunctionMIParsingState &PFS, SMDiagnostic &Error, 523*0b57cec5SDimitry Andric StringRef Source) 524*0b57cec5SDimitry Andric : MF(PFS.MF), Error(Error), Source(Source), CurrentSource(Source), PFS(PFS) 525*0b57cec5SDimitry Andric {} 526*0b57cec5SDimitry Andric 527*0b57cec5SDimitry Andric void MIParser::lex(unsigned SkipChar) { 528*0b57cec5SDimitry Andric CurrentSource = lexMIToken( 529*0b57cec5SDimitry Andric CurrentSource.data() + SkipChar, Token, 530*0b57cec5SDimitry Andric [this](StringRef::iterator Loc, const Twine &Msg) { error(Loc, Msg); }); 531*0b57cec5SDimitry Andric } 532*0b57cec5SDimitry Andric 533*0b57cec5SDimitry Andric bool MIParser::error(const Twine &Msg) { return error(Token.location(), Msg); } 534*0b57cec5SDimitry Andric 535*0b57cec5SDimitry Andric bool MIParser::error(StringRef::iterator Loc, const Twine &Msg) { 536*0b57cec5SDimitry Andric const SourceMgr &SM = *PFS.SM; 537*0b57cec5SDimitry Andric assert(Loc >= Source.data() && Loc <= (Source.data() + Source.size())); 538*0b57cec5SDimitry Andric const MemoryBuffer &Buffer = *SM.getMemoryBuffer(SM.getMainFileID()); 539*0b57cec5SDimitry Andric if (Loc >= Buffer.getBufferStart() && Loc <= Buffer.getBufferEnd()) { 540*0b57cec5SDimitry Andric // Create an ordinary diagnostic when the source manager's buffer is the 541*0b57cec5SDimitry Andric // source string. 542*0b57cec5SDimitry Andric Error = SM.GetMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg); 543*0b57cec5SDimitry Andric return true; 544*0b57cec5SDimitry Andric } 545*0b57cec5SDimitry Andric // Create a diagnostic for a YAML string literal. 546*0b57cec5SDimitry Andric Error = SMDiagnostic(SM, SMLoc(), Buffer.getBufferIdentifier(), 1, 547*0b57cec5SDimitry Andric Loc - Source.data(), SourceMgr::DK_Error, Msg.str(), 548*0b57cec5SDimitry Andric Source, None, None); 549*0b57cec5SDimitry Andric return true; 550*0b57cec5SDimitry Andric } 551*0b57cec5SDimitry Andric 552*0b57cec5SDimitry Andric static const char *toString(MIToken::TokenKind TokenKind) { 553*0b57cec5SDimitry Andric switch (TokenKind) { 554*0b57cec5SDimitry Andric case MIToken::comma: 555*0b57cec5SDimitry Andric return "','"; 556*0b57cec5SDimitry Andric case MIToken::equal: 557*0b57cec5SDimitry Andric return "'='"; 558*0b57cec5SDimitry Andric case MIToken::colon: 559*0b57cec5SDimitry Andric return "':'"; 560*0b57cec5SDimitry Andric case MIToken::lparen: 561*0b57cec5SDimitry Andric return "'('"; 562*0b57cec5SDimitry Andric case MIToken::rparen: 563*0b57cec5SDimitry Andric return "')'"; 564*0b57cec5SDimitry Andric default: 565*0b57cec5SDimitry Andric return "<unknown token>"; 566*0b57cec5SDimitry Andric } 567*0b57cec5SDimitry Andric } 568*0b57cec5SDimitry Andric 569*0b57cec5SDimitry Andric bool MIParser::expectAndConsume(MIToken::TokenKind TokenKind) { 570*0b57cec5SDimitry Andric if (Token.isNot(TokenKind)) 571*0b57cec5SDimitry Andric return error(Twine("expected ") + toString(TokenKind)); 572*0b57cec5SDimitry Andric lex(); 573*0b57cec5SDimitry Andric return false; 574*0b57cec5SDimitry Andric } 575*0b57cec5SDimitry Andric 576*0b57cec5SDimitry Andric bool MIParser::consumeIfPresent(MIToken::TokenKind TokenKind) { 577*0b57cec5SDimitry Andric if (Token.isNot(TokenKind)) 578*0b57cec5SDimitry Andric return false; 579*0b57cec5SDimitry Andric lex(); 580*0b57cec5SDimitry Andric return true; 581*0b57cec5SDimitry Andric } 582*0b57cec5SDimitry Andric 583*0b57cec5SDimitry Andric bool MIParser::parseBasicBlockDefinition( 584*0b57cec5SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { 585*0b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel)); 586*0b57cec5SDimitry Andric unsigned ID = 0; 587*0b57cec5SDimitry Andric if (getUnsigned(ID)) 588*0b57cec5SDimitry Andric return true; 589*0b57cec5SDimitry Andric auto Loc = Token.location(); 590*0b57cec5SDimitry Andric auto Name = Token.stringValue(); 591*0b57cec5SDimitry Andric lex(); 592*0b57cec5SDimitry Andric bool HasAddressTaken = false; 593*0b57cec5SDimitry Andric bool IsLandingPad = false; 594*0b57cec5SDimitry Andric unsigned Alignment = 0; 595*0b57cec5SDimitry Andric BasicBlock *BB = nullptr; 596*0b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) { 597*0b57cec5SDimitry Andric do { 598*0b57cec5SDimitry Andric // TODO: Report an error when multiple same attributes are specified. 599*0b57cec5SDimitry Andric switch (Token.kind()) { 600*0b57cec5SDimitry Andric case MIToken::kw_address_taken: 601*0b57cec5SDimitry Andric HasAddressTaken = true; 602*0b57cec5SDimitry Andric lex(); 603*0b57cec5SDimitry Andric break; 604*0b57cec5SDimitry Andric case MIToken::kw_landing_pad: 605*0b57cec5SDimitry Andric IsLandingPad = true; 606*0b57cec5SDimitry Andric lex(); 607*0b57cec5SDimitry Andric break; 608*0b57cec5SDimitry Andric case MIToken::kw_align: 609*0b57cec5SDimitry Andric if (parseAlignment(Alignment)) 610*0b57cec5SDimitry Andric return true; 611*0b57cec5SDimitry Andric break; 612*0b57cec5SDimitry Andric case MIToken::IRBlock: 613*0b57cec5SDimitry Andric // TODO: Report an error when both name and ir block are specified. 614*0b57cec5SDimitry Andric if (parseIRBlock(BB, MF.getFunction())) 615*0b57cec5SDimitry Andric return true; 616*0b57cec5SDimitry Andric lex(); 617*0b57cec5SDimitry Andric break; 618*0b57cec5SDimitry Andric default: 619*0b57cec5SDimitry Andric break; 620*0b57cec5SDimitry Andric } 621*0b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma)); 622*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 623*0b57cec5SDimitry Andric return true; 624*0b57cec5SDimitry Andric } 625*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 626*0b57cec5SDimitry Andric return true; 627*0b57cec5SDimitry Andric 628*0b57cec5SDimitry Andric if (!Name.empty()) { 629*0b57cec5SDimitry Andric BB = dyn_cast_or_null<BasicBlock>( 630*0b57cec5SDimitry Andric MF.getFunction().getValueSymbolTable()->lookup(Name)); 631*0b57cec5SDimitry Andric if (!BB) 632*0b57cec5SDimitry Andric return error(Loc, Twine("basic block '") + Name + 633*0b57cec5SDimitry Andric "' is not defined in the function '" + 634*0b57cec5SDimitry Andric MF.getName() + "'"); 635*0b57cec5SDimitry Andric } 636*0b57cec5SDimitry Andric auto *MBB = MF.CreateMachineBasicBlock(BB); 637*0b57cec5SDimitry Andric MF.insert(MF.end(), MBB); 638*0b57cec5SDimitry Andric bool WasInserted = MBBSlots.insert(std::make_pair(ID, MBB)).second; 639*0b57cec5SDimitry Andric if (!WasInserted) 640*0b57cec5SDimitry Andric return error(Loc, Twine("redefinition of machine basic block with id #") + 641*0b57cec5SDimitry Andric Twine(ID)); 642*0b57cec5SDimitry Andric if (Alignment) 643*0b57cec5SDimitry Andric MBB->setAlignment(Alignment); 644*0b57cec5SDimitry Andric if (HasAddressTaken) 645*0b57cec5SDimitry Andric MBB->setHasAddressTaken(); 646*0b57cec5SDimitry Andric MBB->setIsEHPad(IsLandingPad); 647*0b57cec5SDimitry Andric return false; 648*0b57cec5SDimitry Andric } 649*0b57cec5SDimitry Andric 650*0b57cec5SDimitry Andric bool MIParser::parseBasicBlockDefinitions( 651*0b57cec5SDimitry Andric DenseMap<unsigned, MachineBasicBlock *> &MBBSlots) { 652*0b57cec5SDimitry Andric lex(); 653*0b57cec5SDimitry Andric // Skip until the first machine basic block. 654*0b57cec5SDimitry Andric while (Token.is(MIToken::Newline)) 655*0b57cec5SDimitry Andric lex(); 656*0b57cec5SDimitry Andric if (Token.isErrorOrEOF()) 657*0b57cec5SDimitry Andric return Token.isError(); 658*0b57cec5SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlockLabel)) 659*0b57cec5SDimitry Andric return error("expected a basic block definition before instructions"); 660*0b57cec5SDimitry Andric unsigned BraceDepth = 0; 661*0b57cec5SDimitry Andric do { 662*0b57cec5SDimitry Andric if (parseBasicBlockDefinition(MBBSlots)) 663*0b57cec5SDimitry Andric return true; 664*0b57cec5SDimitry Andric bool IsAfterNewline = false; 665*0b57cec5SDimitry Andric // Skip until the next machine basic block. 666*0b57cec5SDimitry Andric while (true) { 667*0b57cec5SDimitry Andric if ((Token.is(MIToken::MachineBasicBlockLabel) && IsAfterNewline) || 668*0b57cec5SDimitry Andric Token.isErrorOrEOF()) 669*0b57cec5SDimitry Andric break; 670*0b57cec5SDimitry Andric else if (Token.is(MIToken::MachineBasicBlockLabel)) 671*0b57cec5SDimitry Andric return error("basic block definition should be located at the start of " 672*0b57cec5SDimitry Andric "the line"); 673*0b57cec5SDimitry Andric else if (consumeIfPresent(MIToken::Newline)) { 674*0b57cec5SDimitry Andric IsAfterNewline = true; 675*0b57cec5SDimitry Andric continue; 676*0b57cec5SDimitry Andric } 677*0b57cec5SDimitry Andric IsAfterNewline = false; 678*0b57cec5SDimitry Andric if (Token.is(MIToken::lbrace)) 679*0b57cec5SDimitry Andric ++BraceDepth; 680*0b57cec5SDimitry Andric if (Token.is(MIToken::rbrace)) { 681*0b57cec5SDimitry Andric if (!BraceDepth) 682*0b57cec5SDimitry Andric return error("extraneous closing brace ('}')"); 683*0b57cec5SDimitry Andric --BraceDepth; 684*0b57cec5SDimitry Andric } 685*0b57cec5SDimitry Andric lex(); 686*0b57cec5SDimitry Andric } 687*0b57cec5SDimitry Andric // Verify that we closed all of the '{' at the end of a file or a block. 688*0b57cec5SDimitry Andric if (!Token.isError() && BraceDepth) 689*0b57cec5SDimitry Andric return error("expected '}'"); // FIXME: Report a note that shows '{'. 690*0b57cec5SDimitry Andric } while (!Token.isErrorOrEOF()); 691*0b57cec5SDimitry Andric return Token.isError(); 692*0b57cec5SDimitry Andric } 693*0b57cec5SDimitry Andric 694*0b57cec5SDimitry Andric bool MIParser::parseBasicBlockLiveins(MachineBasicBlock &MBB) { 695*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_liveins)); 696*0b57cec5SDimitry Andric lex(); 697*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 698*0b57cec5SDimitry Andric return true; 699*0b57cec5SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of liveins. 700*0b57cec5SDimitry Andric return false; 701*0b57cec5SDimitry Andric do { 702*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister)) 703*0b57cec5SDimitry Andric return error("expected a named register"); 704*0b57cec5SDimitry Andric unsigned Reg = 0; 705*0b57cec5SDimitry Andric if (parseNamedRegister(Reg)) 706*0b57cec5SDimitry Andric return true; 707*0b57cec5SDimitry Andric lex(); 708*0b57cec5SDimitry Andric LaneBitmask Mask = LaneBitmask::getAll(); 709*0b57cec5SDimitry Andric if (consumeIfPresent(MIToken::colon)) { 710*0b57cec5SDimitry Andric // Parse lane mask. 711*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) && 712*0b57cec5SDimitry Andric Token.isNot(MIToken::HexLiteral)) 713*0b57cec5SDimitry Andric return error("expected a lane mask"); 714*0b57cec5SDimitry Andric static_assert(sizeof(LaneBitmask::Type) == sizeof(unsigned), 715*0b57cec5SDimitry Andric "Use correct get-function for lane mask"); 716*0b57cec5SDimitry Andric LaneBitmask::Type V; 717*0b57cec5SDimitry Andric if (getUnsigned(V)) 718*0b57cec5SDimitry Andric return error("invalid lane mask value"); 719*0b57cec5SDimitry Andric Mask = LaneBitmask(V); 720*0b57cec5SDimitry Andric lex(); 721*0b57cec5SDimitry Andric } 722*0b57cec5SDimitry Andric MBB.addLiveIn(Reg, Mask); 723*0b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma)); 724*0b57cec5SDimitry Andric return false; 725*0b57cec5SDimitry Andric } 726*0b57cec5SDimitry Andric 727*0b57cec5SDimitry Andric bool MIParser::parseBasicBlockSuccessors(MachineBasicBlock &MBB) { 728*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_successors)); 729*0b57cec5SDimitry Andric lex(); 730*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 731*0b57cec5SDimitry Andric return true; 732*0b57cec5SDimitry Andric if (Token.isNewlineOrEOF()) // Allow an empty list of successors. 733*0b57cec5SDimitry Andric return false; 734*0b57cec5SDimitry Andric do { 735*0b57cec5SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock)) 736*0b57cec5SDimitry Andric return error("expected a machine basic block reference"); 737*0b57cec5SDimitry Andric MachineBasicBlock *SuccMBB = nullptr; 738*0b57cec5SDimitry Andric if (parseMBBReference(SuccMBB)) 739*0b57cec5SDimitry Andric return true; 740*0b57cec5SDimitry Andric lex(); 741*0b57cec5SDimitry Andric unsigned Weight = 0; 742*0b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) { 743*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) && 744*0b57cec5SDimitry Andric Token.isNot(MIToken::HexLiteral)) 745*0b57cec5SDimitry Andric return error("expected an integer literal after '('"); 746*0b57cec5SDimitry Andric if (getUnsigned(Weight)) 747*0b57cec5SDimitry Andric return true; 748*0b57cec5SDimitry Andric lex(); 749*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 750*0b57cec5SDimitry Andric return true; 751*0b57cec5SDimitry Andric } 752*0b57cec5SDimitry Andric MBB.addSuccessor(SuccMBB, BranchProbability::getRaw(Weight)); 753*0b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma)); 754*0b57cec5SDimitry Andric MBB.normalizeSuccProbs(); 755*0b57cec5SDimitry Andric return false; 756*0b57cec5SDimitry Andric } 757*0b57cec5SDimitry Andric 758*0b57cec5SDimitry Andric bool MIParser::parseBasicBlock(MachineBasicBlock &MBB, 759*0b57cec5SDimitry Andric MachineBasicBlock *&AddFalthroughFrom) { 760*0b57cec5SDimitry Andric // Skip the definition. 761*0b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel)); 762*0b57cec5SDimitry Andric lex(); 763*0b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) { 764*0b57cec5SDimitry Andric while (Token.isNot(MIToken::rparen) && !Token.isErrorOrEOF()) 765*0b57cec5SDimitry Andric lex(); 766*0b57cec5SDimitry Andric consumeIfPresent(MIToken::rparen); 767*0b57cec5SDimitry Andric } 768*0b57cec5SDimitry Andric consumeIfPresent(MIToken::colon); 769*0b57cec5SDimitry Andric 770*0b57cec5SDimitry Andric // Parse the liveins and successors. 771*0b57cec5SDimitry Andric // N.B: Multiple lists of successors and liveins are allowed and they're 772*0b57cec5SDimitry Andric // merged into one. 773*0b57cec5SDimitry Andric // Example: 774*0b57cec5SDimitry Andric // liveins: %edi 775*0b57cec5SDimitry Andric // liveins: %esi 776*0b57cec5SDimitry Andric // 777*0b57cec5SDimitry Andric // is equivalent to 778*0b57cec5SDimitry Andric // liveins: %edi, %esi 779*0b57cec5SDimitry Andric bool ExplicitSuccessors = false; 780*0b57cec5SDimitry Andric while (true) { 781*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_successors)) { 782*0b57cec5SDimitry Andric if (parseBasicBlockSuccessors(MBB)) 783*0b57cec5SDimitry Andric return true; 784*0b57cec5SDimitry Andric ExplicitSuccessors = true; 785*0b57cec5SDimitry Andric } else if (Token.is(MIToken::kw_liveins)) { 786*0b57cec5SDimitry Andric if (parseBasicBlockLiveins(MBB)) 787*0b57cec5SDimitry Andric return true; 788*0b57cec5SDimitry Andric } else if (consumeIfPresent(MIToken::Newline)) { 789*0b57cec5SDimitry Andric continue; 790*0b57cec5SDimitry Andric } else 791*0b57cec5SDimitry Andric break; 792*0b57cec5SDimitry Andric if (!Token.isNewlineOrEOF()) 793*0b57cec5SDimitry Andric return error("expected line break at the end of a list"); 794*0b57cec5SDimitry Andric lex(); 795*0b57cec5SDimitry Andric } 796*0b57cec5SDimitry Andric 797*0b57cec5SDimitry Andric // Parse the instructions. 798*0b57cec5SDimitry Andric bool IsInBundle = false; 799*0b57cec5SDimitry Andric MachineInstr *PrevMI = nullptr; 800*0b57cec5SDimitry Andric while (!Token.is(MIToken::MachineBasicBlockLabel) && 801*0b57cec5SDimitry Andric !Token.is(MIToken::Eof)) { 802*0b57cec5SDimitry Andric if (consumeIfPresent(MIToken::Newline)) 803*0b57cec5SDimitry Andric continue; 804*0b57cec5SDimitry Andric if (consumeIfPresent(MIToken::rbrace)) { 805*0b57cec5SDimitry Andric // The first parsing pass should verify that all closing '}' have an 806*0b57cec5SDimitry Andric // opening '{'. 807*0b57cec5SDimitry Andric assert(IsInBundle); 808*0b57cec5SDimitry Andric IsInBundle = false; 809*0b57cec5SDimitry Andric continue; 810*0b57cec5SDimitry Andric } 811*0b57cec5SDimitry Andric MachineInstr *MI = nullptr; 812*0b57cec5SDimitry Andric if (parse(MI)) 813*0b57cec5SDimitry Andric return true; 814*0b57cec5SDimitry Andric MBB.insert(MBB.end(), MI); 815*0b57cec5SDimitry Andric if (IsInBundle) { 816*0b57cec5SDimitry Andric PrevMI->setFlag(MachineInstr::BundledSucc); 817*0b57cec5SDimitry Andric MI->setFlag(MachineInstr::BundledPred); 818*0b57cec5SDimitry Andric } 819*0b57cec5SDimitry Andric PrevMI = MI; 820*0b57cec5SDimitry Andric if (Token.is(MIToken::lbrace)) { 821*0b57cec5SDimitry Andric if (IsInBundle) 822*0b57cec5SDimitry Andric return error("nested instruction bundles are not allowed"); 823*0b57cec5SDimitry Andric lex(); 824*0b57cec5SDimitry Andric // This instruction is the start of the bundle. 825*0b57cec5SDimitry Andric MI->setFlag(MachineInstr::BundledSucc); 826*0b57cec5SDimitry Andric IsInBundle = true; 827*0b57cec5SDimitry Andric if (!Token.is(MIToken::Newline)) 828*0b57cec5SDimitry Andric // The next instruction can be on the same line. 829*0b57cec5SDimitry Andric continue; 830*0b57cec5SDimitry Andric } 831*0b57cec5SDimitry Andric assert(Token.isNewlineOrEOF() && "MI is not fully parsed"); 832*0b57cec5SDimitry Andric lex(); 833*0b57cec5SDimitry Andric } 834*0b57cec5SDimitry Andric 835*0b57cec5SDimitry Andric // Construct successor list by searching for basic block machine operands. 836*0b57cec5SDimitry Andric if (!ExplicitSuccessors) { 837*0b57cec5SDimitry Andric SmallVector<MachineBasicBlock*,4> Successors; 838*0b57cec5SDimitry Andric bool IsFallthrough; 839*0b57cec5SDimitry Andric guessSuccessors(MBB, Successors, IsFallthrough); 840*0b57cec5SDimitry Andric for (MachineBasicBlock *Succ : Successors) 841*0b57cec5SDimitry Andric MBB.addSuccessor(Succ); 842*0b57cec5SDimitry Andric 843*0b57cec5SDimitry Andric if (IsFallthrough) { 844*0b57cec5SDimitry Andric AddFalthroughFrom = &MBB; 845*0b57cec5SDimitry Andric } else { 846*0b57cec5SDimitry Andric MBB.normalizeSuccProbs(); 847*0b57cec5SDimitry Andric } 848*0b57cec5SDimitry Andric } 849*0b57cec5SDimitry Andric 850*0b57cec5SDimitry Andric return false; 851*0b57cec5SDimitry Andric } 852*0b57cec5SDimitry Andric 853*0b57cec5SDimitry Andric bool MIParser::parseBasicBlocks() { 854*0b57cec5SDimitry Andric lex(); 855*0b57cec5SDimitry Andric // Skip until the first machine basic block. 856*0b57cec5SDimitry Andric while (Token.is(MIToken::Newline)) 857*0b57cec5SDimitry Andric lex(); 858*0b57cec5SDimitry Andric if (Token.isErrorOrEOF()) 859*0b57cec5SDimitry Andric return Token.isError(); 860*0b57cec5SDimitry Andric // The first parsing pass should have verified that this token is a MBB label 861*0b57cec5SDimitry Andric // in the 'parseBasicBlockDefinitions' method. 862*0b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel)); 863*0b57cec5SDimitry Andric MachineBasicBlock *AddFalthroughFrom = nullptr; 864*0b57cec5SDimitry Andric do { 865*0b57cec5SDimitry Andric MachineBasicBlock *MBB = nullptr; 866*0b57cec5SDimitry Andric if (parseMBBReference(MBB)) 867*0b57cec5SDimitry Andric return true; 868*0b57cec5SDimitry Andric if (AddFalthroughFrom) { 869*0b57cec5SDimitry Andric if (!AddFalthroughFrom->isSuccessor(MBB)) 870*0b57cec5SDimitry Andric AddFalthroughFrom->addSuccessor(MBB); 871*0b57cec5SDimitry Andric AddFalthroughFrom->normalizeSuccProbs(); 872*0b57cec5SDimitry Andric AddFalthroughFrom = nullptr; 873*0b57cec5SDimitry Andric } 874*0b57cec5SDimitry Andric if (parseBasicBlock(*MBB, AddFalthroughFrom)) 875*0b57cec5SDimitry Andric return true; 876*0b57cec5SDimitry Andric // The method 'parseBasicBlock' should parse the whole block until the next 877*0b57cec5SDimitry Andric // block or the end of file. 878*0b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlockLabel) || Token.is(MIToken::Eof)); 879*0b57cec5SDimitry Andric } while (Token.isNot(MIToken::Eof)); 880*0b57cec5SDimitry Andric return false; 881*0b57cec5SDimitry Andric } 882*0b57cec5SDimitry Andric 883*0b57cec5SDimitry Andric bool MIParser::parse(MachineInstr *&MI) { 884*0b57cec5SDimitry Andric // Parse any register operands before '=' 885*0b57cec5SDimitry Andric MachineOperand MO = MachineOperand::CreateImm(0); 886*0b57cec5SDimitry Andric SmallVector<ParsedMachineOperand, 8> Operands; 887*0b57cec5SDimitry Andric while (Token.isRegister() || Token.isRegisterFlag()) { 888*0b57cec5SDimitry Andric auto Loc = Token.location(); 889*0b57cec5SDimitry Andric Optional<unsigned> TiedDefIdx; 890*0b57cec5SDimitry Andric if (parseRegisterOperand(MO, TiedDefIdx, /*IsDef=*/true)) 891*0b57cec5SDimitry Andric return true; 892*0b57cec5SDimitry Andric Operands.push_back( 893*0b57cec5SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); 894*0b57cec5SDimitry Andric if (Token.isNot(MIToken::comma)) 895*0b57cec5SDimitry Andric break; 896*0b57cec5SDimitry Andric lex(); 897*0b57cec5SDimitry Andric } 898*0b57cec5SDimitry Andric if (!Operands.empty() && expectAndConsume(MIToken::equal)) 899*0b57cec5SDimitry Andric return true; 900*0b57cec5SDimitry Andric 901*0b57cec5SDimitry Andric unsigned OpCode, Flags = 0; 902*0b57cec5SDimitry Andric if (Token.isError() || parseInstruction(OpCode, Flags)) 903*0b57cec5SDimitry Andric return true; 904*0b57cec5SDimitry Andric 905*0b57cec5SDimitry Andric // Parse the remaining machine operands. 906*0b57cec5SDimitry Andric while (!Token.isNewlineOrEOF() && Token.isNot(MIToken::kw_pre_instr_symbol) && 907*0b57cec5SDimitry Andric Token.isNot(MIToken::kw_post_instr_symbol) && 908*0b57cec5SDimitry Andric Token.isNot(MIToken::kw_debug_location) && 909*0b57cec5SDimitry Andric Token.isNot(MIToken::coloncolon) && Token.isNot(MIToken::lbrace)) { 910*0b57cec5SDimitry Andric auto Loc = Token.location(); 911*0b57cec5SDimitry Andric Optional<unsigned> TiedDefIdx; 912*0b57cec5SDimitry Andric if (parseMachineOperandAndTargetFlags(MO, TiedDefIdx)) 913*0b57cec5SDimitry Andric return true; 914*0b57cec5SDimitry Andric if (OpCode == TargetOpcode::DBG_VALUE && MO.isReg()) 915*0b57cec5SDimitry Andric MO.setIsDebug(); 916*0b57cec5SDimitry Andric Operands.push_back( 917*0b57cec5SDimitry Andric ParsedMachineOperand(MO, Loc, Token.location(), TiedDefIdx)); 918*0b57cec5SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || 919*0b57cec5SDimitry Andric Token.is(MIToken::lbrace)) 920*0b57cec5SDimitry Andric break; 921*0b57cec5SDimitry Andric if (Token.isNot(MIToken::comma)) 922*0b57cec5SDimitry Andric return error("expected ',' before the next machine operand"); 923*0b57cec5SDimitry Andric lex(); 924*0b57cec5SDimitry Andric } 925*0b57cec5SDimitry Andric 926*0b57cec5SDimitry Andric MCSymbol *PreInstrSymbol = nullptr; 927*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_pre_instr_symbol)) 928*0b57cec5SDimitry Andric if (parsePreOrPostInstrSymbol(PreInstrSymbol)) 929*0b57cec5SDimitry Andric return true; 930*0b57cec5SDimitry Andric MCSymbol *PostInstrSymbol = nullptr; 931*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_post_instr_symbol)) 932*0b57cec5SDimitry Andric if (parsePreOrPostInstrSymbol(PostInstrSymbol)) 933*0b57cec5SDimitry Andric return true; 934*0b57cec5SDimitry Andric 935*0b57cec5SDimitry Andric DebugLoc DebugLocation; 936*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_debug_location)) { 937*0b57cec5SDimitry Andric lex(); 938*0b57cec5SDimitry Andric MDNode *Node = nullptr; 939*0b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) { 940*0b57cec5SDimitry Andric if (parseMDNode(Node)) 941*0b57cec5SDimitry Andric return true; 942*0b57cec5SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) { 943*0b57cec5SDimitry Andric if (parseDILocation(Node)) 944*0b57cec5SDimitry Andric return true; 945*0b57cec5SDimitry Andric } else 946*0b57cec5SDimitry Andric return error("expected a metadata node after 'debug-location'"); 947*0b57cec5SDimitry Andric if (!isa<DILocation>(Node)) 948*0b57cec5SDimitry Andric return error("referenced metadata is not a DILocation"); 949*0b57cec5SDimitry Andric DebugLocation = DebugLoc(Node); 950*0b57cec5SDimitry Andric } 951*0b57cec5SDimitry Andric 952*0b57cec5SDimitry Andric // Parse the machine memory operands. 953*0b57cec5SDimitry Andric SmallVector<MachineMemOperand *, 2> MemOperands; 954*0b57cec5SDimitry Andric if (Token.is(MIToken::coloncolon)) { 955*0b57cec5SDimitry Andric lex(); 956*0b57cec5SDimitry Andric while (!Token.isNewlineOrEOF()) { 957*0b57cec5SDimitry Andric MachineMemOperand *MemOp = nullptr; 958*0b57cec5SDimitry Andric if (parseMachineMemoryOperand(MemOp)) 959*0b57cec5SDimitry Andric return true; 960*0b57cec5SDimitry Andric MemOperands.push_back(MemOp); 961*0b57cec5SDimitry Andric if (Token.isNewlineOrEOF()) 962*0b57cec5SDimitry Andric break; 963*0b57cec5SDimitry Andric if (Token.isNot(MIToken::comma)) 964*0b57cec5SDimitry Andric return error("expected ',' before the next machine memory operand"); 965*0b57cec5SDimitry Andric lex(); 966*0b57cec5SDimitry Andric } 967*0b57cec5SDimitry Andric } 968*0b57cec5SDimitry Andric 969*0b57cec5SDimitry Andric const auto &MCID = MF.getSubtarget().getInstrInfo()->get(OpCode); 970*0b57cec5SDimitry Andric if (!MCID.isVariadic()) { 971*0b57cec5SDimitry Andric // FIXME: Move the implicit operand verification to the machine verifier. 972*0b57cec5SDimitry Andric if (verifyImplicitOperands(Operands, MCID)) 973*0b57cec5SDimitry Andric return true; 974*0b57cec5SDimitry Andric } 975*0b57cec5SDimitry Andric 976*0b57cec5SDimitry Andric // TODO: Check for extraneous machine operands. 977*0b57cec5SDimitry Andric MI = MF.CreateMachineInstr(MCID, DebugLocation, /*NoImplicit=*/true); 978*0b57cec5SDimitry Andric MI->setFlags(Flags); 979*0b57cec5SDimitry Andric for (const auto &Operand : Operands) 980*0b57cec5SDimitry Andric MI->addOperand(MF, Operand.Operand); 981*0b57cec5SDimitry Andric if (assignRegisterTies(*MI, Operands)) 982*0b57cec5SDimitry Andric return true; 983*0b57cec5SDimitry Andric if (PreInstrSymbol) 984*0b57cec5SDimitry Andric MI->setPreInstrSymbol(MF, PreInstrSymbol); 985*0b57cec5SDimitry Andric if (PostInstrSymbol) 986*0b57cec5SDimitry Andric MI->setPostInstrSymbol(MF, PostInstrSymbol); 987*0b57cec5SDimitry Andric if (!MemOperands.empty()) 988*0b57cec5SDimitry Andric MI->setMemRefs(MF, MemOperands); 989*0b57cec5SDimitry Andric return false; 990*0b57cec5SDimitry Andric } 991*0b57cec5SDimitry Andric 992*0b57cec5SDimitry Andric bool MIParser::parseStandaloneMBB(MachineBasicBlock *&MBB) { 993*0b57cec5SDimitry Andric lex(); 994*0b57cec5SDimitry Andric if (Token.isNot(MIToken::MachineBasicBlock)) 995*0b57cec5SDimitry Andric return error("expected a machine basic block reference"); 996*0b57cec5SDimitry Andric if (parseMBBReference(MBB)) 997*0b57cec5SDimitry Andric return true; 998*0b57cec5SDimitry Andric lex(); 999*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof)) 1000*0b57cec5SDimitry Andric return error( 1001*0b57cec5SDimitry Andric "expected end of string after the machine basic block reference"); 1002*0b57cec5SDimitry Andric return false; 1003*0b57cec5SDimitry Andric } 1004*0b57cec5SDimitry Andric 1005*0b57cec5SDimitry Andric bool MIParser::parseStandaloneNamedRegister(unsigned &Reg) { 1006*0b57cec5SDimitry Andric lex(); 1007*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister)) 1008*0b57cec5SDimitry Andric return error("expected a named register"); 1009*0b57cec5SDimitry Andric if (parseNamedRegister(Reg)) 1010*0b57cec5SDimitry Andric return true; 1011*0b57cec5SDimitry Andric lex(); 1012*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof)) 1013*0b57cec5SDimitry Andric return error("expected end of string after the register reference"); 1014*0b57cec5SDimitry Andric return false; 1015*0b57cec5SDimitry Andric } 1016*0b57cec5SDimitry Andric 1017*0b57cec5SDimitry Andric bool MIParser::parseStandaloneVirtualRegister(VRegInfo *&Info) { 1018*0b57cec5SDimitry Andric lex(); 1019*0b57cec5SDimitry Andric if (Token.isNot(MIToken::VirtualRegister)) 1020*0b57cec5SDimitry Andric return error("expected a virtual register"); 1021*0b57cec5SDimitry Andric if (parseVirtualRegister(Info)) 1022*0b57cec5SDimitry Andric return true; 1023*0b57cec5SDimitry Andric lex(); 1024*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof)) 1025*0b57cec5SDimitry Andric return error("expected end of string after the register reference"); 1026*0b57cec5SDimitry Andric return false; 1027*0b57cec5SDimitry Andric } 1028*0b57cec5SDimitry Andric 1029*0b57cec5SDimitry Andric bool MIParser::parseStandaloneRegister(unsigned &Reg) { 1030*0b57cec5SDimitry Andric lex(); 1031*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister) && 1032*0b57cec5SDimitry Andric Token.isNot(MIToken::VirtualRegister)) 1033*0b57cec5SDimitry Andric return error("expected either a named or virtual register"); 1034*0b57cec5SDimitry Andric 1035*0b57cec5SDimitry Andric VRegInfo *Info; 1036*0b57cec5SDimitry Andric if (parseRegister(Reg, Info)) 1037*0b57cec5SDimitry Andric return true; 1038*0b57cec5SDimitry Andric 1039*0b57cec5SDimitry Andric lex(); 1040*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof)) 1041*0b57cec5SDimitry Andric return error("expected end of string after the register reference"); 1042*0b57cec5SDimitry Andric return false; 1043*0b57cec5SDimitry Andric } 1044*0b57cec5SDimitry Andric 1045*0b57cec5SDimitry Andric bool MIParser::parseStandaloneStackObject(int &FI) { 1046*0b57cec5SDimitry Andric lex(); 1047*0b57cec5SDimitry Andric if (Token.isNot(MIToken::StackObject)) 1048*0b57cec5SDimitry Andric return error("expected a stack object"); 1049*0b57cec5SDimitry Andric if (parseStackFrameIndex(FI)) 1050*0b57cec5SDimitry Andric return true; 1051*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof)) 1052*0b57cec5SDimitry Andric return error("expected end of string after the stack object reference"); 1053*0b57cec5SDimitry Andric return false; 1054*0b57cec5SDimitry Andric } 1055*0b57cec5SDimitry Andric 1056*0b57cec5SDimitry Andric bool MIParser::parseStandaloneMDNode(MDNode *&Node) { 1057*0b57cec5SDimitry Andric lex(); 1058*0b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) { 1059*0b57cec5SDimitry Andric if (parseMDNode(Node)) 1060*0b57cec5SDimitry Andric return true; 1061*0b57cec5SDimitry Andric } else if (Token.is(MIToken::md_diexpr)) { 1062*0b57cec5SDimitry Andric if (parseDIExpression(Node)) 1063*0b57cec5SDimitry Andric return true; 1064*0b57cec5SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) { 1065*0b57cec5SDimitry Andric if (parseDILocation(Node)) 1066*0b57cec5SDimitry Andric return true; 1067*0b57cec5SDimitry Andric } else 1068*0b57cec5SDimitry Andric return error("expected a metadata node"); 1069*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Eof)) 1070*0b57cec5SDimitry Andric return error("expected end of string after the metadata node"); 1071*0b57cec5SDimitry Andric return false; 1072*0b57cec5SDimitry Andric } 1073*0b57cec5SDimitry Andric 1074*0b57cec5SDimitry Andric static const char *printImplicitRegisterFlag(const MachineOperand &MO) { 1075*0b57cec5SDimitry Andric assert(MO.isImplicit()); 1076*0b57cec5SDimitry Andric return MO.isDef() ? "implicit-def" : "implicit"; 1077*0b57cec5SDimitry Andric } 1078*0b57cec5SDimitry Andric 1079*0b57cec5SDimitry Andric static std::string getRegisterName(const TargetRegisterInfo *TRI, 1080*0b57cec5SDimitry Andric unsigned Reg) { 1081*0b57cec5SDimitry Andric assert(TargetRegisterInfo::isPhysicalRegister(Reg) && "expected phys reg"); 1082*0b57cec5SDimitry Andric return StringRef(TRI->getName(Reg)).lower(); 1083*0b57cec5SDimitry Andric } 1084*0b57cec5SDimitry Andric 1085*0b57cec5SDimitry Andric /// Return true if the parsed machine operands contain a given machine operand. 1086*0b57cec5SDimitry Andric static bool isImplicitOperandIn(const MachineOperand &ImplicitOperand, 1087*0b57cec5SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) { 1088*0b57cec5SDimitry Andric for (const auto &I : Operands) { 1089*0b57cec5SDimitry Andric if (ImplicitOperand.isIdenticalTo(I.Operand)) 1090*0b57cec5SDimitry Andric return true; 1091*0b57cec5SDimitry Andric } 1092*0b57cec5SDimitry Andric return false; 1093*0b57cec5SDimitry Andric } 1094*0b57cec5SDimitry Andric 1095*0b57cec5SDimitry Andric bool MIParser::verifyImplicitOperands(ArrayRef<ParsedMachineOperand> Operands, 1096*0b57cec5SDimitry Andric const MCInstrDesc &MCID) { 1097*0b57cec5SDimitry Andric if (MCID.isCall()) 1098*0b57cec5SDimitry Andric // We can't verify call instructions as they can contain arbitrary implicit 1099*0b57cec5SDimitry Andric // register and register mask operands. 1100*0b57cec5SDimitry Andric return false; 1101*0b57cec5SDimitry Andric 1102*0b57cec5SDimitry Andric // Gather all the expected implicit operands. 1103*0b57cec5SDimitry Andric SmallVector<MachineOperand, 4> ImplicitOperands; 1104*0b57cec5SDimitry Andric if (MCID.ImplicitDefs) 1105*0b57cec5SDimitry Andric for (const MCPhysReg *ImpDefs = MCID.getImplicitDefs(); *ImpDefs; ++ImpDefs) 1106*0b57cec5SDimitry Andric ImplicitOperands.push_back( 1107*0b57cec5SDimitry Andric MachineOperand::CreateReg(*ImpDefs, true, true)); 1108*0b57cec5SDimitry Andric if (MCID.ImplicitUses) 1109*0b57cec5SDimitry Andric for (const MCPhysReg *ImpUses = MCID.getImplicitUses(); *ImpUses; ++ImpUses) 1110*0b57cec5SDimitry Andric ImplicitOperands.push_back( 1111*0b57cec5SDimitry Andric MachineOperand::CreateReg(*ImpUses, false, true)); 1112*0b57cec5SDimitry Andric 1113*0b57cec5SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo(); 1114*0b57cec5SDimitry Andric assert(TRI && "Expected target register info"); 1115*0b57cec5SDimitry Andric for (const auto &I : ImplicitOperands) { 1116*0b57cec5SDimitry Andric if (isImplicitOperandIn(I, Operands)) 1117*0b57cec5SDimitry Andric continue; 1118*0b57cec5SDimitry Andric return error(Operands.empty() ? Token.location() : Operands.back().End, 1119*0b57cec5SDimitry Andric Twine("missing implicit register operand '") + 1120*0b57cec5SDimitry Andric printImplicitRegisterFlag(I) + " $" + 1121*0b57cec5SDimitry Andric getRegisterName(TRI, I.getReg()) + "'"); 1122*0b57cec5SDimitry Andric } 1123*0b57cec5SDimitry Andric return false; 1124*0b57cec5SDimitry Andric } 1125*0b57cec5SDimitry Andric 1126*0b57cec5SDimitry Andric bool MIParser::parseInstruction(unsigned &OpCode, unsigned &Flags) { 1127*0b57cec5SDimitry Andric // Allow frame and fast math flags for OPCODE 1128*0b57cec5SDimitry Andric while (Token.is(MIToken::kw_frame_setup) || 1129*0b57cec5SDimitry Andric Token.is(MIToken::kw_frame_destroy) || 1130*0b57cec5SDimitry Andric Token.is(MIToken::kw_nnan) || 1131*0b57cec5SDimitry Andric Token.is(MIToken::kw_ninf) || 1132*0b57cec5SDimitry Andric Token.is(MIToken::kw_nsz) || 1133*0b57cec5SDimitry Andric Token.is(MIToken::kw_arcp) || 1134*0b57cec5SDimitry Andric Token.is(MIToken::kw_contract) || 1135*0b57cec5SDimitry Andric Token.is(MIToken::kw_afn) || 1136*0b57cec5SDimitry Andric Token.is(MIToken::kw_reassoc) || 1137*0b57cec5SDimitry Andric Token.is(MIToken::kw_nuw) || 1138*0b57cec5SDimitry Andric Token.is(MIToken::kw_nsw) || 1139*0b57cec5SDimitry Andric Token.is(MIToken::kw_exact) || 1140*0b57cec5SDimitry Andric Token.is(MIToken::kw_fpexcept)) { 1141*0b57cec5SDimitry Andric // Mine frame and fast math flags 1142*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_frame_setup)) 1143*0b57cec5SDimitry Andric Flags |= MachineInstr::FrameSetup; 1144*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_frame_destroy)) 1145*0b57cec5SDimitry Andric Flags |= MachineInstr::FrameDestroy; 1146*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_nnan)) 1147*0b57cec5SDimitry Andric Flags |= MachineInstr::FmNoNans; 1148*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_ninf)) 1149*0b57cec5SDimitry Andric Flags |= MachineInstr::FmNoInfs; 1150*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_nsz)) 1151*0b57cec5SDimitry Andric Flags |= MachineInstr::FmNsz; 1152*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_arcp)) 1153*0b57cec5SDimitry Andric Flags |= MachineInstr::FmArcp; 1154*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_contract)) 1155*0b57cec5SDimitry Andric Flags |= MachineInstr::FmContract; 1156*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_afn)) 1157*0b57cec5SDimitry Andric Flags |= MachineInstr::FmAfn; 1158*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_reassoc)) 1159*0b57cec5SDimitry Andric Flags |= MachineInstr::FmReassoc; 1160*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_nuw)) 1161*0b57cec5SDimitry Andric Flags |= MachineInstr::NoUWrap; 1162*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_nsw)) 1163*0b57cec5SDimitry Andric Flags |= MachineInstr::NoSWrap; 1164*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_exact)) 1165*0b57cec5SDimitry Andric Flags |= MachineInstr::IsExact; 1166*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_fpexcept)) 1167*0b57cec5SDimitry Andric Flags |= MachineInstr::FPExcept; 1168*0b57cec5SDimitry Andric 1169*0b57cec5SDimitry Andric lex(); 1170*0b57cec5SDimitry Andric } 1171*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier)) 1172*0b57cec5SDimitry Andric return error("expected a machine instruction"); 1173*0b57cec5SDimitry Andric StringRef InstrName = Token.stringValue(); 1174*0b57cec5SDimitry Andric if (PFS.Target.parseInstrName(InstrName, OpCode)) 1175*0b57cec5SDimitry Andric return error(Twine("unknown machine instruction name '") + InstrName + "'"); 1176*0b57cec5SDimitry Andric lex(); 1177*0b57cec5SDimitry Andric return false; 1178*0b57cec5SDimitry Andric } 1179*0b57cec5SDimitry Andric 1180*0b57cec5SDimitry Andric bool MIParser::parseNamedRegister(unsigned &Reg) { 1181*0b57cec5SDimitry Andric assert(Token.is(MIToken::NamedRegister) && "Needs NamedRegister token"); 1182*0b57cec5SDimitry Andric StringRef Name = Token.stringValue(); 1183*0b57cec5SDimitry Andric if (PFS.Target.getRegisterByName(Name, Reg)) 1184*0b57cec5SDimitry Andric return error(Twine("unknown register name '") + Name + "'"); 1185*0b57cec5SDimitry Andric return false; 1186*0b57cec5SDimitry Andric } 1187*0b57cec5SDimitry Andric 1188*0b57cec5SDimitry Andric bool MIParser::parseNamedVirtualRegister(VRegInfo *&Info) { 1189*0b57cec5SDimitry Andric assert(Token.is(MIToken::NamedVirtualRegister) && "Expected NamedVReg token"); 1190*0b57cec5SDimitry Andric StringRef Name = Token.stringValue(); 1191*0b57cec5SDimitry Andric // TODO: Check that the VReg name is not the same as a physical register name. 1192*0b57cec5SDimitry Andric // If it is, then print a warning (when warnings are implemented). 1193*0b57cec5SDimitry Andric Info = &PFS.getVRegInfoNamed(Name); 1194*0b57cec5SDimitry Andric return false; 1195*0b57cec5SDimitry Andric } 1196*0b57cec5SDimitry Andric 1197*0b57cec5SDimitry Andric bool MIParser::parseVirtualRegister(VRegInfo *&Info) { 1198*0b57cec5SDimitry Andric if (Token.is(MIToken::NamedVirtualRegister)) 1199*0b57cec5SDimitry Andric return parseNamedVirtualRegister(Info); 1200*0b57cec5SDimitry Andric assert(Token.is(MIToken::VirtualRegister) && "Needs VirtualRegister token"); 1201*0b57cec5SDimitry Andric unsigned ID; 1202*0b57cec5SDimitry Andric if (getUnsigned(ID)) 1203*0b57cec5SDimitry Andric return true; 1204*0b57cec5SDimitry Andric Info = &PFS.getVRegInfo(ID); 1205*0b57cec5SDimitry Andric return false; 1206*0b57cec5SDimitry Andric } 1207*0b57cec5SDimitry Andric 1208*0b57cec5SDimitry Andric bool MIParser::parseRegister(unsigned &Reg, VRegInfo *&Info) { 1209*0b57cec5SDimitry Andric switch (Token.kind()) { 1210*0b57cec5SDimitry Andric case MIToken::underscore: 1211*0b57cec5SDimitry Andric Reg = 0; 1212*0b57cec5SDimitry Andric return false; 1213*0b57cec5SDimitry Andric case MIToken::NamedRegister: 1214*0b57cec5SDimitry Andric return parseNamedRegister(Reg); 1215*0b57cec5SDimitry Andric case MIToken::NamedVirtualRegister: 1216*0b57cec5SDimitry Andric case MIToken::VirtualRegister: 1217*0b57cec5SDimitry Andric if (parseVirtualRegister(Info)) 1218*0b57cec5SDimitry Andric return true; 1219*0b57cec5SDimitry Andric Reg = Info->VReg; 1220*0b57cec5SDimitry Andric return false; 1221*0b57cec5SDimitry Andric // TODO: Parse other register kinds. 1222*0b57cec5SDimitry Andric default: 1223*0b57cec5SDimitry Andric llvm_unreachable("The current token should be a register"); 1224*0b57cec5SDimitry Andric } 1225*0b57cec5SDimitry Andric } 1226*0b57cec5SDimitry Andric 1227*0b57cec5SDimitry Andric bool MIParser::parseRegisterClassOrBank(VRegInfo &RegInfo) { 1228*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) && Token.isNot(MIToken::underscore)) 1229*0b57cec5SDimitry Andric return error("expected '_', register class, or register bank name"); 1230*0b57cec5SDimitry Andric StringRef::iterator Loc = Token.location(); 1231*0b57cec5SDimitry Andric StringRef Name = Token.stringValue(); 1232*0b57cec5SDimitry Andric 1233*0b57cec5SDimitry Andric // Was it a register class? 1234*0b57cec5SDimitry Andric const TargetRegisterClass *RC = PFS.Target.getRegClass(Name); 1235*0b57cec5SDimitry Andric if (RC) { 1236*0b57cec5SDimitry Andric lex(); 1237*0b57cec5SDimitry Andric 1238*0b57cec5SDimitry Andric switch (RegInfo.Kind) { 1239*0b57cec5SDimitry Andric case VRegInfo::UNKNOWN: 1240*0b57cec5SDimitry Andric case VRegInfo::NORMAL: 1241*0b57cec5SDimitry Andric RegInfo.Kind = VRegInfo::NORMAL; 1242*0b57cec5SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RC != RC) { 1243*0b57cec5SDimitry Andric const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 1244*0b57cec5SDimitry Andric return error(Loc, Twine("conflicting register classes, previously: ") + 1245*0b57cec5SDimitry Andric Twine(TRI.getRegClassName(RegInfo.D.RC))); 1246*0b57cec5SDimitry Andric } 1247*0b57cec5SDimitry Andric RegInfo.D.RC = RC; 1248*0b57cec5SDimitry Andric RegInfo.Explicit = true; 1249*0b57cec5SDimitry Andric return false; 1250*0b57cec5SDimitry Andric 1251*0b57cec5SDimitry Andric case VRegInfo::GENERIC: 1252*0b57cec5SDimitry Andric case VRegInfo::REGBANK: 1253*0b57cec5SDimitry Andric return error(Loc, "register class specification on generic register"); 1254*0b57cec5SDimitry Andric } 1255*0b57cec5SDimitry Andric llvm_unreachable("Unexpected register kind"); 1256*0b57cec5SDimitry Andric } 1257*0b57cec5SDimitry Andric 1258*0b57cec5SDimitry Andric // Should be a register bank or a generic register. 1259*0b57cec5SDimitry Andric const RegisterBank *RegBank = nullptr; 1260*0b57cec5SDimitry Andric if (Name != "_") { 1261*0b57cec5SDimitry Andric RegBank = PFS.Target.getRegBank(Name); 1262*0b57cec5SDimitry Andric if (!RegBank) 1263*0b57cec5SDimitry Andric return error(Loc, "expected '_', register class, or register bank name"); 1264*0b57cec5SDimitry Andric } 1265*0b57cec5SDimitry Andric 1266*0b57cec5SDimitry Andric lex(); 1267*0b57cec5SDimitry Andric 1268*0b57cec5SDimitry Andric switch (RegInfo.Kind) { 1269*0b57cec5SDimitry Andric case VRegInfo::UNKNOWN: 1270*0b57cec5SDimitry Andric case VRegInfo::GENERIC: 1271*0b57cec5SDimitry Andric case VRegInfo::REGBANK: 1272*0b57cec5SDimitry Andric RegInfo.Kind = RegBank ? VRegInfo::REGBANK : VRegInfo::GENERIC; 1273*0b57cec5SDimitry Andric if (RegInfo.Explicit && RegInfo.D.RegBank != RegBank) 1274*0b57cec5SDimitry Andric return error(Loc, "conflicting generic register banks"); 1275*0b57cec5SDimitry Andric RegInfo.D.RegBank = RegBank; 1276*0b57cec5SDimitry Andric RegInfo.Explicit = true; 1277*0b57cec5SDimitry Andric return false; 1278*0b57cec5SDimitry Andric 1279*0b57cec5SDimitry Andric case VRegInfo::NORMAL: 1280*0b57cec5SDimitry Andric return error(Loc, "register bank specification on normal register"); 1281*0b57cec5SDimitry Andric } 1282*0b57cec5SDimitry Andric llvm_unreachable("Unexpected register kind"); 1283*0b57cec5SDimitry Andric } 1284*0b57cec5SDimitry Andric 1285*0b57cec5SDimitry Andric bool MIParser::parseRegisterFlag(unsigned &Flags) { 1286*0b57cec5SDimitry Andric const unsigned OldFlags = Flags; 1287*0b57cec5SDimitry Andric switch (Token.kind()) { 1288*0b57cec5SDimitry Andric case MIToken::kw_implicit: 1289*0b57cec5SDimitry Andric Flags |= RegState::Implicit; 1290*0b57cec5SDimitry Andric break; 1291*0b57cec5SDimitry Andric case MIToken::kw_implicit_define: 1292*0b57cec5SDimitry Andric Flags |= RegState::ImplicitDefine; 1293*0b57cec5SDimitry Andric break; 1294*0b57cec5SDimitry Andric case MIToken::kw_def: 1295*0b57cec5SDimitry Andric Flags |= RegState::Define; 1296*0b57cec5SDimitry Andric break; 1297*0b57cec5SDimitry Andric case MIToken::kw_dead: 1298*0b57cec5SDimitry Andric Flags |= RegState::Dead; 1299*0b57cec5SDimitry Andric break; 1300*0b57cec5SDimitry Andric case MIToken::kw_killed: 1301*0b57cec5SDimitry Andric Flags |= RegState::Kill; 1302*0b57cec5SDimitry Andric break; 1303*0b57cec5SDimitry Andric case MIToken::kw_undef: 1304*0b57cec5SDimitry Andric Flags |= RegState::Undef; 1305*0b57cec5SDimitry Andric break; 1306*0b57cec5SDimitry Andric case MIToken::kw_internal: 1307*0b57cec5SDimitry Andric Flags |= RegState::InternalRead; 1308*0b57cec5SDimitry Andric break; 1309*0b57cec5SDimitry Andric case MIToken::kw_early_clobber: 1310*0b57cec5SDimitry Andric Flags |= RegState::EarlyClobber; 1311*0b57cec5SDimitry Andric break; 1312*0b57cec5SDimitry Andric case MIToken::kw_debug_use: 1313*0b57cec5SDimitry Andric Flags |= RegState::Debug; 1314*0b57cec5SDimitry Andric break; 1315*0b57cec5SDimitry Andric case MIToken::kw_renamable: 1316*0b57cec5SDimitry Andric Flags |= RegState::Renamable; 1317*0b57cec5SDimitry Andric break; 1318*0b57cec5SDimitry Andric default: 1319*0b57cec5SDimitry Andric llvm_unreachable("The current token should be a register flag"); 1320*0b57cec5SDimitry Andric } 1321*0b57cec5SDimitry Andric if (OldFlags == Flags) 1322*0b57cec5SDimitry Andric // We know that the same flag is specified more than once when the flags 1323*0b57cec5SDimitry Andric // weren't modified. 1324*0b57cec5SDimitry Andric return error("duplicate '" + Token.stringValue() + "' register flag"); 1325*0b57cec5SDimitry Andric lex(); 1326*0b57cec5SDimitry Andric return false; 1327*0b57cec5SDimitry Andric } 1328*0b57cec5SDimitry Andric 1329*0b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndex(unsigned &SubReg) { 1330*0b57cec5SDimitry Andric assert(Token.is(MIToken::dot)); 1331*0b57cec5SDimitry Andric lex(); 1332*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier)) 1333*0b57cec5SDimitry Andric return error("expected a subregister index after '.'"); 1334*0b57cec5SDimitry Andric auto Name = Token.stringValue(); 1335*0b57cec5SDimitry Andric SubReg = PFS.Target.getSubRegIndex(Name); 1336*0b57cec5SDimitry Andric if (!SubReg) 1337*0b57cec5SDimitry Andric return error(Twine("use of unknown subregister index '") + Name + "'"); 1338*0b57cec5SDimitry Andric lex(); 1339*0b57cec5SDimitry Andric return false; 1340*0b57cec5SDimitry Andric } 1341*0b57cec5SDimitry Andric 1342*0b57cec5SDimitry Andric bool MIParser::parseRegisterTiedDefIndex(unsigned &TiedDefIdx) { 1343*0b57cec5SDimitry Andric if (!consumeIfPresent(MIToken::kw_tied_def)) 1344*0b57cec5SDimitry Andric return true; 1345*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) 1346*0b57cec5SDimitry Andric return error("expected an integer literal after 'tied-def'"); 1347*0b57cec5SDimitry Andric if (getUnsigned(TiedDefIdx)) 1348*0b57cec5SDimitry Andric return true; 1349*0b57cec5SDimitry Andric lex(); 1350*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 1351*0b57cec5SDimitry Andric return true; 1352*0b57cec5SDimitry Andric return false; 1353*0b57cec5SDimitry Andric } 1354*0b57cec5SDimitry Andric 1355*0b57cec5SDimitry Andric bool MIParser::assignRegisterTies(MachineInstr &MI, 1356*0b57cec5SDimitry Andric ArrayRef<ParsedMachineOperand> Operands) { 1357*0b57cec5SDimitry Andric SmallVector<std::pair<unsigned, unsigned>, 4> TiedRegisterPairs; 1358*0b57cec5SDimitry Andric for (unsigned I = 0, E = Operands.size(); I != E; ++I) { 1359*0b57cec5SDimitry Andric if (!Operands[I].TiedDefIdx) 1360*0b57cec5SDimitry Andric continue; 1361*0b57cec5SDimitry Andric // The parser ensures that this operand is a register use, so we just have 1362*0b57cec5SDimitry Andric // to check the tied-def operand. 1363*0b57cec5SDimitry Andric unsigned DefIdx = Operands[I].TiedDefIdx.getValue(); 1364*0b57cec5SDimitry Andric if (DefIdx >= E) 1365*0b57cec5SDimitry Andric return error(Operands[I].Begin, 1366*0b57cec5SDimitry Andric Twine("use of invalid tied-def operand index '" + 1367*0b57cec5SDimitry Andric Twine(DefIdx) + "'; instruction has only ") + 1368*0b57cec5SDimitry Andric Twine(E) + " operands"); 1369*0b57cec5SDimitry Andric const auto &DefOperand = Operands[DefIdx].Operand; 1370*0b57cec5SDimitry Andric if (!DefOperand.isReg() || !DefOperand.isDef()) 1371*0b57cec5SDimitry Andric // FIXME: add note with the def operand. 1372*0b57cec5SDimitry Andric return error(Operands[I].Begin, 1373*0b57cec5SDimitry Andric Twine("use of invalid tied-def operand index '") + 1374*0b57cec5SDimitry Andric Twine(DefIdx) + "'; the operand #" + Twine(DefIdx) + 1375*0b57cec5SDimitry Andric " isn't a defined register"); 1376*0b57cec5SDimitry Andric // Check that the tied-def operand wasn't tied elsewhere. 1377*0b57cec5SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs) { 1378*0b57cec5SDimitry Andric if (TiedPair.first == DefIdx) 1379*0b57cec5SDimitry Andric return error(Operands[I].Begin, 1380*0b57cec5SDimitry Andric Twine("the tied-def operand #") + Twine(DefIdx) + 1381*0b57cec5SDimitry Andric " is already tied with another register operand"); 1382*0b57cec5SDimitry Andric } 1383*0b57cec5SDimitry Andric TiedRegisterPairs.push_back(std::make_pair(DefIdx, I)); 1384*0b57cec5SDimitry Andric } 1385*0b57cec5SDimitry Andric // FIXME: Verify that for non INLINEASM instructions, the def and use tied 1386*0b57cec5SDimitry Andric // indices must be less than tied max. 1387*0b57cec5SDimitry Andric for (const auto &TiedPair : TiedRegisterPairs) 1388*0b57cec5SDimitry Andric MI.tieOperands(TiedPair.first, TiedPair.second); 1389*0b57cec5SDimitry Andric return false; 1390*0b57cec5SDimitry Andric } 1391*0b57cec5SDimitry Andric 1392*0b57cec5SDimitry Andric bool MIParser::parseRegisterOperand(MachineOperand &Dest, 1393*0b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx, 1394*0b57cec5SDimitry Andric bool IsDef) { 1395*0b57cec5SDimitry Andric unsigned Flags = IsDef ? RegState::Define : 0; 1396*0b57cec5SDimitry Andric while (Token.isRegisterFlag()) { 1397*0b57cec5SDimitry Andric if (parseRegisterFlag(Flags)) 1398*0b57cec5SDimitry Andric return true; 1399*0b57cec5SDimitry Andric } 1400*0b57cec5SDimitry Andric if (!Token.isRegister()) 1401*0b57cec5SDimitry Andric return error("expected a register after register flags"); 1402*0b57cec5SDimitry Andric unsigned Reg; 1403*0b57cec5SDimitry Andric VRegInfo *RegInfo; 1404*0b57cec5SDimitry Andric if (parseRegister(Reg, RegInfo)) 1405*0b57cec5SDimitry Andric return true; 1406*0b57cec5SDimitry Andric lex(); 1407*0b57cec5SDimitry Andric unsigned SubReg = 0; 1408*0b57cec5SDimitry Andric if (Token.is(MIToken::dot)) { 1409*0b57cec5SDimitry Andric if (parseSubRegisterIndex(SubReg)) 1410*0b57cec5SDimitry Andric return true; 1411*0b57cec5SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 1412*0b57cec5SDimitry Andric return error("subregister index expects a virtual register"); 1413*0b57cec5SDimitry Andric } 1414*0b57cec5SDimitry Andric if (Token.is(MIToken::colon)) { 1415*0b57cec5SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 1416*0b57cec5SDimitry Andric return error("register class specification expects a virtual register"); 1417*0b57cec5SDimitry Andric lex(); 1418*0b57cec5SDimitry Andric if (parseRegisterClassOrBank(*RegInfo)) 1419*0b57cec5SDimitry Andric return true; 1420*0b57cec5SDimitry Andric } 1421*0b57cec5SDimitry Andric MachineRegisterInfo &MRI = MF.getRegInfo(); 1422*0b57cec5SDimitry Andric if ((Flags & RegState::Define) == 0) { 1423*0b57cec5SDimitry Andric if (consumeIfPresent(MIToken::lparen)) { 1424*0b57cec5SDimitry Andric unsigned Idx; 1425*0b57cec5SDimitry Andric if (!parseRegisterTiedDefIndex(Idx)) 1426*0b57cec5SDimitry Andric TiedDefIdx = Idx; 1427*0b57cec5SDimitry Andric else { 1428*0b57cec5SDimitry Andric // Try a redundant low-level type. 1429*0b57cec5SDimitry Andric LLT Ty; 1430*0b57cec5SDimitry Andric if (parseLowLevelType(Token.location(), Ty)) 1431*0b57cec5SDimitry Andric return error("expected tied-def or low-level type after '('"); 1432*0b57cec5SDimitry Andric 1433*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 1434*0b57cec5SDimitry Andric return true; 1435*0b57cec5SDimitry Andric 1436*0b57cec5SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) 1437*0b57cec5SDimitry Andric return error("inconsistent type for generic virtual register"); 1438*0b57cec5SDimitry Andric 1439*0b57cec5SDimitry Andric MRI.setType(Reg, Ty); 1440*0b57cec5SDimitry Andric } 1441*0b57cec5SDimitry Andric } 1442*0b57cec5SDimitry Andric } else if (consumeIfPresent(MIToken::lparen)) { 1443*0b57cec5SDimitry Andric // Virtual registers may have a tpe with GlobalISel. 1444*0b57cec5SDimitry Andric if (!TargetRegisterInfo::isVirtualRegister(Reg)) 1445*0b57cec5SDimitry Andric return error("unexpected type on physical register"); 1446*0b57cec5SDimitry Andric 1447*0b57cec5SDimitry Andric LLT Ty; 1448*0b57cec5SDimitry Andric if (parseLowLevelType(Token.location(), Ty)) 1449*0b57cec5SDimitry Andric return true; 1450*0b57cec5SDimitry Andric 1451*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 1452*0b57cec5SDimitry Andric return true; 1453*0b57cec5SDimitry Andric 1454*0b57cec5SDimitry Andric if (MRI.getType(Reg).isValid() && MRI.getType(Reg) != Ty) 1455*0b57cec5SDimitry Andric return error("inconsistent type for generic virtual register"); 1456*0b57cec5SDimitry Andric 1457*0b57cec5SDimitry Andric MRI.setType(Reg, Ty); 1458*0b57cec5SDimitry Andric } else if (TargetRegisterInfo::isVirtualRegister(Reg)) { 1459*0b57cec5SDimitry Andric // Generic virtual registers must have a type. 1460*0b57cec5SDimitry Andric // If we end up here this means the type hasn't been specified and 1461*0b57cec5SDimitry Andric // this is bad! 1462*0b57cec5SDimitry Andric if (RegInfo->Kind == VRegInfo::GENERIC || 1463*0b57cec5SDimitry Andric RegInfo->Kind == VRegInfo::REGBANK) 1464*0b57cec5SDimitry Andric return error("generic virtual registers must have a type"); 1465*0b57cec5SDimitry Andric } 1466*0b57cec5SDimitry Andric Dest = MachineOperand::CreateReg( 1467*0b57cec5SDimitry Andric Reg, Flags & RegState::Define, Flags & RegState::Implicit, 1468*0b57cec5SDimitry Andric Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef, 1469*0b57cec5SDimitry Andric Flags & RegState::EarlyClobber, SubReg, Flags & RegState::Debug, 1470*0b57cec5SDimitry Andric Flags & RegState::InternalRead, Flags & RegState::Renamable); 1471*0b57cec5SDimitry Andric 1472*0b57cec5SDimitry Andric return false; 1473*0b57cec5SDimitry Andric } 1474*0b57cec5SDimitry Andric 1475*0b57cec5SDimitry Andric bool MIParser::parseImmediateOperand(MachineOperand &Dest) { 1476*0b57cec5SDimitry Andric assert(Token.is(MIToken::IntegerLiteral)); 1477*0b57cec5SDimitry Andric const APSInt &Int = Token.integerValue(); 1478*0b57cec5SDimitry Andric if (Int.getMinSignedBits() > 64) 1479*0b57cec5SDimitry Andric return error("integer literal is too large to be an immediate operand"); 1480*0b57cec5SDimitry Andric Dest = MachineOperand::CreateImm(Int.getExtValue()); 1481*0b57cec5SDimitry Andric lex(); 1482*0b57cec5SDimitry Andric return false; 1483*0b57cec5SDimitry Andric } 1484*0b57cec5SDimitry Andric 1485*0b57cec5SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, StringRef StringValue, 1486*0b57cec5SDimitry Andric const Constant *&C) { 1487*0b57cec5SDimitry Andric auto Source = StringValue.str(); // The source has to be null terminated. 1488*0b57cec5SDimitry Andric SMDiagnostic Err; 1489*0b57cec5SDimitry Andric C = parseConstantValue(Source, Err, *MF.getFunction().getParent(), 1490*0b57cec5SDimitry Andric &PFS.IRSlots); 1491*0b57cec5SDimitry Andric if (!C) 1492*0b57cec5SDimitry Andric return error(Loc + Err.getColumnNo(), Err.getMessage()); 1493*0b57cec5SDimitry Andric return false; 1494*0b57cec5SDimitry Andric } 1495*0b57cec5SDimitry Andric 1496*0b57cec5SDimitry Andric bool MIParser::parseIRConstant(StringRef::iterator Loc, const Constant *&C) { 1497*0b57cec5SDimitry Andric if (parseIRConstant(Loc, StringRef(Loc, Token.range().end() - Loc), C)) 1498*0b57cec5SDimitry Andric return true; 1499*0b57cec5SDimitry Andric lex(); 1500*0b57cec5SDimitry Andric return false; 1501*0b57cec5SDimitry Andric } 1502*0b57cec5SDimitry Andric 1503*0b57cec5SDimitry Andric // See LLT implemntation for bit size limits. 1504*0b57cec5SDimitry Andric static bool verifyScalarSize(uint64_t Size) { 1505*0b57cec5SDimitry Andric return Size != 0 && isUInt<16>(Size); 1506*0b57cec5SDimitry Andric } 1507*0b57cec5SDimitry Andric 1508*0b57cec5SDimitry Andric static bool verifyVectorElementCount(uint64_t NumElts) { 1509*0b57cec5SDimitry Andric return NumElts != 0 && isUInt<16>(NumElts); 1510*0b57cec5SDimitry Andric } 1511*0b57cec5SDimitry Andric 1512*0b57cec5SDimitry Andric static bool verifyAddrSpace(uint64_t AddrSpace) { 1513*0b57cec5SDimitry Andric return isUInt<24>(AddrSpace); 1514*0b57cec5SDimitry Andric } 1515*0b57cec5SDimitry Andric 1516*0b57cec5SDimitry Andric bool MIParser::parseLowLevelType(StringRef::iterator Loc, LLT &Ty) { 1517*0b57cec5SDimitry Andric if (Token.range().front() == 's' || Token.range().front() == 'p') { 1518*0b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front(); 1519*0b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) 1520*0b57cec5SDimitry Andric return error("expected integers after 's'/'p' type character"); 1521*0b57cec5SDimitry Andric } 1522*0b57cec5SDimitry Andric 1523*0b57cec5SDimitry Andric if (Token.range().front() == 's') { 1524*0b57cec5SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue(); 1525*0b57cec5SDimitry Andric if (!verifyScalarSize(ScalarSize)) 1526*0b57cec5SDimitry Andric return error("invalid size for scalar type"); 1527*0b57cec5SDimitry Andric 1528*0b57cec5SDimitry Andric Ty = LLT::scalar(ScalarSize); 1529*0b57cec5SDimitry Andric lex(); 1530*0b57cec5SDimitry Andric return false; 1531*0b57cec5SDimitry Andric } else if (Token.range().front() == 'p') { 1532*0b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 1533*0b57cec5SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue(); 1534*0b57cec5SDimitry Andric if (!verifyAddrSpace(AS)) 1535*0b57cec5SDimitry Andric return error("invalid address space number"); 1536*0b57cec5SDimitry Andric 1537*0b57cec5SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); 1538*0b57cec5SDimitry Andric lex(); 1539*0b57cec5SDimitry Andric return false; 1540*0b57cec5SDimitry Andric } 1541*0b57cec5SDimitry Andric 1542*0b57cec5SDimitry Andric // Now we're looking for a vector. 1543*0b57cec5SDimitry Andric if (Token.isNot(MIToken::less)) 1544*0b57cec5SDimitry Andric return error(Loc, 1545*0b57cec5SDimitry Andric "expected sN, pA, <M x sN>, or <M x pA> for GlobalISel type"); 1546*0b57cec5SDimitry Andric lex(); 1547*0b57cec5SDimitry Andric 1548*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) 1549*0b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type"); 1550*0b57cec5SDimitry Andric uint64_t NumElements = Token.integerValue().getZExtValue(); 1551*0b57cec5SDimitry Andric if (!verifyVectorElementCount(NumElements)) 1552*0b57cec5SDimitry Andric return error("invalid number of vector elements"); 1553*0b57cec5SDimitry Andric 1554*0b57cec5SDimitry Andric lex(); 1555*0b57cec5SDimitry Andric 1556*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) || Token.stringValue() != "x") 1557*0b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type"); 1558*0b57cec5SDimitry Andric lex(); 1559*0b57cec5SDimitry Andric 1560*0b57cec5SDimitry Andric if (Token.range().front() != 's' && Token.range().front() != 'p') 1561*0b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type"); 1562*0b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front(); 1563*0b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) 1564*0b57cec5SDimitry Andric return error("expected integers after 's'/'p' type character"); 1565*0b57cec5SDimitry Andric 1566*0b57cec5SDimitry Andric if (Token.range().front() == 's') { 1567*0b57cec5SDimitry Andric auto ScalarSize = APSInt(Token.range().drop_front()).getZExtValue(); 1568*0b57cec5SDimitry Andric if (!verifyScalarSize(ScalarSize)) 1569*0b57cec5SDimitry Andric return error("invalid size for scalar type"); 1570*0b57cec5SDimitry Andric Ty = LLT::scalar(ScalarSize); 1571*0b57cec5SDimitry Andric } else if (Token.range().front() == 'p') { 1572*0b57cec5SDimitry Andric const DataLayout &DL = MF.getDataLayout(); 1573*0b57cec5SDimitry Andric uint64_t AS = APSInt(Token.range().drop_front()).getZExtValue(); 1574*0b57cec5SDimitry Andric if (!verifyAddrSpace(AS)) 1575*0b57cec5SDimitry Andric return error("invalid address space number"); 1576*0b57cec5SDimitry Andric 1577*0b57cec5SDimitry Andric Ty = LLT::pointer(AS, DL.getPointerSizeInBits(AS)); 1578*0b57cec5SDimitry Andric } else 1579*0b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type"); 1580*0b57cec5SDimitry Andric lex(); 1581*0b57cec5SDimitry Andric 1582*0b57cec5SDimitry Andric if (Token.isNot(MIToken::greater)) 1583*0b57cec5SDimitry Andric return error(Loc, "expected <M x sN> or <M x pA> for vector type"); 1584*0b57cec5SDimitry Andric lex(); 1585*0b57cec5SDimitry Andric 1586*0b57cec5SDimitry Andric Ty = LLT::vector(NumElements, Ty); 1587*0b57cec5SDimitry Andric return false; 1588*0b57cec5SDimitry Andric } 1589*0b57cec5SDimitry Andric 1590*0b57cec5SDimitry Andric bool MIParser::parseTypedImmediateOperand(MachineOperand &Dest) { 1591*0b57cec5SDimitry Andric assert(Token.is(MIToken::Identifier)); 1592*0b57cec5SDimitry Andric StringRef TypeStr = Token.range(); 1593*0b57cec5SDimitry Andric if (TypeStr.front() != 'i' && TypeStr.front() != 's' && 1594*0b57cec5SDimitry Andric TypeStr.front() != 'p') 1595*0b57cec5SDimitry Andric return error( 1596*0b57cec5SDimitry Andric "a typed immediate operand should start with one of 'i', 's', or 'p'"); 1597*0b57cec5SDimitry Andric StringRef SizeStr = Token.range().drop_front(); 1598*0b57cec5SDimitry Andric if (SizeStr.size() == 0 || !llvm::all_of(SizeStr, isdigit)) 1599*0b57cec5SDimitry Andric return error("expected integers after 'i'/'s'/'p' type character"); 1600*0b57cec5SDimitry Andric 1601*0b57cec5SDimitry Andric auto Loc = Token.location(); 1602*0b57cec5SDimitry Andric lex(); 1603*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) { 1604*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) || 1605*0b57cec5SDimitry Andric !(Token.range() == "true" || Token.range() == "false")) 1606*0b57cec5SDimitry Andric return error("expected an integer literal"); 1607*0b57cec5SDimitry Andric } 1608*0b57cec5SDimitry Andric const Constant *C = nullptr; 1609*0b57cec5SDimitry Andric if (parseIRConstant(Loc, C)) 1610*0b57cec5SDimitry Andric return true; 1611*0b57cec5SDimitry Andric Dest = MachineOperand::CreateCImm(cast<ConstantInt>(C)); 1612*0b57cec5SDimitry Andric return false; 1613*0b57cec5SDimitry Andric } 1614*0b57cec5SDimitry Andric 1615*0b57cec5SDimitry Andric bool MIParser::parseFPImmediateOperand(MachineOperand &Dest) { 1616*0b57cec5SDimitry Andric auto Loc = Token.location(); 1617*0b57cec5SDimitry Andric lex(); 1618*0b57cec5SDimitry Andric if (Token.isNot(MIToken::FloatingPointLiteral) && 1619*0b57cec5SDimitry Andric Token.isNot(MIToken::HexLiteral)) 1620*0b57cec5SDimitry Andric return error("expected a floating point literal"); 1621*0b57cec5SDimitry Andric const Constant *C = nullptr; 1622*0b57cec5SDimitry Andric if (parseIRConstant(Loc, C)) 1623*0b57cec5SDimitry Andric return true; 1624*0b57cec5SDimitry Andric Dest = MachineOperand::CreateFPImm(cast<ConstantFP>(C)); 1625*0b57cec5SDimitry Andric return false; 1626*0b57cec5SDimitry Andric } 1627*0b57cec5SDimitry Andric 1628*0b57cec5SDimitry Andric bool MIParser::getUnsigned(unsigned &Result) { 1629*0b57cec5SDimitry Andric if (Token.hasIntegerValue()) { 1630*0b57cec5SDimitry Andric const uint64_t Limit = uint64_t(std::numeric_limits<unsigned>::max()) + 1; 1631*0b57cec5SDimitry Andric uint64_t Val64 = Token.integerValue().getLimitedValue(Limit); 1632*0b57cec5SDimitry Andric if (Val64 == Limit) 1633*0b57cec5SDimitry Andric return error("expected 32-bit integer (too large)"); 1634*0b57cec5SDimitry Andric Result = Val64; 1635*0b57cec5SDimitry Andric return false; 1636*0b57cec5SDimitry Andric } 1637*0b57cec5SDimitry Andric if (Token.is(MIToken::HexLiteral)) { 1638*0b57cec5SDimitry Andric APInt A; 1639*0b57cec5SDimitry Andric if (getHexUint(A)) 1640*0b57cec5SDimitry Andric return true; 1641*0b57cec5SDimitry Andric if (A.getBitWidth() > 32) 1642*0b57cec5SDimitry Andric return error("expected 32-bit integer (too large)"); 1643*0b57cec5SDimitry Andric Result = A.getZExtValue(); 1644*0b57cec5SDimitry Andric return false; 1645*0b57cec5SDimitry Andric } 1646*0b57cec5SDimitry Andric return true; 1647*0b57cec5SDimitry Andric } 1648*0b57cec5SDimitry Andric 1649*0b57cec5SDimitry Andric bool MIParser::parseMBBReference(MachineBasicBlock *&MBB) { 1650*0b57cec5SDimitry Andric assert(Token.is(MIToken::MachineBasicBlock) || 1651*0b57cec5SDimitry Andric Token.is(MIToken::MachineBasicBlockLabel)); 1652*0b57cec5SDimitry Andric unsigned Number; 1653*0b57cec5SDimitry Andric if (getUnsigned(Number)) 1654*0b57cec5SDimitry Andric return true; 1655*0b57cec5SDimitry Andric auto MBBInfo = PFS.MBBSlots.find(Number); 1656*0b57cec5SDimitry Andric if (MBBInfo == PFS.MBBSlots.end()) 1657*0b57cec5SDimitry Andric return error(Twine("use of undefined machine basic block #") + 1658*0b57cec5SDimitry Andric Twine(Number)); 1659*0b57cec5SDimitry Andric MBB = MBBInfo->second; 1660*0b57cec5SDimitry Andric // TODO: Only parse the name if it's a MachineBasicBlockLabel. Deprecate once 1661*0b57cec5SDimitry Andric // we drop the <irname> from the bb.<id>.<irname> format. 1662*0b57cec5SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != MBB->getName()) 1663*0b57cec5SDimitry Andric return error(Twine("the name of machine basic block #") + Twine(Number) + 1664*0b57cec5SDimitry Andric " isn't '" + Token.stringValue() + "'"); 1665*0b57cec5SDimitry Andric return false; 1666*0b57cec5SDimitry Andric } 1667*0b57cec5SDimitry Andric 1668*0b57cec5SDimitry Andric bool MIParser::parseMBBOperand(MachineOperand &Dest) { 1669*0b57cec5SDimitry Andric MachineBasicBlock *MBB; 1670*0b57cec5SDimitry Andric if (parseMBBReference(MBB)) 1671*0b57cec5SDimitry Andric return true; 1672*0b57cec5SDimitry Andric Dest = MachineOperand::CreateMBB(MBB); 1673*0b57cec5SDimitry Andric lex(); 1674*0b57cec5SDimitry Andric return false; 1675*0b57cec5SDimitry Andric } 1676*0b57cec5SDimitry Andric 1677*0b57cec5SDimitry Andric bool MIParser::parseStackFrameIndex(int &FI) { 1678*0b57cec5SDimitry Andric assert(Token.is(MIToken::StackObject)); 1679*0b57cec5SDimitry Andric unsigned ID; 1680*0b57cec5SDimitry Andric if (getUnsigned(ID)) 1681*0b57cec5SDimitry Andric return true; 1682*0b57cec5SDimitry Andric auto ObjectInfo = PFS.StackObjectSlots.find(ID); 1683*0b57cec5SDimitry Andric if (ObjectInfo == PFS.StackObjectSlots.end()) 1684*0b57cec5SDimitry Andric return error(Twine("use of undefined stack object '%stack.") + Twine(ID) + 1685*0b57cec5SDimitry Andric "'"); 1686*0b57cec5SDimitry Andric StringRef Name; 1687*0b57cec5SDimitry Andric if (const auto *Alloca = 1688*0b57cec5SDimitry Andric MF.getFrameInfo().getObjectAllocation(ObjectInfo->second)) 1689*0b57cec5SDimitry Andric Name = Alloca->getName(); 1690*0b57cec5SDimitry Andric if (!Token.stringValue().empty() && Token.stringValue() != Name) 1691*0b57cec5SDimitry Andric return error(Twine("the name of the stack object '%stack.") + Twine(ID) + 1692*0b57cec5SDimitry Andric "' isn't '" + Token.stringValue() + "'"); 1693*0b57cec5SDimitry Andric lex(); 1694*0b57cec5SDimitry Andric FI = ObjectInfo->second; 1695*0b57cec5SDimitry Andric return false; 1696*0b57cec5SDimitry Andric } 1697*0b57cec5SDimitry Andric 1698*0b57cec5SDimitry Andric bool MIParser::parseStackObjectOperand(MachineOperand &Dest) { 1699*0b57cec5SDimitry Andric int FI; 1700*0b57cec5SDimitry Andric if (parseStackFrameIndex(FI)) 1701*0b57cec5SDimitry Andric return true; 1702*0b57cec5SDimitry Andric Dest = MachineOperand::CreateFI(FI); 1703*0b57cec5SDimitry Andric return false; 1704*0b57cec5SDimitry Andric } 1705*0b57cec5SDimitry Andric 1706*0b57cec5SDimitry Andric bool MIParser::parseFixedStackFrameIndex(int &FI) { 1707*0b57cec5SDimitry Andric assert(Token.is(MIToken::FixedStackObject)); 1708*0b57cec5SDimitry Andric unsigned ID; 1709*0b57cec5SDimitry Andric if (getUnsigned(ID)) 1710*0b57cec5SDimitry Andric return true; 1711*0b57cec5SDimitry Andric auto ObjectInfo = PFS.FixedStackObjectSlots.find(ID); 1712*0b57cec5SDimitry Andric if (ObjectInfo == PFS.FixedStackObjectSlots.end()) 1713*0b57cec5SDimitry Andric return error(Twine("use of undefined fixed stack object '%fixed-stack.") + 1714*0b57cec5SDimitry Andric Twine(ID) + "'"); 1715*0b57cec5SDimitry Andric lex(); 1716*0b57cec5SDimitry Andric FI = ObjectInfo->second; 1717*0b57cec5SDimitry Andric return false; 1718*0b57cec5SDimitry Andric } 1719*0b57cec5SDimitry Andric 1720*0b57cec5SDimitry Andric bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) { 1721*0b57cec5SDimitry Andric int FI; 1722*0b57cec5SDimitry Andric if (parseFixedStackFrameIndex(FI)) 1723*0b57cec5SDimitry Andric return true; 1724*0b57cec5SDimitry Andric Dest = MachineOperand::CreateFI(FI); 1725*0b57cec5SDimitry Andric return false; 1726*0b57cec5SDimitry Andric } 1727*0b57cec5SDimitry Andric 1728*0b57cec5SDimitry Andric bool MIParser::parseGlobalValue(GlobalValue *&GV) { 1729*0b57cec5SDimitry Andric switch (Token.kind()) { 1730*0b57cec5SDimitry Andric case MIToken::NamedGlobalValue: { 1731*0b57cec5SDimitry Andric const Module *M = MF.getFunction().getParent(); 1732*0b57cec5SDimitry Andric GV = M->getNamedValue(Token.stringValue()); 1733*0b57cec5SDimitry Andric if (!GV) 1734*0b57cec5SDimitry Andric return error(Twine("use of undefined global value '") + Token.range() + 1735*0b57cec5SDimitry Andric "'"); 1736*0b57cec5SDimitry Andric break; 1737*0b57cec5SDimitry Andric } 1738*0b57cec5SDimitry Andric case MIToken::GlobalValue: { 1739*0b57cec5SDimitry Andric unsigned GVIdx; 1740*0b57cec5SDimitry Andric if (getUnsigned(GVIdx)) 1741*0b57cec5SDimitry Andric return true; 1742*0b57cec5SDimitry Andric if (GVIdx >= PFS.IRSlots.GlobalValues.size()) 1743*0b57cec5SDimitry Andric return error(Twine("use of undefined global value '@") + Twine(GVIdx) + 1744*0b57cec5SDimitry Andric "'"); 1745*0b57cec5SDimitry Andric GV = PFS.IRSlots.GlobalValues[GVIdx]; 1746*0b57cec5SDimitry Andric break; 1747*0b57cec5SDimitry Andric } 1748*0b57cec5SDimitry Andric default: 1749*0b57cec5SDimitry Andric llvm_unreachable("The current token should be a global value"); 1750*0b57cec5SDimitry Andric } 1751*0b57cec5SDimitry Andric return false; 1752*0b57cec5SDimitry Andric } 1753*0b57cec5SDimitry Andric 1754*0b57cec5SDimitry Andric bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) { 1755*0b57cec5SDimitry Andric GlobalValue *GV = nullptr; 1756*0b57cec5SDimitry Andric if (parseGlobalValue(GV)) 1757*0b57cec5SDimitry Andric return true; 1758*0b57cec5SDimitry Andric lex(); 1759*0b57cec5SDimitry Andric Dest = MachineOperand::CreateGA(GV, /*Offset=*/0); 1760*0b57cec5SDimitry Andric if (parseOperandsOffset(Dest)) 1761*0b57cec5SDimitry Andric return true; 1762*0b57cec5SDimitry Andric return false; 1763*0b57cec5SDimitry Andric } 1764*0b57cec5SDimitry Andric 1765*0b57cec5SDimitry Andric bool MIParser::parseConstantPoolIndexOperand(MachineOperand &Dest) { 1766*0b57cec5SDimitry Andric assert(Token.is(MIToken::ConstantPoolItem)); 1767*0b57cec5SDimitry Andric unsigned ID; 1768*0b57cec5SDimitry Andric if (getUnsigned(ID)) 1769*0b57cec5SDimitry Andric return true; 1770*0b57cec5SDimitry Andric auto ConstantInfo = PFS.ConstantPoolSlots.find(ID); 1771*0b57cec5SDimitry Andric if (ConstantInfo == PFS.ConstantPoolSlots.end()) 1772*0b57cec5SDimitry Andric return error("use of undefined constant '%const." + Twine(ID) + "'"); 1773*0b57cec5SDimitry Andric lex(); 1774*0b57cec5SDimitry Andric Dest = MachineOperand::CreateCPI(ID, /*Offset=*/0); 1775*0b57cec5SDimitry Andric if (parseOperandsOffset(Dest)) 1776*0b57cec5SDimitry Andric return true; 1777*0b57cec5SDimitry Andric return false; 1778*0b57cec5SDimitry Andric } 1779*0b57cec5SDimitry Andric 1780*0b57cec5SDimitry Andric bool MIParser::parseJumpTableIndexOperand(MachineOperand &Dest) { 1781*0b57cec5SDimitry Andric assert(Token.is(MIToken::JumpTableIndex)); 1782*0b57cec5SDimitry Andric unsigned ID; 1783*0b57cec5SDimitry Andric if (getUnsigned(ID)) 1784*0b57cec5SDimitry Andric return true; 1785*0b57cec5SDimitry Andric auto JumpTableEntryInfo = PFS.JumpTableSlots.find(ID); 1786*0b57cec5SDimitry Andric if (JumpTableEntryInfo == PFS.JumpTableSlots.end()) 1787*0b57cec5SDimitry Andric return error("use of undefined jump table '%jump-table." + Twine(ID) + "'"); 1788*0b57cec5SDimitry Andric lex(); 1789*0b57cec5SDimitry Andric Dest = MachineOperand::CreateJTI(JumpTableEntryInfo->second); 1790*0b57cec5SDimitry Andric return false; 1791*0b57cec5SDimitry Andric } 1792*0b57cec5SDimitry Andric 1793*0b57cec5SDimitry Andric bool MIParser::parseExternalSymbolOperand(MachineOperand &Dest) { 1794*0b57cec5SDimitry Andric assert(Token.is(MIToken::ExternalSymbol)); 1795*0b57cec5SDimitry Andric const char *Symbol = MF.createExternalSymbolName(Token.stringValue()); 1796*0b57cec5SDimitry Andric lex(); 1797*0b57cec5SDimitry Andric Dest = MachineOperand::CreateES(Symbol); 1798*0b57cec5SDimitry Andric if (parseOperandsOffset(Dest)) 1799*0b57cec5SDimitry Andric return true; 1800*0b57cec5SDimitry Andric return false; 1801*0b57cec5SDimitry Andric } 1802*0b57cec5SDimitry Andric 1803*0b57cec5SDimitry Andric bool MIParser::parseMCSymbolOperand(MachineOperand &Dest) { 1804*0b57cec5SDimitry Andric assert(Token.is(MIToken::MCSymbol)); 1805*0b57cec5SDimitry Andric MCSymbol *Symbol = getOrCreateMCSymbol(Token.stringValue()); 1806*0b57cec5SDimitry Andric lex(); 1807*0b57cec5SDimitry Andric Dest = MachineOperand::CreateMCSymbol(Symbol); 1808*0b57cec5SDimitry Andric if (parseOperandsOffset(Dest)) 1809*0b57cec5SDimitry Andric return true; 1810*0b57cec5SDimitry Andric return false; 1811*0b57cec5SDimitry Andric } 1812*0b57cec5SDimitry Andric 1813*0b57cec5SDimitry Andric bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) { 1814*0b57cec5SDimitry Andric assert(Token.is(MIToken::SubRegisterIndex)); 1815*0b57cec5SDimitry Andric StringRef Name = Token.stringValue(); 1816*0b57cec5SDimitry Andric unsigned SubRegIndex = PFS.Target.getSubRegIndex(Token.stringValue()); 1817*0b57cec5SDimitry Andric if (SubRegIndex == 0) 1818*0b57cec5SDimitry Andric return error(Twine("unknown subregister index '") + Name + "'"); 1819*0b57cec5SDimitry Andric lex(); 1820*0b57cec5SDimitry Andric Dest = MachineOperand::CreateImm(SubRegIndex); 1821*0b57cec5SDimitry Andric return false; 1822*0b57cec5SDimitry Andric } 1823*0b57cec5SDimitry Andric 1824*0b57cec5SDimitry Andric bool MIParser::parseMDNode(MDNode *&Node) { 1825*0b57cec5SDimitry Andric assert(Token.is(MIToken::exclaim)); 1826*0b57cec5SDimitry Andric 1827*0b57cec5SDimitry Andric auto Loc = Token.location(); 1828*0b57cec5SDimitry Andric lex(); 1829*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) 1830*0b57cec5SDimitry Andric return error("expected metadata id after '!'"); 1831*0b57cec5SDimitry Andric unsigned ID; 1832*0b57cec5SDimitry Andric if (getUnsigned(ID)) 1833*0b57cec5SDimitry Andric return true; 1834*0b57cec5SDimitry Andric auto NodeInfo = PFS.IRSlots.MetadataNodes.find(ID); 1835*0b57cec5SDimitry Andric if (NodeInfo == PFS.IRSlots.MetadataNodes.end()) 1836*0b57cec5SDimitry Andric return error(Loc, "use of undefined metadata '!" + Twine(ID) + "'"); 1837*0b57cec5SDimitry Andric lex(); 1838*0b57cec5SDimitry Andric Node = NodeInfo->second.get(); 1839*0b57cec5SDimitry Andric return false; 1840*0b57cec5SDimitry Andric } 1841*0b57cec5SDimitry Andric 1842*0b57cec5SDimitry Andric bool MIParser::parseDIExpression(MDNode *&Expr) { 1843*0b57cec5SDimitry Andric assert(Token.is(MIToken::md_diexpr)); 1844*0b57cec5SDimitry Andric lex(); 1845*0b57cec5SDimitry Andric 1846*0b57cec5SDimitry Andric // FIXME: Share this parsing with the IL parser. 1847*0b57cec5SDimitry Andric SmallVector<uint64_t, 8> Elements; 1848*0b57cec5SDimitry Andric 1849*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 1850*0b57cec5SDimitry Andric return true; 1851*0b57cec5SDimitry Andric 1852*0b57cec5SDimitry Andric if (Token.isNot(MIToken::rparen)) { 1853*0b57cec5SDimitry Andric do { 1854*0b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) { 1855*0b57cec5SDimitry Andric if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) { 1856*0b57cec5SDimitry Andric lex(); 1857*0b57cec5SDimitry Andric Elements.push_back(Op); 1858*0b57cec5SDimitry Andric continue; 1859*0b57cec5SDimitry Andric } 1860*0b57cec5SDimitry Andric if (unsigned Enc = dwarf::getAttributeEncoding(Token.stringValue())) { 1861*0b57cec5SDimitry Andric lex(); 1862*0b57cec5SDimitry Andric Elements.push_back(Enc); 1863*0b57cec5SDimitry Andric continue; 1864*0b57cec5SDimitry Andric } 1865*0b57cec5SDimitry Andric return error(Twine("invalid DWARF op '") + Token.stringValue() + "'"); 1866*0b57cec5SDimitry Andric } 1867*0b57cec5SDimitry Andric 1868*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || 1869*0b57cec5SDimitry Andric Token.integerValue().isSigned()) 1870*0b57cec5SDimitry Andric return error("expected unsigned integer"); 1871*0b57cec5SDimitry Andric 1872*0b57cec5SDimitry Andric auto &U = Token.integerValue(); 1873*0b57cec5SDimitry Andric if (U.ugt(UINT64_MAX)) 1874*0b57cec5SDimitry Andric return error("element too large, limit is " + Twine(UINT64_MAX)); 1875*0b57cec5SDimitry Andric Elements.push_back(U.getZExtValue()); 1876*0b57cec5SDimitry Andric lex(); 1877*0b57cec5SDimitry Andric 1878*0b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma)); 1879*0b57cec5SDimitry Andric } 1880*0b57cec5SDimitry Andric 1881*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 1882*0b57cec5SDimitry Andric return true; 1883*0b57cec5SDimitry Andric 1884*0b57cec5SDimitry Andric Expr = DIExpression::get(MF.getFunction().getContext(), Elements); 1885*0b57cec5SDimitry Andric return false; 1886*0b57cec5SDimitry Andric } 1887*0b57cec5SDimitry Andric 1888*0b57cec5SDimitry Andric bool MIParser::parseDILocation(MDNode *&Loc) { 1889*0b57cec5SDimitry Andric assert(Token.is(MIToken::md_dilocation)); 1890*0b57cec5SDimitry Andric lex(); 1891*0b57cec5SDimitry Andric 1892*0b57cec5SDimitry Andric bool HaveLine = false; 1893*0b57cec5SDimitry Andric unsigned Line = 0; 1894*0b57cec5SDimitry Andric unsigned Column = 0; 1895*0b57cec5SDimitry Andric MDNode *Scope = nullptr; 1896*0b57cec5SDimitry Andric MDNode *InlinedAt = nullptr; 1897*0b57cec5SDimitry Andric bool ImplicitCode = false; 1898*0b57cec5SDimitry Andric 1899*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 1900*0b57cec5SDimitry Andric return true; 1901*0b57cec5SDimitry Andric 1902*0b57cec5SDimitry Andric if (Token.isNot(MIToken::rparen)) { 1903*0b57cec5SDimitry Andric do { 1904*0b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) { 1905*0b57cec5SDimitry Andric if (Token.stringValue() == "line") { 1906*0b57cec5SDimitry Andric lex(); 1907*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 1908*0b57cec5SDimitry Andric return true; 1909*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || 1910*0b57cec5SDimitry Andric Token.integerValue().isSigned()) 1911*0b57cec5SDimitry Andric return error("expected unsigned integer"); 1912*0b57cec5SDimitry Andric Line = Token.integerValue().getZExtValue(); 1913*0b57cec5SDimitry Andric HaveLine = true; 1914*0b57cec5SDimitry Andric lex(); 1915*0b57cec5SDimitry Andric continue; 1916*0b57cec5SDimitry Andric } 1917*0b57cec5SDimitry Andric if (Token.stringValue() == "column") { 1918*0b57cec5SDimitry Andric lex(); 1919*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 1920*0b57cec5SDimitry Andric return true; 1921*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || 1922*0b57cec5SDimitry Andric Token.integerValue().isSigned()) 1923*0b57cec5SDimitry Andric return error("expected unsigned integer"); 1924*0b57cec5SDimitry Andric Column = Token.integerValue().getZExtValue(); 1925*0b57cec5SDimitry Andric lex(); 1926*0b57cec5SDimitry Andric continue; 1927*0b57cec5SDimitry Andric } 1928*0b57cec5SDimitry Andric if (Token.stringValue() == "scope") { 1929*0b57cec5SDimitry Andric lex(); 1930*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 1931*0b57cec5SDimitry Andric return true; 1932*0b57cec5SDimitry Andric if (parseMDNode(Scope)) 1933*0b57cec5SDimitry Andric return error("expected metadata node"); 1934*0b57cec5SDimitry Andric if (!isa<DIScope>(Scope)) 1935*0b57cec5SDimitry Andric return error("expected DIScope node"); 1936*0b57cec5SDimitry Andric continue; 1937*0b57cec5SDimitry Andric } 1938*0b57cec5SDimitry Andric if (Token.stringValue() == "inlinedAt") { 1939*0b57cec5SDimitry Andric lex(); 1940*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 1941*0b57cec5SDimitry Andric return true; 1942*0b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) { 1943*0b57cec5SDimitry Andric if (parseMDNode(InlinedAt)) 1944*0b57cec5SDimitry Andric return true; 1945*0b57cec5SDimitry Andric } else if (Token.is(MIToken::md_dilocation)) { 1946*0b57cec5SDimitry Andric if (parseDILocation(InlinedAt)) 1947*0b57cec5SDimitry Andric return true; 1948*0b57cec5SDimitry Andric } else 1949*0b57cec5SDimitry Andric return error("expected metadata node"); 1950*0b57cec5SDimitry Andric if (!isa<DILocation>(InlinedAt)) 1951*0b57cec5SDimitry Andric return error("expected DILocation node"); 1952*0b57cec5SDimitry Andric continue; 1953*0b57cec5SDimitry Andric } 1954*0b57cec5SDimitry Andric if (Token.stringValue() == "isImplicitCode") { 1955*0b57cec5SDimitry Andric lex(); 1956*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::colon)) 1957*0b57cec5SDimitry Andric return true; 1958*0b57cec5SDimitry Andric if (!Token.is(MIToken::Identifier)) 1959*0b57cec5SDimitry Andric return error("expected true/false"); 1960*0b57cec5SDimitry Andric // As far as I can see, we don't have any existing need for parsing 1961*0b57cec5SDimitry Andric // true/false in MIR yet. Do it ad-hoc until there's something else 1962*0b57cec5SDimitry Andric // that needs it. 1963*0b57cec5SDimitry Andric if (Token.stringValue() == "true") 1964*0b57cec5SDimitry Andric ImplicitCode = true; 1965*0b57cec5SDimitry Andric else if (Token.stringValue() == "false") 1966*0b57cec5SDimitry Andric ImplicitCode = false; 1967*0b57cec5SDimitry Andric else 1968*0b57cec5SDimitry Andric return error("expected true/false"); 1969*0b57cec5SDimitry Andric lex(); 1970*0b57cec5SDimitry Andric continue; 1971*0b57cec5SDimitry Andric } 1972*0b57cec5SDimitry Andric } 1973*0b57cec5SDimitry Andric return error(Twine("invalid DILocation argument '") + 1974*0b57cec5SDimitry Andric Token.stringValue() + "'"); 1975*0b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma)); 1976*0b57cec5SDimitry Andric } 1977*0b57cec5SDimitry Andric 1978*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 1979*0b57cec5SDimitry Andric return true; 1980*0b57cec5SDimitry Andric 1981*0b57cec5SDimitry Andric if (!HaveLine) 1982*0b57cec5SDimitry Andric return error("DILocation requires line number"); 1983*0b57cec5SDimitry Andric if (!Scope) 1984*0b57cec5SDimitry Andric return error("DILocation requires a scope"); 1985*0b57cec5SDimitry Andric 1986*0b57cec5SDimitry Andric Loc = DILocation::get(MF.getFunction().getContext(), Line, Column, Scope, 1987*0b57cec5SDimitry Andric InlinedAt, ImplicitCode); 1988*0b57cec5SDimitry Andric return false; 1989*0b57cec5SDimitry Andric } 1990*0b57cec5SDimitry Andric 1991*0b57cec5SDimitry Andric bool MIParser::parseMetadataOperand(MachineOperand &Dest) { 1992*0b57cec5SDimitry Andric MDNode *Node = nullptr; 1993*0b57cec5SDimitry Andric if (Token.is(MIToken::exclaim)) { 1994*0b57cec5SDimitry Andric if (parseMDNode(Node)) 1995*0b57cec5SDimitry Andric return true; 1996*0b57cec5SDimitry Andric } else if (Token.is(MIToken::md_diexpr)) { 1997*0b57cec5SDimitry Andric if (parseDIExpression(Node)) 1998*0b57cec5SDimitry Andric return true; 1999*0b57cec5SDimitry Andric } 2000*0b57cec5SDimitry Andric Dest = MachineOperand::CreateMetadata(Node); 2001*0b57cec5SDimitry Andric return false; 2002*0b57cec5SDimitry Andric } 2003*0b57cec5SDimitry Andric 2004*0b57cec5SDimitry Andric bool MIParser::parseCFIOffset(int &Offset) { 2005*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) 2006*0b57cec5SDimitry Andric return error("expected a cfi offset"); 2007*0b57cec5SDimitry Andric if (Token.integerValue().getMinSignedBits() > 32) 2008*0b57cec5SDimitry Andric return error("expected a 32 bit integer (the cfi offset is too large)"); 2009*0b57cec5SDimitry Andric Offset = (int)Token.integerValue().getExtValue(); 2010*0b57cec5SDimitry Andric lex(); 2011*0b57cec5SDimitry Andric return false; 2012*0b57cec5SDimitry Andric } 2013*0b57cec5SDimitry Andric 2014*0b57cec5SDimitry Andric bool MIParser::parseCFIRegister(unsigned &Reg) { 2015*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister)) 2016*0b57cec5SDimitry Andric return error("expected a cfi register"); 2017*0b57cec5SDimitry Andric unsigned LLVMReg; 2018*0b57cec5SDimitry Andric if (parseNamedRegister(LLVMReg)) 2019*0b57cec5SDimitry Andric return true; 2020*0b57cec5SDimitry Andric const auto *TRI = MF.getSubtarget().getRegisterInfo(); 2021*0b57cec5SDimitry Andric assert(TRI && "Expected target register info"); 2022*0b57cec5SDimitry Andric int DwarfReg = TRI->getDwarfRegNum(LLVMReg, true); 2023*0b57cec5SDimitry Andric if (DwarfReg < 0) 2024*0b57cec5SDimitry Andric return error("invalid DWARF register"); 2025*0b57cec5SDimitry Andric Reg = (unsigned)DwarfReg; 2026*0b57cec5SDimitry Andric lex(); 2027*0b57cec5SDimitry Andric return false; 2028*0b57cec5SDimitry Andric } 2029*0b57cec5SDimitry Andric 2030*0b57cec5SDimitry Andric bool MIParser::parseCFIEscapeValues(std::string &Values) { 2031*0b57cec5SDimitry Andric do { 2032*0b57cec5SDimitry Andric if (Token.isNot(MIToken::HexLiteral)) 2033*0b57cec5SDimitry Andric return error("expected a hexadecimal literal"); 2034*0b57cec5SDimitry Andric unsigned Value; 2035*0b57cec5SDimitry Andric if (getUnsigned(Value)) 2036*0b57cec5SDimitry Andric return true; 2037*0b57cec5SDimitry Andric if (Value > UINT8_MAX) 2038*0b57cec5SDimitry Andric return error("expected a 8-bit integer (too large)"); 2039*0b57cec5SDimitry Andric Values.push_back(static_cast<uint8_t>(Value)); 2040*0b57cec5SDimitry Andric lex(); 2041*0b57cec5SDimitry Andric } while (consumeIfPresent(MIToken::comma)); 2042*0b57cec5SDimitry Andric return false; 2043*0b57cec5SDimitry Andric } 2044*0b57cec5SDimitry Andric 2045*0b57cec5SDimitry Andric bool MIParser::parseCFIOperand(MachineOperand &Dest) { 2046*0b57cec5SDimitry Andric auto Kind = Token.kind(); 2047*0b57cec5SDimitry Andric lex(); 2048*0b57cec5SDimitry Andric int Offset; 2049*0b57cec5SDimitry Andric unsigned Reg; 2050*0b57cec5SDimitry Andric unsigned CFIIndex; 2051*0b57cec5SDimitry Andric switch (Kind) { 2052*0b57cec5SDimitry Andric case MIToken::kw_cfi_same_value: 2053*0b57cec5SDimitry Andric if (parseCFIRegister(Reg)) 2054*0b57cec5SDimitry Andric return true; 2055*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createSameValue(nullptr, Reg)); 2056*0b57cec5SDimitry Andric break; 2057*0b57cec5SDimitry Andric case MIToken::kw_cfi_offset: 2058*0b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || 2059*0b57cec5SDimitry Andric parseCFIOffset(Offset)) 2060*0b57cec5SDimitry Andric return true; 2061*0b57cec5SDimitry Andric CFIIndex = 2062*0b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, Reg, Offset)); 2063*0b57cec5SDimitry Andric break; 2064*0b57cec5SDimitry Andric case MIToken::kw_cfi_rel_offset: 2065*0b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || 2066*0b57cec5SDimitry Andric parseCFIOffset(Offset)) 2067*0b57cec5SDimitry Andric return true; 2068*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst( 2069*0b57cec5SDimitry Andric MCCFIInstruction::createRelOffset(nullptr, Reg, Offset)); 2070*0b57cec5SDimitry Andric break; 2071*0b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_register: 2072*0b57cec5SDimitry Andric if (parseCFIRegister(Reg)) 2073*0b57cec5SDimitry Andric return true; 2074*0b57cec5SDimitry Andric CFIIndex = 2075*0b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createDefCfaRegister(nullptr, Reg)); 2076*0b57cec5SDimitry Andric break; 2077*0b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_offset: 2078*0b57cec5SDimitry Andric if (parseCFIOffset(Offset)) 2079*0b57cec5SDimitry Andric return true; 2080*0b57cec5SDimitry Andric // NB: MCCFIInstruction::createDefCfaOffset negates the offset. 2081*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst( 2082*0b57cec5SDimitry Andric MCCFIInstruction::createDefCfaOffset(nullptr, -Offset)); 2083*0b57cec5SDimitry Andric break; 2084*0b57cec5SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset: 2085*0b57cec5SDimitry Andric if (parseCFIOffset(Offset)) 2086*0b57cec5SDimitry Andric return true; 2087*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst( 2088*0b57cec5SDimitry Andric MCCFIInstruction::createAdjustCfaOffset(nullptr, Offset)); 2089*0b57cec5SDimitry Andric break; 2090*0b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa: 2091*0b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || 2092*0b57cec5SDimitry Andric parseCFIOffset(Offset)) 2093*0b57cec5SDimitry Andric return true; 2094*0b57cec5SDimitry Andric // NB: MCCFIInstruction::createDefCfa negates the offset. 2095*0b57cec5SDimitry Andric CFIIndex = 2096*0b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createDefCfa(nullptr, Reg, -Offset)); 2097*0b57cec5SDimitry Andric break; 2098*0b57cec5SDimitry Andric case MIToken::kw_cfi_remember_state: 2099*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRememberState(nullptr)); 2100*0b57cec5SDimitry Andric break; 2101*0b57cec5SDimitry Andric case MIToken::kw_cfi_restore: 2102*0b57cec5SDimitry Andric if (parseCFIRegister(Reg)) 2103*0b57cec5SDimitry Andric return true; 2104*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestore(nullptr, Reg)); 2105*0b57cec5SDimitry Andric break; 2106*0b57cec5SDimitry Andric case MIToken::kw_cfi_restore_state: 2107*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createRestoreState(nullptr)); 2108*0b57cec5SDimitry Andric break; 2109*0b57cec5SDimitry Andric case MIToken::kw_cfi_undefined: 2110*0b57cec5SDimitry Andric if (parseCFIRegister(Reg)) 2111*0b57cec5SDimitry Andric return true; 2112*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createUndefined(nullptr, Reg)); 2113*0b57cec5SDimitry Andric break; 2114*0b57cec5SDimitry Andric case MIToken::kw_cfi_register: { 2115*0b57cec5SDimitry Andric unsigned Reg2; 2116*0b57cec5SDimitry Andric if (parseCFIRegister(Reg) || expectAndConsume(MIToken::comma) || 2117*0b57cec5SDimitry Andric parseCFIRegister(Reg2)) 2118*0b57cec5SDimitry Andric return true; 2119*0b57cec5SDimitry Andric 2120*0b57cec5SDimitry Andric CFIIndex = 2121*0b57cec5SDimitry Andric MF.addFrameInst(MCCFIInstruction::createRegister(nullptr, Reg, Reg2)); 2122*0b57cec5SDimitry Andric break; 2123*0b57cec5SDimitry Andric } 2124*0b57cec5SDimitry Andric case MIToken::kw_cfi_window_save: 2125*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createWindowSave(nullptr)); 2126*0b57cec5SDimitry Andric break; 2127*0b57cec5SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state: 2128*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); 2129*0b57cec5SDimitry Andric break; 2130*0b57cec5SDimitry Andric case MIToken::kw_cfi_escape: { 2131*0b57cec5SDimitry Andric std::string Values; 2132*0b57cec5SDimitry Andric if (parseCFIEscapeValues(Values)) 2133*0b57cec5SDimitry Andric return true; 2134*0b57cec5SDimitry Andric CFIIndex = MF.addFrameInst(MCCFIInstruction::createEscape(nullptr, Values)); 2135*0b57cec5SDimitry Andric break; 2136*0b57cec5SDimitry Andric } 2137*0b57cec5SDimitry Andric default: 2138*0b57cec5SDimitry Andric // TODO: Parse the other CFI operands. 2139*0b57cec5SDimitry Andric llvm_unreachable("The current token should be a cfi operand"); 2140*0b57cec5SDimitry Andric } 2141*0b57cec5SDimitry Andric Dest = MachineOperand::CreateCFIIndex(CFIIndex); 2142*0b57cec5SDimitry Andric return false; 2143*0b57cec5SDimitry Andric } 2144*0b57cec5SDimitry Andric 2145*0b57cec5SDimitry Andric bool MIParser::parseIRBlock(BasicBlock *&BB, const Function &F) { 2146*0b57cec5SDimitry Andric switch (Token.kind()) { 2147*0b57cec5SDimitry Andric case MIToken::NamedIRBlock: { 2148*0b57cec5SDimitry Andric BB = dyn_cast_or_null<BasicBlock>( 2149*0b57cec5SDimitry Andric F.getValueSymbolTable()->lookup(Token.stringValue())); 2150*0b57cec5SDimitry Andric if (!BB) 2151*0b57cec5SDimitry Andric return error(Twine("use of undefined IR block '") + Token.range() + "'"); 2152*0b57cec5SDimitry Andric break; 2153*0b57cec5SDimitry Andric } 2154*0b57cec5SDimitry Andric case MIToken::IRBlock: { 2155*0b57cec5SDimitry Andric unsigned SlotNumber = 0; 2156*0b57cec5SDimitry Andric if (getUnsigned(SlotNumber)) 2157*0b57cec5SDimitry Andric return true; 2158*0b57cec5SDimitry Andric BB = const_cast<BasicBlock *>(getIRBlock(SlotNumber, F)); 2159*0b57cec5SDimitry Andric if (!BB) 2160*0b57cec5SDimitry Andric return error(Twine("use of undefined IR block '%ir-block.") + 2161*0b57cec5SDimitry Andric Twine(SlotNumber) + "'"); 2162*0b57cec5SDimitry Andric break; 2163*0b57cec5SDimitry Andric } 2164*0b57cec5SDimitry Andric default: 2165*0b57cec5SDimitry Andric llvm_unreachable("The current token should be an IR block reference"); 2166*0b57cec5SDimitry Andric } 2167*0b57cec5SDimitry Andric return false; 2168*0b57cec5SDimitry Andric } 2169*0b57cec5SDimitry Andric 2170*0b57cec5SDimitry Andric bool MIParser::parseBlockAddressOperand(MachineOperand &Dest) { 2171*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_blockaddress)); 2172*0b57cec5SDimitry Andric lex(); 2173*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2174*0b57cec5SDimitry Andric return true; 2175*0b57cec5SDimitry Andric if (Token.isNot(MIToken::GlobalValue) && 2176*0b57cec5SDimitry Andric Token.isNot(MIToken::NamedGlobalValue)) 2177*0b57cec5SDimitry Andric return error("expected a global value"); 2178*0b57cec5SDimitry Andric GlobalValue *GV = nullptr; 2179*0b57cec5SDimitry Andric if (parseGlobalValue(GV)) 2180*0b57cec5SDimitry Andric return true; 2181*0b57cec5SDimitry Andric auto *F = dyn_cast<Function>(GV); 2182*0b57cec5SDimitry Andric if (!F) 2183*0b57cec5SDimitry Andric return error("expected an IR function reference"); 2184*0b57cec5SDimitry Andric lex(); 2185*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::comma)) 2186*0b57cec5SDimitry Andric return true; 2187*0b57cec5SDimitry Andric BasicBlock *BB = nullptr; 2188*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IRBlock) && Token.isNot(MIToken::NamedIRBlock)) 2189*0b57cec5SDimitry Andric return error("expected an IR block reference"); 2190*0b57cec5SDimitry Andric if (parseIRBlock(BB, *F)) 2191*0b57cec5SDimitry Andric return true; 2192*0b57cec5SDimitry Andric lex(); 2193*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2194*0b57cec5SDimitry Andric return true; 2195*0b57cec5SDimitry Andric Dest = MachineOperand::CreateBA(BlockAddress::get(F, BB), /*Offset=*/0); 2196*0b57cec5SDimitry Andric if (parseOperandsOffset(Dest)) 2197*0b57cec5SDimitry Andric return true; 2198*0b57cec5SDimitry Andric return false; 2199*0b57cec5SDimitry Andric } 2200*0b57cec5SDimitry Andric 2201*0b57cec5SDimitry Andric bool MIParser::parseIntrinsicOperand(MachineOperand &Dest) { 2202*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_intrinsic)); 2203*0b57cec5SDimitry Andric lex(); 2204*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2205*0b57cec5SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)"); 2206*0b57cec5SDimitry Andric 2207*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedGlobalValue)) 2208*0b57cec5SDimitry Andric return error("expected syntax intrinsic(@llvm.whatever)"); 2209*0b57cec5SDimitry Andric 2210*0b57cec5SDimitry Andric std::string Name = Token.stringValue(); 2211*0b57cec5SDimitry Andric lex(); 2212*0b57cec5SDimitry Andric 2213*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2214*0b57cec5SDimitry Andric return error("expected ')' to terminate intrinsic name"); 2215*0b57cec5SDimitry Andric 2216*0b57cec5SDimitry Andric // Find out what intrinsic we're dealing with, first try the global namespace 2217*0b57cec5SDimitry Andric // and then the target's private intrinsics if that fails. 2218*0b57cec5SDimitry Andric const TargetIntrinsicInfo *TII = MF.getTarget().getIntrinsicInfo(); 2219*0b57cec5SDimitry Andric Intrinsic::ID ID = Function::lookupIntrinsicID(Name); 2220*0b57cec5SDimitry Andric if (ID == Intrinsic::not_intrinsic && TII) 2221*0b57cec5SDimitry Andric ID = static_cast<Intrinsic::ID>(TII->lookupName(Name)); 2222*0b57cec5SDimitry Andric 2223*0b57cec5SDimitry Andric if (ID == Intrinsic::not_intrinsic) 2224*0b57cec5SDimitry Andric return error("unknown intrinsic name"); 2225*0b57cec5SDimitry Andric Dest = MachineOperand::CreateIntrinsicID(ID); 2226*0b57cec5SDimitry Andric 2227*0b57cec5SDimitry Andric return false; 2228*0b57cec5SDimitry Andric } 2229*0b57cec5SDimitry Andric 2230*0b57cec5SDimitry Andric bool MIParser::parsePredicateOperand(MachineOperand &Dest) { 2231*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_intpred) || Token.is(MIToken::kw_floatpred)); 2232*0b57cec5SDimitry Andric bool IsFloat = Token.is(MIToken::kw_floatpred); 2233*0b57cec5SDimitry Andric lex(); 2234*0b57cec5SDimitry Andric 2235*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2236*0b57cec5SDimitry Andric return error("expected syntax intpred(whatever) or floatpred(whatever"); 2237*0b57cec5SDimitry Andric 2238*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier)) 2239*0b57cec5SDimitry Andric return error("whatever"); 2240*0b57cec5SDimitry Andric 2241*0b57cec5SDimitry Andric CmpInst::Predicate Pred; 2242*0b57cec5SDimitry Andric if (IsFloat) { 2243*0b57cec5SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) 2244*0b57cec5SDimitry Andric .Case("false", CmpInst::FCMP_FALSE) 2245*0b57cec5SDimitry Andric .Case("oeq", CmpInst::FCMP_OEQ) 2246*0b57cec5SDimitry Andric .Case("ogt", CmpInst::FCMP_OGT) 2247*0b57cec5SDimitry Andric .Case("oge", CmpInst::FCMP_OGE) 2248*0b57cec5SDimitry Andric .Case("olt", CmpInst::FCMP_OLT) 2249*0b57cec5SDimitry Andric .Case("ole", CmpInst::FCMP_OLE) 2250*0b57cec5SDimitry Andric .Case("one", CmpInst::FCMP_ONE) 2251*0b57cec5SDimitry Andric .Case("ord", CmpInst::FCMP_ORD) 2252*0b57cec5SDimitry Andric .Case("uno", CmpInst::FCMP_UNO) 2253*0b57cec5SDimitry Andric .Case("ueq", CmpInst::FCMP_UEQ) 2254*0b57cec5SDimitry Andric .Case("ugt", CmpInst::FCMP_UGT) 2255*0b57cec5SDimitry Andric .Case("uge", CmpInst::FCMP_UGE) 2256*0b57cec5SDimitry Andric .Case("ult", CmpInst::FCMP_ULT) 2257*0b57cec5SDimitry Andric .Case("ule", CmpInst::FCMP_ULE) 2258*0b57cec5SDimitry Andric .Case("une", CmpInst::FCMP_UNE) 2259*0b57cec5SDimitry Andric .Case("true", CmpInst::FCMP_TRUE) 2260*0b57cec5SDimitry Andric .Default(CmpInst::BAD_FCMP_PREDICATE); 2261*0b57cec5SDimitry Andric if (!CmpInst::isFPPredicate(Pred)) 2262*0b57cec5SDimitry Andric return error("invalid floating-point predicate"); 2263*0b57cec5SDimitry Andric } else { 2264*0b57cec5SDimitry Andric Pred = StringSwitch<CmpInst::Predicate>(Token.stringValue()) 2265*0b57cec5SDimitry Andric .Case("eq", CmpInst::ICMP_EQ) 2266*0b57cec5SDimitry Andric .Case("ne", CmpInst::ICMP_NE) 2267*0b57cec5SDimitry Andric .Case("sgt", CmpInst::ICMP_SGT) 2268*0b57cec5SDimitry Andric .Case("sge", CmpInst::ICMP_SGE) 2269*0b57cec5SDimitry Andric .Case("slt", CmpInst::ICMP_SLT) 2270*0b57cec5SDimitry Andric .Case("sle", CmpInst::ICMP_SLE) 2271*0b57cec5SDimitry Andric .Case("ugt", CmpInst::ICMP_UGT) 2272*0b57cec5SDimitry Andric .Case("uge", CmpInst::ICMP_UGE) 2273*0b57cec5SDimitry Andric .Case("ult", CmpInst::ICMP_ULT) 2274*0b57cec5SDimitry Andric .Case("ule", CmpInst::ICMP_ULE) 2275*0b57cec5SDimitry Andric .Default(CmpInst::BAD_ICMP_PREDICATE); 2276*0b57cec5SDimitry Andric if (!CmpInst::isIntPredicate(Pred)) 2277*0b57cec5SDimitry Andric return error("invalid integer predicate"); 2278*0b57cec5SDimitry Andric } 2279*0b57cec5SDimitry Andric 2280*0b57cec5SDimitry Andric lex(); 2281*0b57cec5SDimitry Andric Dest = MachineOperand::CreatePredicate(Pred); 2282*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2283*0b57cec5SDimitry Andric return error("predicate should be terminated by ')'."); 2284*0b57cec5SDimitry Andric 2285*0b57cec5SDimitry Andric return false; 2286*0b57cec5SDimitry Andric } 2287*0b57cec5SDimitry Andric 2288*0b57cec5SDimitry Andric bool MIParser::parseTargetIndexOperand(MachineOperand &Dest) { 2289*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_target_index)); 2290*0b57cec5SDimitry Andric lex(); 2291*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2292*0b57cec5SDimitry Andric return true; 2293*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier)) 2294*0b57cec5SDimitry Andric return error("expected the name of the target index"); 2295*0b57cec5SDimitry Andric int Index = 0; 2296*0b57cec5SDimitry Andric if (PFS.Target.getTargetIndex(Token.stringValue(), Index)) 2297*0b57cec5SDimitry Andric return error("use of undefined target index '" + Token.stringValue() + "'"); 2298*0b57cec5SDimitry Andric lex(); 2299*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2300*0b57cec5SDimitry Andric return true; 2301*0b57cec5SDimitry Andric Dest = MachineOperand::CreateTargetIndex(unsigned(Index), /*Offset=*/0); 2302*0b57cec5SDimitry Andric if (parseOperandsOffset(Dest)) 2303*0b57cec5SDimitry Andric return true; 2304*0b57cec5SDimitry Andric return false; 2305*0b57cec5SDimitry Andric } 2306*0b57cec5SDimitry Andric 2307*0b57cec5SDimitry Andric bool MIParser::parseCustomRegisterMaskOperand(MachineOperand &Dest) { 2308*0b57cec5SDimitry Andric assert(Token.stringValue() == "CustomRegMask" && "Expected a custom RegMask"); 2309*0b57cec5SDimitry Andric lex(); 2310*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2311*0b57cec5SDimitry Andric return true; 2312*0b57cec5SDimitry Andric 2313*0b57cec5SDimitry Andric uint32_t *Mask = MF.allocateRegMask(); 2314*0b57cec5SDimitry Andric while (true) { 2315*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister)) 2316*0b57cec5SDimitry Andric return error("expected a named register"); 2317*0b57cec5SDimitry Andric unsigned Reg; 2318*0b57cec5SDimitry Andric if (parseNamedRegister(Reg)) 2319*0b57cec5SDimitry Andric return true; 2320*0b57cec5SDimitry Andric lex(); 2321*0b57cec5SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32); 2322*0b57cec5SDimitry Andric // TODO: Report an error if the same register is used more than once. 2323*0b57cec5SDimitry Andric if (Token.isNot(MIToken::comma)) 2324*0b57cec5SDimitry Andric break; 2325*0b57cec5SDimitry Andric lex(); 2326*0b57cec5SDimitry Andric } 2327*0b57cec5SDimitry Andric 2328*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2329*0b57cec5SDimitry Andric return true; 2330*0b57cec5SDimitry Andric Dest = MachineOperand::CreateRegMask(Mask); 2331*0b57cec5SDimitry Andric return false; 2332*0b57cec5SDimitry Andric } 2333*0b57cec5SDimitry Andric 2334*0b57cec5SDimitry Andric bool MIParser::parseLiveoutRegisterMaskOperand(MachineOperand &Dest) { 2335*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_liveout)); 2336*0b57cec5SDimitry Andric uint32_t *Mask = MF.allocateRegMask(); 2337*0b57cec5SDimitry Andric lex(); 2338*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2339*0b57cec5SDimitry Andric return true; 2340*0b57cec5SDimitry Andric while (true) { 2341*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedRegister)) 2342*0b57cec5SDimitry Andric return error("expected a named register"); 2343*0b57cec5SDimitry Andric unsigned Reg; 2344*0b57cec5SDimitry Andric if (parseNamedRegister(Reg)) 2345*0b57cec5SDimitry Andric return true; 2346*0b57cec5SDimitry Andric lex(); 2347*0b57cec5SDimitry Andric Mask[Reg / 32] |= 1U << (Reg % 32); 2348*0b57cec5SDimitry Andric // TODO: Report an error if the same register is used more than once. 2349*0b57cec5SDimitry Andric if (Token.isNot(MIToken::comma)) 2350*0b57cec5SDimitry Andric break; 2351*0b57cec5SDimitry Andric lex(); 2352*0b57cec5SDimitry Andric } 2353*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2354*0b57cec5SDimitry Andric return true; 2355*0b57cec5SDimitry Andric Dest = MachineOperand::CreateRegLiveOut(Mask); 2356*0b57cec5SDimitry Andric return false; 2357*0b57cec5SDimitry Andric } 2358*0b57cec5SDimitry Andric 2359*0b57cec5SDimitry Andric bool MIParser::parseMachineOperand(MachineOperand &Dest, 2360*0b57cec5SDimitry Andric Optional<unsigned> &TiedDefIdx) { 2361*0b57cec5SDimitry Andric switch (Token.kind()) { 2362*0b57cec5SDimitry Andric case MIToken::kw_implicit: 2363*0b57cec5SDimitry Andric case MIToken::kw_implicit_define: 2364*0b57cec5SDimitry Andric case MIToken::kw_def: 2365*0b57cec5SDimitry Andric case MIToken::kw_dead: 2366*0b57cec5SDimitry Andric case MIToken::kw_killed: 2367*0b57cec5SDimitry Andric case MIToken::kw_undef: 2368*0b57cec5SDimitry Andric case MIToken::kw_internal: 2369*0b57cec5SDimitry Andric case MIToken::kw_early_clobber: 2370*0b57cec5SDimitry Andric case MIToken::kw_debug_use: 2371*0b57cec5SDimitry Andric case MIToken::kw_renamable: 2372*0b57cec5SDimitry Andric case MIToken::underscore: 2373*0b57cec5SDimitry Andric case MIToken::NamedRegister: 2374*0b57cec5SDimitry Andric case MIToken::VirtualRegister: 2375*0b57cec5SDimitry Andric case MIToken::NamedVirtualRegister: 2376*0b57cec5SDimitry Andric return parseRegisterOperand(Dest, TiedDefIdx); 2377*0b57cec5SDimitry Andric case MIToken::IntegerLiteral: 2378*0b57cec5SDimitry Andric return parseImmediateOperand(Dest); 2379*0b57cec5SDimitry Andric case MIToken::kw_half: 2380*0b57cec5SDimitry Andric case MIToken::kw_float: 2381*0b57cec5SDimitry Andric case MIToken::kw_double: 2382*0b57cec5SDimitry Andric case MIToken::kw_x86_fp80: 2383*0b57cec5SDimitry Andric case MIToken::kw_fp128: 2384*0b57cec5SDimitry Andric case MIToken::kw_ppc_fp128: 2385*0b57cec5SDimitry Andric return parseFPImmediateOperand(Dest); 2386*0b57cec5SDimitry Andric case MIToken::MachineBasicBlock: 2387*0b57cec5SDimitry Andric return parseMBBOperand(Dest); 2388*0b57cec5SDimitry Andric case MIToken::StackObject: 2389*0b57cec5SDimitry Andric return parseStackObjectOperand(Dest); 2390*0b57cec5SDimitry Andric case MIToken::FixedStackObject: 2391*0b57cec5SDimitry Andric return parseFixedStackObjectOperand(Dest); 2392*0b57cec5SDimitry Andric case MIToken::GlobalValue: 2393*0b57cec5SDimitry Andric case MIToken::NamedGlobalValue: 2394*0b57cec5SDimitry Andric return parseGlobalAddressOperand(Dest); 2395*0b57cec5SDimitry Andric case MIToken::ConstantPoolItem: 2396*0b57cec5SDimitry Andric return parseConstantPoolIndexOperand(Dest); 2397*0b57cec5SDimitry Andric case MIToken::JumpTableIndex: 2398*0b57cec5SDimitry Andric return parseJumpTableIndexOperand(Dest); 2399*0b57cec5SDimitry Andric case MIToken::ExternalSymbol: 2400*0b57cec5SDimitry Andric return parseExternalSymbolOperand(Dest); 2401*0b57cec5SDimitry Andric case MIToken::MCSymbol: 2402*0b57cec5SDimitry Andric return parseMCSymbolOperand(Dest); 2403*0b57cec5SDimitry Andric case MIToken::SubRegisterIndex: 2404*0b57cec5SDimitry Andric return parseSubRegisterIndexOperand(Dest); 2405*0b57cec5SDimitry Andric case MIToken::md_diexpr: 2406*0b57cec5SDimitry Andric case MIToken::exclaim: 2407*0b57cec5SDimitry Andric return parseMetadataOperand(Dest); 2408*0b57cec5SDimitry Andric case MIToken::kw_cfi_same_value: 2409*0b57cec5SDimitry Andric case MIToken::kw_cfi_offset: 2410*0b57cec5SDimitry Andric case MIToken::kw_cfi_rel_offset: 2411*0b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_register: 2412*0b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa_offset: 2413*0b57cec5SDimitry Andric case MIToken::kw_cfi_adjust_cfa_offset: 2414*0b57cec5SDimitry Andric case MIToken::kw_cfi_escape: 2415*0b57cec5SDimitry Andric case MIToken::kw_cfi_def_cfa: 2416*0b57cec5SDimitry Andric case MIToken::kw_cfi_register: 2417*0b57cec5SDimitry Andric case MIToken::kw_cfi_remember_state: 2418*0b57cec5SDimitry Andric case MIToken::kw_cfi_restore: 2419*0b57cec5SDimitry Andric case MIToken::kw_cfi_restore_state: 2420*0b57cec5SDimitry Andric case MIToken::kw_cfi_undefined: 2421*0b57cec5SDimitry Andric case MIToken::kw_cfi_window_save: 2422*0b57cec5SDimitry Andric case MIToken::kw_cfi_aarch64_negate_ra_sign_state: 2423*0b57cec5SDimitry Andric return parseCFIOperand(Dest); 2424*0b57cec5SDimitry Andric case MIToken::kw_blockaddress: 2425*0b57cec5SDimitry Andric return parseBlockAddressOperand(Dest); 2426*0b57cec5SDimitry Andric case MIToken::kw_intrinsic: 2427*0b57cec5SDimitry Andric return parseIntrinsicOperand(Dest); 2428*0b57cec5SDimitry Andric case MIToken::kw_target_index: 2429*0b57cec5SDimitry Andric return parseTargetIndexOperand(Dest); 2430*0b57cec5SDimitry Andric case MIToken::kw_liveout: 2431*0b57cec5SDimitry Andric return parseLiveoutRegisterMaskOperand(Dest); 2432*0b57cec5SDimitry Andric case MIToken::kw_floatpred: 2433*0b57cec5SDimitry Andric case MIToken::kw_intpred: 2434*0b57cec5SDimitry Andric return parsePredicateOperand(Dest); 2435*0b57cec5SDimitry Andric case MIToken::Error: 2436*0b57cec5SDimitry Andric return true; 2437*0b57cec5SDimitry Andric case MIToken::Identifier: 2438*0b57cec5SDimitry Andric if (const auto *RegMask = PFS.Target.getRegMask(Token.stringValue())) { 2439*0b57cec5SDimitry Andric Dest = MachineOperand::CreateRegMask(RegMask); 2440*0b57cec5SDimitry Andric lex(); 2441*0b57cec5SDimitry Andric break; 2442*0b57cec5SDimitry Andric } else if (Token.stringValue() == "CustomRegMask") { 2443*0b57cec5SDimitry Andric return parseCustomRegisterMaskOperand(Dest); 2444*0b57cec5SDimitry Andric } else 2445*0b57cec5SDimitry Andric return parseTypedImmediateOperand(Dest); 2446*0b57cec5SDimitry Andric default: 2447*0b57cec5SDimitry Andric // FIXME: Parse the MCSymbol machine operand. 2448*0b57cec5SDimitry Andric return error("expected a machine operand"); 2449*0b57cec5SDimitry Andric } 2450*0b57cec5SDimitry Andric return false; 2451*0b57cec5SDimitry Andric } 2452*0b57cec5SDimitry Andric 2453*0b57cec5SDimitry Andric bool MIParser::parseMachineOperandAndTargetFlags( 2454*0b57cec5SDimitry Andric MachineOperand &Dest, Optional<unsigned> &TiedDefIdx) { 2455*0b57cec5SDimitry Andric unsigned TF = 0; 2456*0b57cec5SDimitry Andric bool HasTargetFlags = false; 2457*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_target_flags)) { 2458*0b57cec5SDimitry Andric HasTargetFlags = true; 2459*0b57cec5SDimitry Andric lex(); 2460*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2461*0b57cec5SDimitry Andric return true; 2462*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier)) 2463*0b57cec5SDimitry Andric return error("expected the name of the target flag"); 2464*0b57cec5SDimitry Andric if (PFS.Target.getDirectTargetFlag(Token.stringValue(), TF)) { 2465*0b57cec5SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), TF)) 2466*0b57cec5SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() + 2467*0b57cec5SDimitry Andric "'"); 2468*0b57cec5SDimitry Andric } 2469*0b57cec5SDimitry Andric lex(); 2470*0b57cec5SDimitry Andric while (Token.is(MIToken::comma)) { 2471*0b57cec5SDimitry Andric lex(); 2472*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier)) 2473*0b57cec5SDimitry Andric return error("expected the name of the target flag"); 2474*0b57cec5SDimitry Andric unsigned BitFlag = 0; 2475*0b57cec5SDimitry Andric if (PFS.Target.getBitmaskTargetFlag(Token.stringValue(), BitFlag)) 2476*0b57cec5SDimitry Andric return error("use of undefined target flag '" + Token.stringValue() + 2477*0b57cec5SDimitry Andric "'"); 2478*0b57cec5SDimitry Andric // TODO: Report an error when using a duplicate bit target flag. 2479*0b57cec5SDimitry Andric TF |= BitFlag; 2480*0b57cec5SDimitry Andric lex(); 2481*0b57cec5SDimitry Andric } 2482*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2483*0b57cec5SDimitry Andric return true; 2484*0b57cec5SDimitry Andric } 2485*0b57cec5SDimitry Andric auto Loc = Token.location(); 2486*0b57cec5SDimitry Andric if (parseMachineOperand(Dest, TiedDefIdx)) 2487*0b57cec5SDimitry Andric return true; 2488*0b57cec5SDimitry Andric if (!HasTargetFlags) 2489*0b57cec5SDimitry Andric return false; 2490*0b57cec5SDimitry Andric if (Dest.isReg()) 2491*0b57cec5SDimitry Andric return error(Loc, "register operands can't have target flags"); 2492*0b57cec5SDimitry Andric Dest.setTargetFlags(TF); 2493*0b57cec5SDimitry Andric return false; 2494*0b57cec5SDimitry Andric } 2495*0b57cec5SDimitry Andric 2496*0b57cec5SDimitry Andric bool MIParser::parseOffset(int64_t &Offset) { 2497*0b57cec5SDimitry Andric if (Token.isNot(MIToken::plus) && Token.isNot(MIToken::minus)) 2498*0b57cec5SDimitry Andric return false; 2499*0b57cec5SDimitry Andric StringRef Sign = Token.range(); 2500*0b57cec5SDimitry Andric bool IsNegative = Token.is(MIToken::minus); 2501*0b57cec5SDimitry Andric lex(); 2502*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral)) 2503*0b57cec5SDimitry Andric return error("expected an integer literal after '" + Sign + "'"); 2504*0b57cec5SDimitry Andric if (Token.integerValue().getMinSignedBits() > 64) 2505*0b57cec5SDimitry Andric return error("expected 64-bit integer (too large)"); 2506*0b57cec5SDimitry Andric Offset = Token.integerValue().getExtValue(); 2507*0b57cec5SDimitry Andric if (IsNegative) 2508*0b57cec5SDimitry Andric Offset = -Offset; 2509*0b57cec5SDimitry Andric lex(); 2510*0b57cec5SDimitry Andric return false; 2511*0b57cec5SDimitry Andric } 2512*0b57cec5SDimitry Andric 2513*0b57cec5SDimitry Andric bool MIParser::parseAlignment(unsigned &Alignment) { 2514*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_align)); 2515*0b57cec5SDimitry Andric lex(); 2516*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) 2517*0b57cec5SDimitry Andric return error("expected an integer literal after 'align'"); 2518*0b57cec5SDimitry Andric if (getUnsigned(Alignment)) 2519*0b57cec5SDimitry Andric return true; 2520*0b57cec5SDimitry Andric lex(); 2521*0b57cec5SDimitry Andric 2522*0b57cec5SDimitry Andric if (!isPowerOf2_32(Alignment)) 2523*0b57cec5SDimitry Andric return error("expected a power-of-2 literal after 'align'"); 2524*0b57cec5SDimitry Andric 2525*0b57cec5SDimitry Andric return false; 2526*0b57cec5SDimitry Andric } 2527*0b57cec5SDimitry Andric 2528*0b57cec5SDimitry Andric bool MIParser::parseAddrspace(unsigned &Addrspace) { 2529*0b57cec5SDimitry Andric assert(Token.is(MIToken::kw_addrspace)); 2530*0b57cec5SDimitry Andric lex(); 2531*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) 2532*0b57cec5SDimitry Andric return error("expected an integer literal after 'addrspace'"); 2533*0b57cec5SDimitry Andric if (getUnsigned(Addrspace)) 2534*0b57cec5SDimitry Andric return true; 2535*0b57cec5SDimitry Andric lex(); 2536*0b57cec5SDimitry Andric return false; 2537*0b57cec5SDimitry Andric } 2538*0b57cec5SDimitry Andric 2539*0b57cec5SDimitry Andric bool MIParser::parseOperandsOffset(MachineOperand &Op) { 2540*0b57cec5SDimitry Andric int64_t Offset = 0; 2541*0b57cec5SDimitry Andric if (parseOffset(Offset)) 2542*0b57cec5SDimitry Andric return true; 2543*0b57cec5SDimitry Andric Op.setOffset(Offset); 2544*0b57cec5SDimitry Andric return false; 2545*0b57cec5SDimitry Andric } 2546*0b57cec5SDimitry Andric 2547*0b57cec5SDimitry Andric bool MIParser::parseIRValue(const Value *&V) { 2548*0b57cec5SDimitry Andric switch (Token.kind()) { 2549*0b57cec5SDimitry Andric case MIToken::NamedIRValue: { 2550*0b57cec5SDimitry Andric V = MF.getFunction().getValueSymbolTable()->lookup(Token.stringValue()); 2551*0b57cec5SDimitry Andric break; 2552*0b57cec5SDimitry Andric } 2553*0b57cec5SDimitry Andric case MIToken::IRValue: { 2554*0b57cec5SDimitry Andric unsigned SlotNumber = 0; 2555*0b57cec5SDimitry Andric if (getUnsigned(SlotNumber)) 2556*0b57cec5SDimitry Andric return true; 2557*0b57cec5SDimitry Andric V = getIRValue(SlotNumber); 2558*0b57cec5SDimitry Andric break; 2559*0b57cec5SDimitry Andric } 2560*0b57cec5SDimitry Andric case MIToken::NamedGlobalValue: 2561*0b57cec5SDimitry Andric case MIToken::GlobalValue: { 2562*0b57cec5SDimitry Andric GlobalValue *GV = nullptr; 2563*0b57cec5SDimitry Andric if (parseGlobalValue(GV)) 2564*0b57cec5SDimitry Andric return true; 2565*0b57cec5SDimitry Andric V = GV; 2566*0b57cec5SDimitry Andric break; 2567*0b57cec5SDimitry Andric } 2568*0b57cec5SDimitry Andric case MIToken::QuotedIRValue: { 2569*0b57cec5SDimitry Andric const Constant *C = nullptr; 2570*0b57cec5SDimitry Andric if (parseIRConstant(Token.location(), Token.stringValue(), C)) 2571*0b57cec5SDimitry Andric return true; 2572*0b57cec5SDimitry Andric V = C; 2573*0b57cec5SDimitry Andric break; 2574*0b57cec5SDimitry Andric } 2575*0b57cec5SDimitry Andric default: 2576*0b57cec5SDimitry Andric llvm_unreachable("The current token should be an IR block reference"); 2577*0b57cec5SDimitry Andric } 2578*0b57cec5SDimitry Andric if (!V) 2579*0b57cec5SDimitry Andric return error(Twine("use of undefined IR value '") + Token.range() + "'"); 2580*0b57cec5SDimitry Andric return false; 2581*0b57cec5SDimitry Andric } 2582*0b57cec5SDimitry Andric 2583*0b57cec5SDimitry Andric bool MIParser::getUint64(uint64_t &Result) { 2584*0b57cec5SDimitry Andric if (Token.hasIntegerValue()) { 2585*0b57cec5SDimitry Andric if (Token.integerValue().getActiveBits() > 64) 2586*0b57cec5SDimitry Andric return error("expected 64-bit integer (too large)"); 2587*0b57cec5SDimitry Andric Result = Token.integerValue().getZExtValue(); 2588*0b57cec5SDimitry Andric return false; 2589*0b57cec5SDimitry Andric } 2590*0b57cec5SDimitry Andric if (Token.is(MIToken::HexLiteral)) { 2591*0b57cec5SDimitry Andric APInt A; 2592*0b57cec5SDimitry Andric if (getHexUint(A)) 2593*0b57cec5SDimitry Andric return true; 2594*0b57cec5SDimitry Andric if (A.getBitWidth() > 64) 2595*0b57cec5SDimitry Andric return error("expected 64-bit integer (too large)"); 2596*0b57cec5SDimitry Andric Result = A.getZExtValue(); 2597*0b57cec5SDimitry Andric return false; 2598*0b57cec5SDimitry Andric } 2599*0b57cec5SDimitry Andric return true; 2600*0b57cec5SDimitry Andric } 2601*0b57cec5SDimitry Andric 2602*0b57cec5SDimitry Andric bool MIParser::getHexUint(APInt &Result) { 2603*0b57cec5SDimitry Andric assert(Token.is(MIToken::HexLiteral)); 2604*0b57cec5SDimitry Andric StringRef S = Token.range(); 2605*0b57cec5SDimitry Andric assert(S[0] == '0' && tolower(S[1]) == 'x'); 2606*0b57cec5SDimitry Andric // This could be a floating point literal with a special prefix. 2607*0b57cec5SDimitry Andric if (!isxdigit(S[2])) 2608*0b57cec5SDimitry Andric return true; 2609*0b57cec5SDimitry Andric StringRef V = S.substr(2); 2610*0b57cec5SDimitry Andric APInt A(V.size()*4, V, 16); 2611*0b57cec5SDimitry Andric 2612*0b57cec5SDimitry Andric // If A is 0, then A.getActiveBits() is 0. This isn't a valid bitwidth. Make 2613*0b57cec5SDimitry Andric // sure it isn't the case before constructing result. 2614*0b57cec5SDimitry Andric unsigned NumBits = (A == 0) ? 32 : A.getActiveBits(); 2615*0b57cec5SDimitry Andric Result = APInt(NumBits, ArrayRef<uint64_t>(A.getRawData(), A.getNumWords())); 2616*0b57cec5SDimitry Andric return false; 2617*0b57cec5SDimitry Andric } 2618*0b57cec5SDimitry Andric 2619*0b57cec5SDimitry Andric bool MIParser::parseMemoryOperandFlag(MachineMemOperand::Flags &Flags) { 2620*0b57cec5SDimitry Andric const auto OldFlags = Flags; 2621*0b57cec5SDimitry Andric switch (Token.kind()) { 2622*0b57cec5SDimitry Andric case MIToken::kw_volatile: 2623*0b57cec5SDimitry Andric Flags |= MachineMemOperand::MOVolatile; 2624*0b57cec5SDimitry Andric break; 2625*0b57cec5SDimitry Andric case MIToken::kw_non_temporal: 2626*0b57cec5SDimitry Andric Flags |= MachineMemOperand::MONonTemporal; 2627*0b57cec5SDimitry Andric break; 2628*0b57cec5SDimitry Andric case MIToken::kw_dereferenceable: 2629*0b57cec5SDimitry Andric Flags |= MachineMemOperand::MODereferenceable; 2630*0b57cec5SDimitry Andric break; 2631*0b57cec5SDimitry Andric case MIToken::kw_invariant: 2632*0b57cec5SDimitry Andric Flags |= MachineMemOperand::MOInvariant; 2633*0b57cec5SDimitry Andric break; 2634*0b57cec5SDimitry Andric case MIToken::StringConstant: { 2635*0b57cec5SDimitry Andric MachineMemOperand::Flags TF; 2636*0b57cec5SDimitry Andric if (PFS.Target.getMMOTargetFlag(Token.stringValue(), TF)) 2637*0b57cec5SDimitry Andric return error("use of undefined target MMO flag '" + Token.stringValue() + 2638*0b57cec5SDimitry Andric "'"); 2639*0b57cec5SDimitry Andric Flags |= TF; 2640*0b57cec5SDimitry Andric break; 2641*0b57cec5SDimitry Andric } 2642*0b57cec5SDimitry Andric default: 2643*0b57cec5SDimitry Andric llvm_unreachable("The current token should be a memory operand flag"); 2644*0b57cec5SDimitry Andric } 2645*0b57cec5SDimitry Andric if (OldFlags == Flags) 2646*0b57cec5SDimitry Andric // We know that the same flag is specified more than once when the flags 2647*0b57cec5SDimitry Andric // weren't modified. 2648*0b57cec5SDimitry Andric return error("duplicate '" + Token.stringValue() + "' memory operand flag"); 2649*0b57cec5SDimitry Andric lex(); 2650*0b57cec5SDimitry Andric return false; 2651*0b57cec5SDimitry Andric } 2652*0b57cec5SDimitry Andric 2653*0b57cec5SDimitry Andric bool MIParser::parseMemoryPseudoSourceValue(const PseudoSourceValue *&PSV) { 2654*0b57cec5SDimitry Andric switch (Token.kind()) { 2655*0b57cec5SDimitry Andric case MIToken::kw_stack: 2656*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getStack(); 2657*0b57cec5SDimitry Andric break; 2658*0b57cec5SDimitry Andric case MIToken::kw_got: 2659*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getGOT(); 2660*0b57cec5SDimitry Andric break; 2661*0b57cec5SDimitry Andric case MIToken::kw_jump_table: 2662*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getJumpTable(); 2663*0b57cec5SDimitry Andric break; 2664*0b57cec5SDimitry Andric case MIToken::kw_constant_pool: 2665*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getConstantPool(); 2666*0b57cec5SDimitry Andric break; 2667*0b57cec5SDimitry Andric case MIToken::FixedStackObject: { 2668*0b57cec5SDimitry Andric int FI; 2669*0b57cec5SDimitry Andric if (parseFixedStackFrameIndex(FI)) 2670*0b57cec5SDimitry Andric return true; 2671*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI); 2672*0b57cec5SDimitry Andric // The token was already consumed, so use return here instead of break. 2673*0b57cec5SDimitry Andric return false; 2674*0b57cec5SDimitry Andric } 2675*0b57cec5SDimitry Andric case MIToken::StackObject: { 2676*0b57cec5SDimitry Andric int FI; 2677*0b57cec5SDimitry Andric if (parseStackFrameIndex(FI)) 2678*0b57cec5SDimitry Andric return true; 2679*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getFixedStack(FI); 2680*0b57cec5SDimitry Andric // The token was already consumed, so use return here instead of break. 2681*0b57cec5SDimitry Andric return false; 2682*0b57cec5SDimitry Andric } 2683*0b57cec5SDimitry Andric case MIToken::kw_call_entry: 2684*0b57cec5SDimitry Andric lex(); 2685*0b57cec5SDimitry Andric switch (Token.kind()) { 2686*0b57cec5SDimitry Andric case MIToken::GlobalValue: 2687*0b57cec5SDimitry Andric case MIToken::NamedGlobalValue: { 2688*0b57cec5SDimitry Andric GlobalValue *GV = nullptr; 2689*0b57cec5SDimitry Andric if (parseGlobalValue(GV)) 2690*0b57cec5SDimitry Andric return true; 2691*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getGlobalValueCallEntry(GV); 2692*0b57cec5SDimitry Andric break; 2693*0b57cec5SDimitry Andric } 2694*0b57cec5SDimitry Andric case MIToken::ExternalSymbol: 2695*0b57cec5SDimitry Andric PSV = MF.getPSVManager().getExternalSymbolCallEntry( 2696*0b57cec5SDimitry Andric MF.createExternalSymbolName(Token.stringValue())); 2697*0b57cec5SDimitry Andric break; 2698*0b57cec5SDimitry Andric default: 2699*0b57cec5SDimitry Andric return error( 2700*0b57cec5SDimitry Andric "expected a global value or an external symbol after 'call-entry'"); 2701*0b57cec5SDimitry Andric } 2702*0b57cec5SDimitry Andric break; 2703*0b57cec5SDimitry Andric default: 2704*0b57cec5SDimitry Andric llvm_unreachable("The current token should be pseudo source value"); 2705*0b57cec5SDimitry Andric } 2706*0b57cec5SDimitry Andric lex(); 2707*0b57cec5SDimitry Andric return false; 2708*0b57cec5SDimitry Andric } 2709*0b57cec5SDimitry Andric 2710*0b57cec5SDimitry Andric bool MIParser::parseMachinePointerInfo(MachinePointerInfo &Dest) { 2711*0b57cec5SDimitry Andric if (Token.is(MIToken::kw_constant_pool) || Token.is(MIToken::kw_stack) || 2712*0b57cec5SDimitry Andric Token.is(MIToken::kw_got) || Token.is(MIToken::kw_jump_table) || 2713*0b57cec5SDimitry Andric Token.is(MIToken::FixedStackObject) || Token.is(MIToken::StackObject) || 2714*0b57cec5SDimitry Andric Token.is(MIToken::kw_call_entry)) { 2715*0b57cec5SDimitry Andric const PseudoSourceValue *PSV = nullptr; 2716*0b57cec5SDimitry Andric if (parseMemoryPseudoSourceValue(PSV)) 2717*0b57cec5SDimitry Andric return true; 2718*0b57cec5SDimitry Andric int64_t Offset = 0; 2719*0b57cec5SDimitry Andric if (parseOffset(Offset)) 2720*0b57cec5SDimitry Andric return true; 2721*0b57cec5SDimitry Andric Dest = MachinePointerInfo(PSV, Offset); 2722*0b57cec5SDimitry Andric return false; 2723*0b57cec5SDimitry Andric } 2724*0b57cec5SDimitry Andric if (Token.isNot(MIToken::NamedIRValue) && Token.isNot(MIToken::IRValue) && 2725*0b57cec5SDimitry Andric Token.isNot(MIToken::GlobalValue) && 2726*0b57cec5SDimitry Andric Token.isNot(MIToken::NamedGlobalValue) && 2727*0b57cec5SDimitry Andric Token.isNot(MIToken::QuotedIRValue)) 2728*0b57cec5SDimitry Andric return error("expected an IR value reference"); 2729*0b57cec5SDimitry Andric const Value *V = nullptr; 2730*0b57cec5SDimitry Andric if (parseIRValue(V)) 2731*0b57cec5SDimitry Andric return true; 2732*0b57cec5SDimitry Andric if (!V->getType()->isPointerTy()) 2733*0b57cec5SDimitry Andric return error("expected a pointer IR value"); 2734*0b57cec5SDimitry Andric lex(); 2735*0b57cec5SDimitry Andric int64_t Offset = 0; 2736*0b57cec5SDimitry Andric if (parseOffset(Offset)) 2737*0b57cec5SDimitry Andric return true; 2738*0b57cec5SDimitry Andric Dest = MachinePointerInfo(V, Offset); 2739*0b57cec5SDimitry Andric return false; 2740*0b57cec5SDimitry Andric } 2741*0b57cec5SDimitry Andric 2742*0b57cec5SDimitry Andric bool MIParser::parseOptionalScope(LLVMContext &Context, 2743*0b57cec5SDimitry Andric SyncScope::ID &SSID) { 2744*0b57cec5SDimitry Andric SSID = SyncScope::System; 2745*0b57cec5SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "syncscope") { 2746*0b57cec5SDimitry Andric lex(); 2747*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2748*0b57cec5SDimitry Andric return error("expected '(' in syncscope"); 2749*0b57cec5SDimitry Andric 2750*0b57cec5SDimitry Andric std::string SSN; 2751*0b57cec5SDimitry Andric if (parseStringConstant(SSN)) 2752*0b57cec5SDimitry Andric return true; 2753*0b57cec5SDimitry Andric 2754*0b57cec5SDimitry Andric SSID = Context.getOrInsertSyncScopeID(SSN); 2755*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2756*0b57cec5SDimitry Andric return error("expected ')' in syncscope"); 2757*0b57cec5SDimitry Andric } 2758*0b57cec5SDimitry Andric 2759*0b57cec5SDimitry Andric return false; 2760*0b57cec5SDimitry Andric } 2761*0b57cec5SDimitry Andric 2762*0b57cec5SDimitry Andric bool MIParser::parseOptionalAtomicOrdering(AtomicOrdering &Order) { 2763*0b57cec5SDimitry Andric Order = AtomicOrdering::NotAtomic; 2764*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier)) 2765*0b57cec5SDimitry Andric return false; 2766*0b57cec5SDimitry Andric 2767*0b57cec5SDimitry Andric Order = StringSwitch<AtomicOrdering>(Token.stringValue()) 2768*0b57cec5SDimitry Andric .Case("unordered", AtomicOrdering::Unordered) 2769*0b57cec5SDimitry Andric .Case("monotonic", AtomicOrdering::Monotonic) 2770*0b57cec5SDimitry Andric .Case("acquire", AtomicOrdering::Acquire) 2771*0b57cec5SDimitry Andric .Case("release", AtomicOrdering::Release) 2772*0b57cec5SDimitry Andric .Case("acq_rel", AtomicOrdering::AcquireRelease) 2773*0b57cec5SDimitry Andric .Case("seq_cst", AtomicOrdering::SequentiallyConsistent) 2774*0b57cec5SDimitry Andric .Default(AtomicOrdering::NotAtomic); 2775*0b57cec5SDimitry Andric 2776*0b57cec5SDimitry Andric if (Order != AtomicOrdering::NotAtomic) { 2777*0b57cec5SDimitry Andric lex(); 2778*0b57cec5SDimitry Andric return false; 2779*0b57cec5SDimitry Andric } 2780*0b57cec5SDimitry Andric 2781*0b57cec5SDimitry Andric return error("expected an atomic scope, ordering or a size specification"); 2782*0b57cec5SDimitry Andric } 2783*0b57cec5SDimitry Andric 2784*0b57cec5SDimitry Andric bool MIParser::parseMachineMemoryOperand(MachineMemOperand *&Dest) { 2785*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::lparen)) 2786*0b57cec5SDimitry Andric return true; 2787*0b57cec5SDimitry Andric MachineMemOperand::Flags Flags = MachineMemOperand::MONone; 2788*0b57cec5SDimitry Andric while (Token.isMemoryOperandFlag()) { 2789*0b57cec5SDimitry Andric if (parseMemoryOperandFlag(Flags)) 2790*0b57cec5SDimitry Andric return true; 2791*0b57cec5SDimitry Andric } 2792*0b57cec5SDimitry Andric if (Token.isNot(MIToken::Identifier) || 2793*0b57cec5SDimitry Andric (Token.stringValue() != "load" && Token.stringValue() != "store")) 2794*0b57cec5SDimitry Andric return error("expected 'load' or 'store' memory operation"); 2795*0b57cec5SDimitry Andric if (Token.stringValue() == "load") 2796*0b57cec5SDimitry Andric Flags |= MachineMemOperand::MOLoad; 2797*0b57cec5SDimitry Andric else 2798*0b57cec5SDimitry Andric Flags |= MachineMemOperand::MOStore; 2799*0b57cec5SDimitry Andric lex(); 2800*0b57cec5SDimitry Andric 2801*0b57cec5SDimitry Andric // Optional 'store' for operands that both load and store. 2802*0b57cec5SDimitry Andric if (Token.is(MIToken::Identifier) && Token.stringValue() == "store") { 2803*0b57cec5SDimitry Andric Flags |= MachineMemOperand::MOStore; 2804*0b57cec5SDimitry Andric lex(); 2805*0b57cec5SDimitry Andric } 2806*0b57cec5SDimitry Andric 2807*0b57cec5SDimitry Andric // Optional synchronization scope. 2808*0b57cec5SDimitry Andric SyncScope::ID SSID; 2809*0b57cec5SDimitry Andric if (parseOptionalScope(MF.getFunction().getContext(), SSID)) 2810*0b57cec5SDimitry Andric return true; 2811*0b57cec5SDimitry Andric 2812*0b57cec5SDimitry Andric // Up to two atomic orderings (cmpxchg provides guarantees on failure). 2813*0b57cec5SDimitry Andric AtomicOrdering Order, FailureOrder; 2814*0b57cec5SDimitry Andric if (parseOptionalAtomicOrdering(Order)) 2815*0b57cec5SDimitry Andric return true; 2816*0b57cec5SDimitry Andric 2817*0b57cec5SDimitry Andric if (parseOptionalAtomicOrdering(FailureOrder)) 2818*0b57cec5SDimitry Andric return true; 2819*0b57cec5SDimitry Andric 2820*0b57cec5SDimitry Andric if (Token.isNot(MIToken::IntegerLiteral) && 2821*0b57cec5SDimitry Andric Token.isNot(MIToken::kw_unknown_size)) 2822*0b57cec5SDimitry Andric return error("expected the size integer literal or 'unknown-size' after " 2823*0b57cec5SDimitry Andric "memory operation"); 2824*0b57cec5SDimitry Andric uint64_t Size; 2825*0b57cec5SDimitry Andric if (Token.is(MIToken::IntegerLiteral)) { 2826*0b57cec5SDimitry Andric if (getUint64(Size)) 2827*0b57cec5SDimitry Andric return true; 2828*0b57cec5SDimitry Andric } else if (Token.is(MIToken::kw_unknown_size)) { 2829*0b57cec5SDimitry Andric Size = MemoryLocation::UnknownSize; 2830*0b57cec5SDimitry Andric } 2831*0b57cec5SDimitry Andric lex(); 2832*0b57cec5SDimitry Andric 2833*0b57cec5SDimitry Andric MachinePointerInfo Ptr = MachinePointerInfo(); 2834*0b57cec5SDimitry Andric if (Token.is(MIToken::Identifier)) { 2835*0b57cec5SDimitry Andric const char *Word = 2836*0b57cec5SDimitry Andric ((Flags & MachineMemOperand::MOLoad) && 2837*0b57cec5SDimitry Andric (Flags & MachineMemOperand::MOStore)) 2838*0b57cec5SDimitry Andric ? "on" 2839*0b57cec5SDimitry Andric : Flags & MachineMemOperand::MOLoad ? "from" : "into"; 2840*0b57cec5SDimitry Andric if (Token.stringValue() != Word) 2841*0b57cec5SDimitry Andric return error(Twine("expected '") + Word + "'"); 2842*0b57cec5SDimitry Andric lex(); 2843*0b57cec5SDimitry Andric 2844*0b57cec5SDimitry Andric if (parseMachinePointerInfo(Ptr)) 2845*0b57cec5SDimitry Andric return true; 2846*0b57cec5SDimitry Andric } 2847*0b57cec5SDimitry Andric unsigned BaseAlignment = (Size != MemoryLocation::UnknownSize ? Size : 1); 2848*0b57cec5SDimitry Andric AAMDNodes AAInfo; 2849*0b57cec5SDimitry Andric MDNode *Range = nullptr; 2850*0b57cec5SDimitry Andric while (consumeIfPresent(MIToken::comma)) { 2851*0b57cec5SDimitry Andric switch (Token.kind()) { 2852*0b57cec5SDimitry Andric case MIToken::kw_align: 2853*0b57cec5SDimitry Andric if (parseAlignment(BaseAlignment)) 2854*0b57cec5SDimitry Andric return true; 2855*0b57cec5SDimitry Andric break; 2856*0b57cec5SDimitry Andric case MIToken::kw_addrspace: 2857*0b57cec5SDimitry Andric if (parseAddrspace(Ptr.AddrSpace)) 2858*0b57cec5SDimitry Andric return true; 2859*0b57cec5SDimitry Andric break; 2860*0b57cec5SDimitry Andric case MIToken::md_tbaa: 2861*0b57cec5SDimitry Andric lex(); 2862*0b57cec5SDimitry Andric if (parseMDNode(AAInfo.TBAA)) 2863*0b57cec5SDimitry Andric return true; 2864*0b57cec5SDimitry Andric break; 2865*0b57cec5SDimitry Andric case MIToken::md_alias_scope: 2866*0b57cec5SDimitry Andric lex(); 2867*0b57cec5SDimitry Andric if (parseMDNode(AAInfo.Scope)) 2868*0b57cec5SDimitry Andric return true; 2869*0b57cec5SDimitry Andric break; 2870*0b57cec5SDimitry Andric case MIToken::md_noalias: 2871*0b57cec5SDimitry Andric lex(); 2872*0b57cec5SDimitry Andric if (parseMDNode(AAInfo.NoAlias)) 2873*0b57cec5SDimitry Andric return true; 2874*0b57cec5SDimitry Andric break; 2875*0b57cec5SDimitry Andric case MIToken::md_range: 2876*0b57cec5SDimitry Andric lex(); 2877*0b57cec5SDimitry Andric if (parseMDNode(Range)) 2878*0b57cec5SDimitry Andric return true; 2879*0b57cec5SDimitry Andric break; 2880*0b57cec5SDimitry Andric // TODO: Report an error on duplicate metadata nodes. 2881*0b57cec5SDimitry Andric default: 2882*0b57cec5SDimitry Andric return error("expected 'align' or '!tbaa' or '!alias.scope' or " 2883*0b57cec5SDimitry Andric "'!noalias' or '!range'"); 2884*0b57cec5SDimitry Andric } 2885*0b57cec5SDimitry Andric } 2886*0b57cec5SDimitry Andric if (expectAndConsume(MIToken::rparen)) 2887*0b57cec5SDimitry Andric return true; 2888*0b57cec5SDimitry Andric Dest = MF.getMachineMemOperand(Ptr, Flags, Size, BaseAlignment, AAInfo, Range, 2889*0b57cec5SDimitry Andric SSID, Order, FailureOrder); 2890*0b57cec5SDimitry Andric return false; 2891*0b57cec5SDimitry Andric } 2892*0b57cec5SDimitry Andric 2893*0b57cec5SDimitry Andric bool MIParser::parsePreOrPostInstrSymbol(MCSymbol *&Symbol) { 2894*0b57cec5SDimitry Andric assert((Token.is(MIToken::kw_pre_instr_symbol) || 2895*0b57cec5SDimitry Andric Token.is(MIToken::kw_post_instr_symbol)) && 2896*0b57cec5SDimitry Andric "Invalid token for a pre- post-instruction symbol!"); 2897*0b57cec5SDimitry Andric lex(); 2898*0b57cec5SDimitry Andric if (Token.isNot(MIToken::MCSymbol)) 2899*0b57cec5SDimitry Andric return error("expected a symbol after 'pre-instr-symbol'"); 2900*0b57cec5SDimitry Andric Symbol = getOrCreateMCSymbol(Token.stringValue()); 2901*0b57cec5SDimitry Andric lex(); 2902*0b57cec5SDimitry Andric if (Token.isNewlineOrEOF() || Token.is(MIToken::coloncolon) || 2903*0b57cec5SDimitry Andric Token.is(MIToken::lbrace)) 2904*0b57cec5SDimitry Andric return false; 2905*0b57cec5SDimitry Andric if (Token.isNot(MIToken::comma)) 2906*0b57cec5SDimitry Andric return error("expected ',' before the next machine operand"); 2907*0b57cec5SDimitry Andric lex(); 2908*0b57cec5SDimitry Andric return false; 2909*0b57cec5SDimitry Andric } 2910*0b57cec5SDimitry Andric 2911*0b57cec5SDimitry Andric static void initSlots2BasicBlocks( 2912*0b57cec5SDimitry Andric const Function &F, 2913*0b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) { 2914*0b57cec5SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false); 2915*0b57cec5SDimitry Andric MST.incorporateFunction(F); 2916*0b57cec5SDimitry Andric for (auto &BB : F) { 2917*0b57cec5SDimitry Andric if (BB.hasName()) 2918*0b57cec5SDimitry Andric continue; 2919*0b57cec5SDimitry Andric int Slot = MST.getLocalSlot(&BB); 2920*0b57cec5SDimitry Andric if (Slot == -1) 2921*0b57cec5SDimitry Andric continue; 2922*0b57cec5SDimitry Andric Slots2BasicBlocks.insert(std::make_pair(unsigned(Slot), &BB)); 2923*0b57cec5SDimitry Andric } 2924*0b57cec5SDimitry Andric } 2925*0b57cec5SDimitry Andric 2926*0b57cec5SDimitry Andric static const BasicBlock *getIRBlockFromSlot( 2927*0b57cec5SDimitry Andric unsigned Slot, 2928*0b57cec5SDimitry Andric const DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) { 2929*0b57cec5SDimitry Andric auto BlockInfo = Slots2BasicBlocks.find(Slot); 2930*0b57cec5SDimitry Andric if (BlockInfo == Slots2BasicBlocks.end()) 2931*0b57cec5SDimitry Andric return nullptr; 2932*0b57cec5SDimitry Andric return BlockInfo->second; 2933*0b57cec5SDimitry Andric } 2934*0b57cec5SDimitry Andric 2935*0b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot) { 2936*0b57cec5SDimitry Andric if (Slots2BasicBlocks.empty()) 2937*0b57cec5SDimitry Andric initSlots2BasicBlocks(MF.getFunction(), Slots2BasicBlocks); 2938*0b57cec5SDimitry Andric return getIRBlockFromSlot(Slot, Slots2BasicBlocks); 2939*0b57cec5SDimitry Andric } 2940*0b57cec5SDimitry Andric 2941*0b57cec5SDimitry Andric const BasicBlock *MIParser::getIRBlock(unsigned Slot, const Function &F) { 2942*0b57cec5SDimitry Andric if (&F == &MF.getFunction()) 2943*0b57cec5SDimitry Andric return getIRBlock(Slot); 2944*0b57cec5SDimitry Andric DenseMap<unsigned, const BasicBlock *> CustomSlots2BasicBlocks; 2945*0b57cec5SDimitry Andric initSlots2BasicBlocks(F, CustomSlots2BasicBlocks); 2946*0b57cec5SDimitry Andric return getIRBlockFromSlot(Slot, CustomSlots2BasicBlocks); 2947*0b57cec5SDimitry Andric } 2948*0b57cec5SDimitry Andric 2949*0b57cec5SDimitry Andric static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST, 2950*0b57cec5SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) { 2951*0b57cec5SDimitry Andric int Slot = MST.getLocalSlot(V); 2952*0b57cec5SDimitry Andric if (Slot == -1) 2953*0b57cec5SDimitry Andric return; 2954*0b57cec5SDimitry Andric Slots2Values.insert(std::make_pair(unsigned(Slot), V)); 2955*0b57cec5SDimitry Andric } 2956*0b57cec5SDimitry Andric 2957*0b57cec5SDimitry Andric /// Creates the mapping from slot numbers to function's unnamed IR values. 2958*0b57cec5SDimitry Andric static void initSlots2Values(const Function &F, 2959*0b57cec5SDimitry Andric DenseMap<unsigned, const Value *> &Slots2Values) { 2960*0b57cec5SDimitry Andric ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false); 2961*0b57cec5SDimitry Andric MST.incorporateFunction(F); 2962*0b57cec5SDimitry Andric for (const auto &Arg : F.args()) 2963*0b57cec5SDimitry Andric mapValueToSlot(&Arg, MST, Slots2Values); 2964*0b57cec5SDimitry Andric for (const auto &BB : F) { 2965*0b57cec5SDimitry Andric mapValueToSlot(&BB, MST, Slots2Values); 2966*0b57cec5SDimitry Andric for (const auto &I : BB) 2967*0b57cec5SDimitry Andric mapValueToSlot(&I, MST, Slots2Values); 2968*0b57cec5SDimitry Andric } 2969*0b57cec5SDimitry Andric } 2970*0b57cec5SDimitry Andric 2971*0b57cec5SDimitry Andric const Value *MIParser::getIRValue(unsigned Slot) { 2972*0b57cec5SDimitry Andric if (Slots2Values.empty()) 2973*0b57cec5SDimitry Andric initSlots2Values(MF.getFunction(), Slots2Values); 2974*0b57cec5SDimitry Andric auto ValueInfo = Slots2Values.find(Slot); 2975*0b57cec5SDimitry Andric if (ValueInfo == Slots2Values.end()) 2976*0b57cec5SDimitry Andric return nullptr; 2977*0b57cec5SDimitry Andric return ValueInfo->second; 2978*0b57cec5SDimitry Andric } 2979*0b57cec5SDimitry Andric 2980*0b57cec5SDimitry Andric MCSymbol *MIParser::getOrCreateMCSymbol(StringRef Name) { 2981*0b57cec5SDimitry Andric // FIXME: Currently we can't recognize temporary or local symbols and call all 2982*0b57cec5SDimitry Andric // of the appropriate forms to create them. However, this handles basic cases 2983*0b57cec5SDimitry Andric // well as most of the special aspects are recognized by a prefix on their 2984*0b57cec5SDimitry Andric // name, and the input names should already be unique. For test cases, keeping 2985*0b57cec5SDimitry Andric // the symbol name out of the symbol table isn't terribly important. 2986*0b57cec5SDimitry Andric return MF.getContext().getOrCreateSymbol(Name); 2987*0b57cec5SDimitry Andric } 2988*0b57cec5SDimitry Andric 2989*0b57cec5SDimitry Andric bool MIParser::parseStringConstant(std::string &Result) { 2990*0b57cec5SDimitry Andric if (Token.isNot(MIToken::StringConstant)) 2991*0b57cec5SDimitry Andric return error("expected string constant"); 2992*0b57cec5SDimitry Andric Result = Token.stringValue(); 2993*0b57cec5SDimitry Andric lex(); 2994*0b57cec5SDimitry Andric return false; 2995*0b57cec5SDimitry Andric } 2996*0b57cec5SDimitry Andric 2997*0b57cec5SDimitry Andric bool llvm::parseMachineBasicBlockDefinitions(PerFunctionMIParsingState &PFS, 2998*0b57cec5SDimitry Andric StringRef Src, 2999*0b57cec5SDimitry Andric SMDiagnostic &Error) { 3000*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlockDefinitions(PFS.MBBSlots); 3001*0b57cec5SDimitry Andric } 3002*0b57cec5SDimitry Andric 3003*0b57cec5SDimitry Andric bool llvm::parseMachineInstructions(PerFunctionMIParsingState &PFS, 3004*0b57cec5SDimitry Andric StringRef Src, SMDiagnostic &Error) { 3005*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseBasicBlocks(); 3006*0b57cec5SDimitry Andric } 3007*0b57cec5SDimitry Andric 3008*0b57cec5SDimitry Andric bool llvm::parseMBBReference(PerFunctionMIParsingState &PFS, 3009*0b57cec5SDimitry Andric MachineBasicBlock *&MBB, StringRef Src, 3010*0b57cec5SDimitry Andric SMDiagnostic &Error) { 3011*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMBB(MBB); 3012*0b57cec5SDimitry Andric } 3013*0b57cec5SDimitry Andric 3014*0b57cec5SDimitry Andric bool llvm::parseRegisterReference(PerFunctionMIParsingState &PFS, 3015*0b57cec5SDimitry Andric unsigned &Reg, StringRef Src, 3016*0b57cec5SDimitry Andric SMDiagnostic &Error) { 3017*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneRegister(Reg); 3018*0b57cec5SDimitry Andric } 3019*0b57cec5SDimitry Andric 3020*0b57cec5SDimitry Andric bool llvm::parseNamedRegisterReference(PerFunctionMIParsingState &PFS, 3021*0b57cec5SDimitry Andric unsigned &Reg, StringRef Src, 3022*0b57cec5SDimitry Andric SMDiagnostic &Error) { 3023*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneNamedRegister(Reg); 3024*0b57cec5SDimitry Andric } 3025*0b57cec5SDimitry Andric 3026*0b57cec5SDimitry Andric bool llvm::parseVirtualRegisterReference(PerFunctionMIParsingState &PFS, 3027*0b57cec5SDimitry Andric VRegInfo *&Info, StringRef Src, 3028*0b57cec5SDimitry Andric SMDiagnostic &Error) { 3029*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneVirtualRegister(Info); 3030*0b57cec5SDimitry Andric } 3031*0b57cec5SDimitry Andric 3032*0b57cec5SDimitry Andric bool llvm::parseStackObjectReference(PerFunctionMIParsingState &PFS, 3033*0b57cec5SDimitry Andric int &FI, StringRef Src, 3034*0b57cec5SDimitry Andric SMDiagnostic &Error) { 3035*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneStackObject(FI); 3036*0b57cec5SDimitry Andric } 3037*0b57cec5SDimitry Andric 3038*0b57cec5SDimitry Andric bool llvm::parseMDNode(PerFunctionMIParsingState &PFS, 3039*0b57cec5SDimitry Andric MDNode *&Node, StringRef Src, SMDiagnostic &Error) { 3040*0b57cec5SDimitry Andric return MIParser(PFS, Error, Src).parseStandaloneMDNode(Node); 3041*0b57cec5SDimitry Andric } 3042