1218885Sdim//===-- MBlazeAsmParser.cpp - Parse MBlaze asm to MCInst instructions -----===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim 10226633Sdim#include "MCTargetDesc/MBlazeBaseInfo.h" 11249423Sdim#include "llvm/ADT/SmallVector.h" 12249423Sdim#include "llvm/ADT/Twine.h" 13249423Sdim#include "llvm/MC/MCExpr.h" 14249423Sdim#include "llvm/MC/MCInst.h" 15218885Sdim#include "llvm/MC/MCParser/MCAsmLexer.h" 16218885Sdim#include "llvm/MC/MCParser/MCAsmParser.h" 17218885Sdim#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 18218885Sdim#include "llvm/MC/MCStreamer.h" 19226633Sdim#include "llvm/MC/MCTargetAsmParser.h" 20218885Sdim#include "llvm/Support/SourceMgr.h" 21226633Sdim#include "llvm/Support/TargetRegistry.h" 22218885Sdim#include "llvm/Support/raw_ostream.h" 23218885Sdimusing namespace llvm; 24218885Sdim 25218885Sdimnamespace { 26218885Sdimstruct MBlazeOperand; 27218885Sdim 28226633Sdimclass MBlazeAsmParser : public MCTargetAsmParser { 29218885Sdim MCAsmParser &Parser; 30218885Sdim 31218885Sdim MCAsmParser &getParser() const { return Parser; } 32218885Sdim MCAsmLexer &getLexer() const { return Parser.getLexer(); } 33218885Sdim 34218885Sdim void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 35218885Sdim bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 36218885Sdim 37218885Sdim MBlazeOperand *ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 38249423Sdim MBlazeOperand *ParseRegister(); 39249423Sdim MBlazeOperand *ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc); 40218885Sdim MBlazeOperand *ParseImmediate(); 41218885Sdim MBlazeOperand *ParseFsl(); 42218885Sdim MBlazeOperand* ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 43218885Sdim 44218885Sdim virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 45218885Sdim 46218885Sdim bool ParseDirectiveWord(unsigned Size, SMLoc L); 47218885Sdim 48243830Sdim bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 49218885Sdim SmallVectorImpl<MCParsedAsmOperand*> &Operands, 50243830Sdim MCStreamer &Out, unsigned &ErrorInfo, 51243830Sdim bool MatchingInlineAsm); 52218885Sdim 53218885Sdim /// @name Auto-generated Match Functions 54218885Sdim /// { 55218885Sdim 56218885Sdim#define GET_ASSEMBLER_HEADER 57218885Sdim#include "MBlazeGenAsmMatcher.inc" 58218885Sdim 59218885Sdim /// } 60218885Sdim 61218885Sdimpublic: 62224145Sdim MBlazeAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 63226633Sdim : MCTargetAsmParser(), Parser(_Parser) {} 64218885Sdim 65243830Sdim virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 66243830Sdim SMLoc NameLoc, 67218885Sdim SmallVectorImpl<MCParsedAsmOperand*> &Operands); 68218885Sdim 69218885Sdim virtual bool ParseDirective(AsmToken DirectiveID); 70218885Sdim}; 71218885Sdim 72218885Sdim/// MBlazeOperand - Instances of this class represent a parsed MBlaze machine 73218885Sdim/// instruction. 74218885Sdimstruct MBlazeOperand : public MCParsedAsmOperand { 75218885Sdim enum KindTy { 76218885Sdim Token, 77218885Sdim Immediate, 78218885Sdim Register, 79218885Sdim Memory, 80218885Sdim Fsl 81218885Sdim } Kind; 82218885Sdim 83218885Sdim SMLoc StartLoc, EndLoc; 84218885Sdim 85249423Sdim struct TokOp { 86249423Sdim const char *Data; 87249423Sdim unsigned Length; 88249423Sdim }; 89218885Sdim 90249423Sdim struct RegOp { 91249423Sdim unsigned RegNum; 92249423Sdim }; 93218885Sdim 94249423Sdim struct ImmOp { 95249423Sdim const MCExpr *Val; 96249423Sdim }; 97218885Sdim 98249423Sdim struct MemOp { 99249423Sdim unsigned Base; 100249423Sdim unsigned OffReg; 101249423Sdim const MCExpr *Off; 102249423Sdim }; 103218885Sdim 104249423Sdim struct FslImmOp { 105249423Sdim const MCExpr *Val; 106218885Sdim }; 107218885Sdim 108249423Sdim union { 109249423Sdim struct TokOp Tok; 110249423Sdim struct RegOp Reg; 111249423Sdim struct ImmOp Imm; 112249423Sdim struct MemOp Mem; 113249423Sdim struct FslImmOp FslImm; 114249423Sdim }; 115249423Sdim 116218885Sdim MBlazeOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 117218885Sdimpublic: 118218885Sdim MBlazeOperand(const MBlazeOperand &o) : MCParsedAsmOperand() { 119218885Sdim Kind = o.Kind; 120218885Sdim StartLoc = o.StartLoc; 121218885Sdim EndLoc = o.EndLoc; 122218885Sdim switch (Kind) { 123218885Sdim case Register: 124218885Sdim Reg = o.Reg; 125218885Sdim break; 126218885Sdim case Immediate: 127218885Sdim Imm = o.Imm; 128218885Sdim break; 129218885Sdim case Token: 130218885Sdim Tok = o.Tok; 131218885Sdim break; 132218885Sdim case Memory: 133218885Sdim Mem = o.Mem; 134218885Sdim break; 135218885Sdim case Fsl: 136218885Sdim FslImm = o.FslImm; 137218885Sdim break; 138218885Sdim } 139218885Sdim } 140218885Sdim 141218885Sdim /// getStartLoc - Get the location of the first token of this operand. 142218885Sdim SMLoc getStartLoc() const { return StartLoc; } 143218885Sdim 144218885Sdim /// getEndLoc - Get the location of the last token of this operand. 145218885Sdim SMLoc getEndLoc() const { return EndLoc; } 146218885Sdim 147218885Sdim unsigned getReg() const { 148218885Sdim assert(Kind == Register && "Invalid access!"); 149218885Sdim return Reg.RegNum; 150218885Sdim } 151218885Sdim 152218885Sdim const MCExpr *getImm() const { 153218885Sdim assert(Kind == Immediate && "Invalid access!"); 154218885Sdim return Imm.Val; 155218885Sdim } 156218885Sdim 157218885Sdim const MCExpr *getFslImm() const { 158218885Sdim assert(Kind == Fsl && "Invalid access!"); 159218885Sdim return FslImm.Val; 160218885Sdim } 161218885Sdim 162218885Sdim unsigned getMemBase() const { 163218885Sdim assert(Kind == Memory && "Invalid access!"); 164218885Sdim return Mem.Base; 165218885Sdim } 166218885Sdim 167218885Sdim const MCExpr* getMemOff() const { 168218885Sdim assert(Kind == Memory && "Invalid access!"); 169218885Sdim return Mem.Off; 170218885Sdim } 171218885Sdim 172218885Sdim unsigned getMemOffReg() const { 173218885Sdim assert(Kind == Memory && "Invalid access!"); 174218885Sdim return Mem.OffReg; 175218885Sdim } 176218885Sdim 177218885Sdim bool isToken() const { return Kind == Token; } 178218885Sdim bool isImm() const { return Kind == Immediate; } 179218885Sdim bool isMem() const { return Kind == Memory; } 180218885Sdim bool isFsl() const { return Kind == Fsl; } 181218885Sdim bool isReg() const { return Kind == Register; } 182218885Sdim 183218885Sdim void addExpr(MCInst &Inst, const MCExpr *Expr) const { 184218885Sdim // Add as immediates when possible. Null MCExpr = 0. 185218885Sdim if (Expr == 0) 186218885Sdim Inst.addOperand(MCOperand::CreateImm(0)); 187218885Sdim else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 188218885Sdim Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 189218885Sdim else 190218885Sdim Inst.addOperand(MCOperand::CreateExpr(Expr)); 191218885Sdim } 192218885Sdim 193218885Sdim void addRegOperands(MCInst &Inst, unsigned N) const { 194218885Sdim assert(N == 1 && "Invalid number of operands!"); 195218885Sdim Inst.addOperand(MCOperand::CreateReg(getReg())); 196218885Sdim } 197218885Sdim 198218885Sdim void addImmOperands(MCInst &Inst, unsigned N) const { 199218885Sdim assert(N == 1 && "Invalid number of operands!"); 200218885Sdim addExpr(Inst, getImm()); 201218885Sdim } 202218885Sdim 203218885Sdim void addFslOperands(MCInst &Inst, unsigned N) const { 204218885Sdim assert(N == 1 && "Invalid number of operands!"); 205218885Sdim addExpr(Inst, getFslImm()); 206218885Sdim } 207218885Sdim 208218885Sdim void addMemOperands(MCInst &Inst, unsigned N) const { 209218885Sdim assert(N == 2 && "Invalid number of operands!"); 210218885Sdim 211218885Sdim Inst.addOperand(MCOperand::CreateReg(getMemBase())); 212218885Sdim 213218885Sdim unsigned RegOff = getMemOffReg(); 214218885Sdim if (RegOff) 215218885Sdim Inst.addOperand(MCOperand::CreateReg(RegOff)); 216218885Sdim else 217218885Sdim addExpr(Inst, getMemOff()); 218218885Sdim } 219218885Sdim 220218885Sdim StringRef getToken() const { 221218885Sdim assert(Kind == Token && "Invalid access!"); 222218885Sdim return StringRef(Tok.Data, Tok.Length); 223218885Sdim } 224218885Sdim 225224145Sdim virtual void print(raw_ostream &OS) const; 226218885Sdim 227218885Sdim static MBlazeOperand *CreateToken(StringRef Str, SMLoc S) { 228218885Sdim MBlazeOperand *Op = new MBlazeOperand(Token); 229218885Sdim Op->Tok.Data = Str.data(); 230218885Sdim Op->Tok.Length = Str.size(); 231218885Sdim Op->StartLoc = S; 232218885Sdim Op->EndLoc = S; 233218885Sdim return Op; 234218885Sdim } 235218885Sdim 236218885Sdim static MBlazeOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 237218885Sdim MBlazeOperand *Op = new MBlazeOperand(Register); 238218885Sdim Op->Reg.RegNum = RegNum; 239218885Sdim Op->StartLoc = S; 240218885Sdim Op->EndLoc = E; 241218885Sdim return Op; 242218885Sdim } 243218885Sdim 244218885Sdim static MBlazeOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 245218885Sdim MBlazeOperand *Op = new MBlazeOperand(Immediate); 246218885Sdim Op->Imm.Val = Val; 247218885Sdim Op->StartLoc = S; 248218885Sdim Op->EndLoc = E; 249218885Sdim return Op; 250218885Sdim } 251218885Sdim 252218885Sdim static MBlazeOperand *CreateFslImm(const MCExpr *Val, SMLoc S, SMLoc E) { 253218885Sdim MBlazeOperand *Op = new MBlazeOperand(Fsl); 254218885Sdim Op->Imm.Val = Val; 255218885Sdim Op->StartLoc = S; 256218885Sdim Op->EndLoc = E; 257218885Sdim return Op; 258218885Sdim } 259218885Sdim 260218885Sdim static MBlazeOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S, 261218885Sdim SMLoc E) { 262218885Sdim MBlazeOperand *Op = new MBlazeOperand(Memory); 263218885Sdim Op->Mem.Base = Base; 264218885Sdim Op->Mem.Off = Off; 265218885Sdim Op->Mem.OffReg = 0; 266218885Sdim Op->StartLoc = S; 267218885Sdim Op->EndLoc = E; 268218885Sdim return Op; 269218885Sdim } 270218885Sdim 271218885Sdim static MBlazeOperand *CreateMem(unsigned Base, unsigned Off, SMLoc S, 272218885Sdim SMLoc E) { 273218885Sdim MBlazeOperand *Op = new MBlazeOperand(Memory); 274218885Sdim Op->Mem.Base = Base; 275218885Sdim Op->Mem.OffReg = Off; 276218885Sdim Op->Mem.Off = 0; 277218885Sdim Op->StartLoc = S; 278218885Sdim Op->EndLoc = E; 279218885Sdim return Op; 280218885Sdim } 281218885Sdim}; 282218885Sdim 283218885Sdim} // end anonymous namespace. 284218885Sdim 285224145Sdimvoid MBlazeOperand::print(raw_ostream &OS) const { 286218885Sdim switch (Kind) { 287218885Sdim case Immediate: 288218885Sdim getImm()->print(OS); 289218885Sdim break; 290218885Sdim case Register: 291218885Sdim OS << "<register R"; 292226633Sdim OS << getMBlazeRegisterNumbering(getReg()) << ">"; 293218885Sdim break; 294218885Sdim case Token: 295218885Sdim OS << "'" << getToken() << "'"; 296218885Sdim break; 297218885Sdim case Memory: { 298218885Sdim OS << "<memory R"; 299226633Sdim OS << getMBlazeRegisterNumbering(getMemBase()); 300218885Sdim OS << ", "; 301218885Sdim 302218885Sdim unsigned RegOff = getMemOffReg(); 303218885Sdim if (RegOff) 304226633Sdim OS << "R" << getMBlazeRegisterNumbering(RegOff); 305218885Sdim else 306218885Sdim OS << getMemOff(); 307218885Sdim OS << ">"; 308218885Sdim } 309218885Sdim break; 310218885Sdim case Fsl: 311218885Sdim getFslImm()->print(OS); 312218885Sdim break; 313218885Sdim } 314218885Sdim} 315218885Sdim 316218885Sdim/// @name Auto-generated Match Functions 317218885Sdim/// { 318218885Sdim 319218885Sdimstatic unsigned MatchRegisterName(StringRef Name); 320218885Sdim 321218885Sdim/// } 322218885Sdim// 323218885Sdimbool MBlazeAsmParser:: 324243830SdimMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 325218885Sdim SmallVectorImpl<MCParsedAsmOperand*> &Operands, 326243830Sdim MCStreamer &Out, unsigned &ErrorInfo, 327243830Sdim bool MatchingInlineAsm) { 328218885Sdim MCInst Inst; 329243830Sdim switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, 330243830Sdim MatchingInlineAsm)) { 331226633Sdim default: break; 332218885Sdim case Match_Success: 333218885Sdim Out.EmitInstruction(Inst); 334218885Sdim return false; 335218885Sdim case Match_MissingFeature: 336218885Sdim return Error(IDLoc, "instruction use requires an option to be enabled"); 337218885Sdim case Match_MnemonicFail: 338218885Sdim return Error(IDLoc, "unrecognized instruction mnemonic"); 339243830Sdim case Match_InvalidOperand: { 340243830Sdim SMLoc ErrorLoc = IDLoc; 341218885Sdim if (ErrorInfo != ~0U) { 342218885Sdim if (ErrorInfo >= Operands.size()) 343218885Sdim return Error(IDLoc, "too few operands for instruction"); 344218885Sdim 345218885Sdim ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc(); 346218885Sdim if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 347218885Sdim } 348218885Sdim 349218885Sdim return Error(ErrorLoc, "invalid operand for instruction"); 350218885Sdim } 351243830Sdim } 352218885Sdim 353218885Sdim llvm_unreachable("Implement any new match types added!"); 354218885Sdim} 355218885Sdim 356218885SdimMBlazeOperand *MBlazeAsmParser:: 357218885SdimParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 358218885Sdim if (Operands.size() != 4) 359218885Sdim return 0; 360218885Sdim 361218885Sdim MBlazeOperand &Base = *(MBlazeOperand*)Operands[2]; 362218885Sdim MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3]; 363218885Sdim 364218885Sdim SMLoc S = Base.getStartLoc(); 365218885Sdim SMLoc O = Offset.getStartLoc(); 366218885Sdim SMLoc E = Offset.getEndLoc(); 367218885Sdim 368218885Sdim if (!Base.isReg()) { 369218885Sdim Error(S, "base address must be a register"); 370218885Sdim return 0; 371218885Sdim } 372218885Sdim 373218885Sdim if (!Offset.isReg() && !Offset.isImm()) { 374218885Sdim Error(O, "offset must be a register or immediate"); 375218885Sdim return 0; 376218885Sdim } 377218885Sdim 378218885Sdim MBlazeOperand *Op; 379218885Sdim if (Offset.isReg()) 380218885Sdim Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E); 381218885Sdim else 382218885Sdim Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E); 383218885Sdim 384218885Sdim delete Operands.pop_back_val(); 385218885Sdim delete Operands.pop_back_val(); 386218885Sdim Operands.push_back(Op); 387218885Sdim 388218885Sdim return Op; 389218885Sdim} 390218885Sdim 391218885Sdimbool MBlazeAsmParser::ParseRegister(unsigned &RegNo, 392218885Sdim SMLoc &StartLoc, SMLoc &EndLoc) { 393249423Sdim MBlazeOperand *Reg = ParseRegister(StartLoc, EndLoc); 394249423Sdim if (!Reg) 395249423Sdim return true; 396249423Sdim RegNo = Reg->getReg(); 397249423Sdim return false; 398218885Sdim} 399218885Sdim 400249423SdimMBlazeOperand *MBlazeAsmParser::ParseRegister() { 401249423Sdim SMLoc S, E; 402249423Sdim return ParseRegister(S, E); 403249423Sdim} 404218885Sdim 405249423SdimMBlazeOperand *MBlazeAsmParser::ParseRegister(SMLoc &StartLoc, SMLoc &EndLoc) { 406249423Sdim StartLoc = Parser.getTok().getLoc(); 407249423Sdim EndLoc = Parser.getTok().getEndLoc(); 408218885Sdim 409249423Sdim if (getLexer().getKind() != AsmToken::Identifier) 410249423Sdim return 0; 411249423Sdim 412249423Sdim unsigned RegNo = MatchRegisterName(getLexer().getTok().getIdentifier()); 413249423Sdim if (RegNo == 0) 414249423Sdim return 0; 415249423Sdim 416249423Sdim getLexer().Lex(); 417249423Sdim return MBlazeOperand::CreateReg(RegNo, StartLoc, EndLoc); 418218885Sdim} 419218885Sdim 420218885Sdimstatic unsigned MatchFslRegister(StringRef String) { 421218885Sdim if (!String.startswith("rfsl")) 422218885Sdim return -1; 423218885Sdim 424218885Sdim unsigned regNum; 425218885Sdim if (String.substr(4).getAsInteger(10,regNum)) 426218885Sdim return -1; 427218885Sdim 428218885Sdim return regNum; 429218885Sdim} 430218885Sdim 431218885SdimMBlazeOperand *MBlazeAsmParser::ParseFsl() { 432218885Sdim SMLoc S = Parser.getTok().getLoc(); 433249423Sdim SMLoc E = Parser.getTok().getEndLoc(); 434218885Sdim 435218885Sdim switch (getLexer().getKind()) { 436218885Sdim default: return 0; 437218885Sdim case AsmToken::Identifier: 438218885Sdim unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier()); 439218885Sdim if (reg >= 16) 440218885Sdim return 0; 441218885Sdim 442218885Sdim getLexer().Lex(); 443218885Sdim const MCExpr *EVal = MCConstantExpr::Create(reg,getContext()); 444218885Sdim return MBlazeOperand::CreateFslImm(EVal,S,E); 445218885Sdim } 446218885Sdim} 447218885Sdim 448218885SdimMBlazeOperand *MBlazeAsmParser::ParseImmediate() { 449218885Sdim SMLoc S = Parser.getTok().getLoc(); 450249423Sdim SMLoc E = Parser.getTok().getEndLoc(); 451218885Sdim 452218885Sdim const MCExpr *EVal; 453218885Sdim switch (getLexer().getKind()) { 454218885Sdim default: return 0; 455218885Sdim case AsmToken::LParen: 456218885Sdim case AsmToken::Plus: 457218885Sdim case AsmToken::Minus: 458218885Sdim case AsmToken::Integer: 459218885Sdim case AsmToken::Identifier: 460249423Sdim if (getParser().parseExpression(EVal)) 461218885Sdim return 0; 462218885Sdim 463218885Sdim return MBlazeOperand::CreateImm(EVal, S, E); 464218885Sdim } 465218885Sdim} 466218885Sdim 467218885SdimMBlazeOperand *MBlazeAsmParser:: 468218885SdimParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 469218885Sdim MBlazeOperand *Op; 470218885Sdim 471218885Sdim // Attempt to parse the next token as a register name 472249423Sdim Op = ParseRegister(); 473218885Sdim 474218885Sdim // Attempt to parse the next token as an FSL immediate 475218885Sdim if (!Op) 476218885Sdim Op = ParseFsl(); 477218885Sdim 478218885Sdim // Attempt to parse the next token as an immediate 479218885Sdim if (!Op) 480218885Sdim Op = ParseImmediate(); 481218885Sdim 482218885Sdim // If the token could not be parsed then fail 483218885Sdim if (!Op) { 484218885Sdim Error(Parser.getTok().getLoc(), "unknown operand"); 485218885Sdim return 0; 486218885Sdim } 487218885Sdim 488218885Sdim // Push the parsed operand into the list of operands 489218885Sdim Operands.push_back(Op); 490218885Sdim return Op; 491218885Sdim} 492218885Sdim 493218885Sdim/// Parse an mblaze instruction mnemonic followed by its operands. 494218885Sdimbool MBlazeAsmParser:: 495243830SdimParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 496218885Sdim SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 497218885Sdim // The first operands is the token for the instruction name 498218885Sdim size_t dotLoc = Name.find('.'); 499218885Sdim Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc)); 500218885Sdim if (dotLoc < Name.size()) 501218885Sdim Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc)); 502218885Sdim 503218885Sdim // If there are no more operands then finish 504218885Sdim if (getLexer().is(AsmToken::EndOfStatement)) 505218885Sdim return false; 506218885Sdim 507218885Sdim // Parse the first operand 508218885Sdim if (!ParseOperand(Operands)) 509218885Sdim return true; 510218885Sdim 511218885Sdim while (getLexer().isNot(AsmToken::EndOfStatement) && 512218885Sdim getLexer().is(AsmToken::Comma)) { 513218885Sdim // Consume the comma token 514218885Sdim getLexer().Lex(); 515218885Sdim 516218885Sdim // Parse the next operand 517218885Sdim if (!ParseOperand(Operands)) 518218885Sdim return true; 519218885Sdim } 520218885Sdim 521218885Sdim // If the instruction requires a memory operand then we need to 522218885Sdim // replace the last two operands (base+offset) with a single 523218885Sdim // memory operand. 524218885Sdim if (Name.startswith("lw") || Name.startswith("sw") || 525218885Sdim Name.startswith("lh") || Name.startswith("sh") || 526218885Sdim Name.startswith("lb") || Name.startswith("sb")) 527218885Sdim return (ParseMemory(Operands) == NULL); 528218885Sdim 529218885Sdim return false; 530218885Sdim} 531218885Sdim 532226633Sdim/// ParseDirective parses the MBlaze specific directives 533218885Sdimbool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) { 534218885Sdim StringRef IDVal = DirectiveID.getIdentifier(); 535218885Sdim if (IDVal == ".word") 536218885Sdim return ParseDirectiveWord(2, DirectiveID.getLoc()); 537218885Sdim return true; 538218885Sdim} 539218885Sdim 540218885Sdim/// ParseDirectiveWord 541218885Sdim/// ::= .word [ expression (, expression)* ] 542218885Sdimbool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 543218885Sdim if (getLexer().isNot(AsmToken::EndOfStatement)) { 544218885Sdim for (;;) { 545218885Sdim const MCExpr *Value; 546249423Sdim if (getParser().parseExpression(Value)) 547218885Sdim return true; 548218885Sdim 549249423Sdim getParser().getStreamer().EmitValue(Value, Size); 550218885Sdim 551218885Sdim if (getLexer().is(AsmToken::EndOfStatement)) 552218885Sdim break; 553218885Sdim 554218885Sdim // FIXME: Improve diagnostic. 555218885Sdim if (getLexer().isNot(AsmToken::Comma)) 556218885Sdim return Error(L, "unexpected token in directive"); 557218885Sdim Parser.Lex(); 558218885Sdim } 559218885Sdim } 560218885Sdim 561218885Sdim Parser.Lex(); 562218885Sdim return false; 563218885Sdim} 564218885Sdim 565218885Sdim/// Force static initialization. 566218885Sdimextern "C" void LLVMInitializeMBlazeAsmParser() { 567226633Sdim RegisterMCAsmParser<MBlazeAsmParser> X(TheMBlazeTarget); 568218885Sdim} 569218885Sdim 570218885Sdim#define GET_REGISTER_MATCHER 571218885Sdim#define GET_MATCHER_IMPLEMENTATION 572218885Sdim#include "MBlazeGenAsmMatcher.inc" 573