diff options
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index 5a88a8d21a5..dec06bc9cc8 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -56,6 +56,8 @@ class MIParser { StringMap<unsigned> Names2Regs; /// Maps from register mask names to register masks. StringMap<const uint32_t *> Names2RegMasks; + /// Maps from subregister names to subregister indices. + StringMap<unsigned> Names2SubRegIndices; public: MIParser(SourceMgr &SM, MachineFunction &MF, SMDiagnostic &Error, @@ -79,6 +81,7 @@ public: bool parseRegister(unsigned &Reg); bool parseRegisterFlag(unsigned &Flags); + bool parseSubRegisterIndex(unsigned &SubReg); bool parseRegisterOperand(MachineOperand &Dest, bool IsDef = false); bool parseImmediateOperand(MachineOperand &Dest); bool parseMBBReference(MachineBasicBlock *&MBB); @@ -115,6 +118,13 @@ private: /// /// Return null if the identifier isn't a register mask. const uint32_t *getRegMask(StringRef Identifier); + + void initNames2SubRegIndices(); + + /// Check if the given identifier is a name of a subregister index. + /// + /// Return 0 if the name isn't a subregister index class. + unsigned getSubRegIndex(StringRef Name); }; } // end anonymous namespace @@ -332,6 +342,19 @@ bool MIParser::parseRegisterFlag(unsigned &Flags) { return false; } +bool MIParser::parseSubRegisterIndex(unsigned &SubReg) { + assert(Token.is(MIToken::colon)); + lex(); + if (Token.isNot(MIToken::Identifier)) + return error("expected a subregister index after ':'"); + auto Name = Token.stringValue(); + SubReg = getSubRegIndex(Name); + if (!SubReg) + return error(Twine("use of unknown subregister index '") + Name + "'"); + lex(); + return false; +} + bool MIParser::parseRegisterOperand(MachineOperand &Dest, bool IsDef) { unsigned Reg; unsigned Flags = IsDef ? RegState::Define : 0; @@ -344,10 +367,15 @@ bool MIParser::parseRegisterOperand(MachineOperand &Dest, bool IsDef) { if (parseRegister(Reg)) return true; lex(); - // TODO: Parse subregister. + unsigned SubReg = 0; + if (Token.is(MIToken::colon)) { + if (parseSubRegisterIndex(SubReg)) + return true; + } Dest = MachineOperand::CreateReg( Reg, Flags & RegState::Define, Flags & RegState::Implicit, - Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef); + Flags & RegState::Kill, Flags & RegState::Dead, Flags & RegState::Undef, + /*isEarlyClobber=*/false, SubReg); return false; } @@ -525,6 +553,23 @@ const uint32_t *MIParser::getRegMask(StringRef Identifier) { return RegMaskInfo->getValue(); } +void MIParser::initNames2SubRegIndices() { + if (!Names2SubRegIndices.empty()) + return; + const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo(); + for (unsigned I = 1, E = TRI->getNumSubRegIndices(); I < E; ++I) + Names2SubRegIndices.insert( + std::make_pair(StringRef(TRI->getSubRegIndexName(I)).lower(), I)); +} + +unsigned MIParser::getSubRegIndex(StringRef Name) { + initNames2SubRegIndices(); + auto SubRegInfo = Names2SubRegIndices.find(Name); + if (SubRegInfo == Names2SubRegIndices.end()) + return 0; + return SubRegInfo->getValue(); +} + bool llvm::parseMachineInstr(MachineInstr *&MI, SourceMgr &SM, MachineFunction &MF, StringRef Src, const PerFunctionMIParsingState &PFS, |