MBlazeAsmParser.cpp revision 243830
1117119Stmm//===-- MBlazeAsmParser.cpp - Parse MBlaze asm to MCInst instructions -----===// 2117119Stmm// 3117119Stmm// The LLVM Compiler Infrastructure 4117119Stmm// 5117119Stmm// This file is distributed under the University of Illinois Open Source 6117119Stmm// License. See LICENSE.TXT for details. 7117119Stmm// 8117119Stmm//===----------------------------------------------------------------------===// 9117119Stmm 10117119Stmm#include "MCTargetDesc/MBlazeBaseInfo.h" 11117119Stmm#include "llvm/MC/MCParser/MCAsmLexer.h" 12117119Stmm#include "llvm/MC/MCParser/MCAsmParser.h" 13117119Stmm#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 14117119Stmm#include "llvm/MC/MCStreamer.h" 15117119Stmm#include "llvm/MC/MCExpr.h" 16117119Stmm#include "llvm/MC/MCInst.h" 17117119Stmm#include "llvm/MC/MCTargetAsmParser.h" 18117119Stmm#include "llvm/Support/SourceMgr.h" 19117119Stmm#include "llvm/Support/TargetRegistry.h" 20117119Stmm#include "llvm/Support/raw_ostream.h" 21117119Stmm#include "llvm/ADT/SmallVector.h" 22117119Stmm#include "llvm/ADT/Twine.h" 23117119Stmmusing namespace llvm; 24117119Stmm 25117119Stmmnamespace { 26117119Stmmstruct MBlazeOperand; 27117119Stmm 28117119Stmmclass MBlazeAsmParser : public MCTargetAsmParser { 29117119Stmm MCAsmParser &Parser; 30152684Smarius 31152684Smarius MCAsmParser &getParser() const { return Parser; } 32152684Smarius MCAsmLexer &getLexer() const { return Parser.getLexer(); } 33117119Stmm 34133589Smarius void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); } 35117119Stmm bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); } 36117119Stmm 37117119Stmm MBlazeOperand *ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 38117119Stmm MBlazeOperand *ParseRegister(unsigned &RegNo); 39117119Stmm MBlazeOperand *ParseImmediate(); 40117119Stmm MBlazeOperand *ParseFsl(); 41117119Stmm MBlazeOperand* ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 42133589Smarius 43152684Smarius virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 44133589Smarius 45117119Stmm bool ParseDirectiveWord(unsigned Size, SMLoc L); 46117119Stmm 47117119Stmm bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 48117119Stmm SmallVectorImpl<MCParsedAsmOperand*> &Operands, 49163146Skmacy MCStreamer &Out, unsigned &ErrorInfo, 50117119Stmm bool MatchingInlineAsm); 51163146Skmacy 52117119Stmm /// @name Auto-generated Match Functions 53117119Stmm /// { 54117119Stmm 55117119Stmm#define GET_ASSEMBLER_HEADER 56117119Stmm#include "MBlazeGenAsmMatcher.inc" 57117119Stmm 58117119Stmm /// } 59117119Stmm 60117119Stmmpublic: 61117119Stmm MBlazeAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser) 62117119Stmm : MCTargetAsmParser(), Parser(_Parser) {} 63117119Stmm 64117119Stmm virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 65117119Stmm SMLoc NameLoc, 66117119Stmm SmallVectorImpl<MCParsedAsmOperand*> &Operands); 67117119Stmm 68117119Stmm virtual bool ParseDirective(AsmToken DirectiveID); 69117119Stmm}; 70117119Stmm 71152684Smarius/// MBlazeOperand - Instances of this class represent a parsed MBlaze machine 72117119Stmm/// instruction. 73117119Stmmstruct MBlazeOperand : public MCParsedAsmOperand { 74117119Stmm enum KindTy { 75117119Stmm Token, 76117119Stmm Immediate, 77117119Stmm Register, 78117119Stmm Memory, 79117119Stmm Fsl 80117119Stmm } Kind; 81117119Stmm 82117119Stmm SMLoc StartLoc, EndLoc; 83133589Smarius 84152684Smarius union { 85152684Smarius struct { 86152684Smarius const char *Data; 87152684Smarius unsigned Length; 88152684Smarius } Tok; 89152684Smarius 90117119Stmm struct { 91117119Stmm unsigned RegNum; 92117119Stmm } Reg; 93117119Stmm 94117119Stmm struct { 95117119Stmm const MCExpr *Val; 96152684Smarius } Imm; 97117119Stmm 98117119Stmm struct { 99117119Stmm unsigned Base; 100117119Stmm unsigned OffReg; 101117119Stmm const MCExpr *Off; 102117119Stmm } Mem; 103154600Sjhb 104117119Stmm struct { 105154600Sjhb const MCExpr *Val; 106154600Sjhb } FslImm; 107117119Stmm }; 108117119Stmm 109117119Stmm MBlazeOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 110117119Stmmpublic: 111117119Stmm MBlazeOperand(const MBlazeOperand &o) : MCParsedAsmOperand() { 112117119Stmm Kind = o.Kind; 113117119Stmm StartLoc = o.StartLoc; 114117119Stmm EndLoc = o.EndLoc; 115133589Smarius switch (Kind) { 116117119Stmm case Register: 117117119Stmm Reg = o.Reg; 118117119Stmm break; 119117119Stmm case Immediate: 120117119Stmm Imm = o.Imm; 121117119Stmm break; 122117119Stmm case Token: 123117119Stmm Tok = o.Tok; 124117119Stmm break; 125117119Stmm case Memory: 126117119Stmm Mem = o.Mem; 127117119Stmm break; 128163146Skmacy case Fsl: 129163146Skmacy FslImm = o.FslImm; 130163146Skmacy break; 131163146Skmacy } 132117119Stmm } 133117119Stmm 134117119Stmm /// getStartLoc - Get the location of the first token of this operand. 135117119Stmm SMLoc getStartLoc() const { return StartLoc; } 136117119Stmm 137117119Stmm /// getEndLoc - Get the location of the last token of this operand. 138117119Stmm SMLoc getEndLoc() const { return EndLoc; } 139117119Stmm 140117119Stmm unsigned getReg() const { 141117119Stmm assert(Kind == Register && "Invalid access!"); 142117119Stmm return Reg.RegNum; 143117119Stmm } 144117119Stmm 145117119Stmm const MCExpr *getImm() const { 146117119Stmm assert(Kind == Immediate && "Invalid access!"); 147117119Stmm return Imm.Val; 148117119Stmm } 149117119Stmm 150133774Smarius const MCExpr *getFslImm() const { 151117119Stmm assert(Kind == Fsl && "Invalid access!"); 152117119Stmm return FslImm.Val; 153163146Skmacy } 154117119Stmm 155117119Stmm unsigned getMemBase() const { 156117119Stmm assert(Kind == Memory && "Invalid access!"); 157117119Stmm return Mem.Base; 158117119Stmm } 159133774Smarius 160117119Stmm const MCExpr* getMemOff() const { 161117119Stmm assert(Kind == Memory && "Invalid access!"); 162117119Stmm return Mem.Off; 163117119Stmm } 164117119Stmm 165117119Stmm unsigned getMemOffReg() const { 166163146Skmacy assert(Kind == Memory && "Invalid access!"); 167117119Stmm return Mem.OffReg; 168117119Stmm } 169117119Stmm 170117119Stmm bool isToken() const { return Kind == Token; } 171117119Stmm bool isImm() const { return Kind == Immediate; } 172117119Stmm bool isMem() const { return Kind == Memory; } 173117119Stmm bool isFsl() const { return Kind == Fsl; } 174117119Stmm bool isReg() const { return Kind == Register; } 175117119Stmm 176117119Stmm void addExpr(MCInst &Inst, const MCExpr *Expr) const { 177117119Stmm // Add as immediates when possible. Null MCExpr = 0. 178153057Smarius if (Expr == 0) 179117119Stmm Inst.addOperand(MCOperand::CreateImm(0)); 180117119Stmm else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 181117119Stmm Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 182117119Stmm else 183117119Stmm Inst.addOperand(MCOperand::CreateExpr(Expr)); 184153057Smarius } 185153057Smarius 186117119Stmm void addRegOperands(MCInst &Inst, unsigned N) const { 187117119Stmm assert(N == 1 && "Invalid number of operands!"); 188117119Stmm Inst.addOperand(MCOperand::CreateReg(getReg())); 189117119Stmm } 190117119Stmm 191117119Stmm void addImmOperands(MCInst &Inst, unsigned N) const { 192117119Stmm assert(N == 1 && "Invalid number of operands!"); 193117119Stmm addExpr(Inst, getImm()); 194133589Smarius } 195117119Stmm 196152684Smarius void addFslOperands(MCInst &Inst, unsigned N) const { 197140512Smarius assert(N == 1 && "Invalid number of operands!"); 198117119Stmm addExpr(Inst, getFslImm()); 199117119Stmm } 200117119Stmm 201117119Stmm void addMemOperands(MCInst &Inst, unsigned N) const { 202117119Stmm assert(N == 2 && "Invalid number of operands!"); 203152684Smarius 204152684Smarius Inst.addOperand(MCOperand::CreateReg(getMemBase())); 205152684Smarius 206152684Smarius unsigned RegOff = getMemOffReg(); 207152684Smarius if (RegOff) 208152684Smarius Inst.addOperand(MCOperand::CreateReg(RegOff)); 209152684Smarius else 210152684Smarius addExpr(Inst, getMemOff()); 211117119Stmm } 212117119Stmm 213117119Stmm StringRef getToken() const { 214117119Stmm assert(Kind == Token && "Invalid access!"); 215117119Stmm return StringRef(Tok.Data, Tok.Length); 216117119Stmm } 217117119Stmm 218117119Stmm virtual void print(raw_ostream &OS) const; 219117119Stmm 220117119Stmm static MBlazeOperand *CreateToken(StringRef Str, SMLoc S) { 221117119Stmm MBlazeOperand *Op = new MBlazeOperand(Token); 222152684Smarius Op->Tok.Data = Str.data(); 223152684Smarius Op->Tok.Length = Str.size(); 224117119Stmm Op->StartLoc = S; 225117119Stmm Op->EndLoc = S; 226152684Smarius return Op; 227117119Stmm } 228117119Stmm 229117119Stmm static MBlazeOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 230117119Stmm MBlazeOperand *Op = new MBlazeOperand(Register); 231117119Stmm Op->Reg.RegNum = RegNum; 232117119Stmm Op->StartLoc = S; 233117119Stmm Op->EndLoc = E; 234117119Stmm return Op; 235117119Stmm } 236117119Stmm 237117119Stmm static MBlazeOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 238117119Stmm MBlazeOperand *Op = new MBlazeOperand(Immediate); 239117119Stmm Op->Imm.Val = Val; 240117119Stmm Op->StartLoc = S; 241117119Stmm Op->EndLoc = E; 242117119Stmm return Op; 243117119Stmm } 244117119Stmm 245117119Stmm static MBlazeOperand *CreateFslImm(const MCExpr *Val, SMLoc S, SMLoc E) { 246152684Smarius MBlazeOperand *Op = new MBlazeOperand(Fsl); 247152684Smarius Op->Imm.Val = Val; 248133589Smarius Op->StartLoc = S; 249133589Smarius Op->EndLoc = E; 250133589Smarius return Op; 251133589Smarius } 252152684Smarius 253133589Smarius static MBlazeOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S, 254 SMLoc E) { 255 MBlazeOperand *Op = new MBlazeOperand(Memory); 256 Op->Mem.Base = Base; 257 Op->Mem.Off = Off; 258 Op->Mem.OffReg = 0; 259 Op->StartLoc = S; 260 Op->EndLoc = E; 261 return Op; 262 } 263 264 static MBlazeOperand *CreateMem(unsigned Base, unsigned Off, SMLoc S, 265 SMLoc E) { 266 MBlazeOperand *Op = new MBlazeOperand(Memory); 267 Op->Mem.Base = Base; 268 Op->Mem.OffReg = Off; 269 Op->Mem.Off = 0; 270 Op->StartLoc = S; 271 Op->EndLoc = E; 272 return Op; 273 } 274}; 275 276} // end anonymous namespace. 277 278void MBlazeOperand::print(raw_ostream &OS) const { 279 switch (Kind) { 280 case Immediate: 281 getImm()->print(OS); 282 break; 283 case Register: 284 OS << "<register R"; 285 OS << getMBlazeRegisterNumbering(getReg()) << ">"; 286 break; 287 case Token: 288 OS << "'" << getToken() << "'"; 289 break; 290 case Memory: { 291 OS << "<memory R"; 292 OS << getMBlazeRegisterNumbering(getMemBase()); 293 OS << ", "; 294 295 unsigned RegOff = getMemOffReg(); 296 if (RegOff) 297 OS << "R" << getMBlazeRegisterNumbering(RegOff); 298 else 299 OS << getMemOff(); 300 OS << ">"; 301 } 302 break; 303 case Fsl: 304 getFslImm()->print(OS); 305 break; 306 } 307} 308 309/// @name Auto-generated Match Functions 310/// { 311 312static unsigned MatchRegisterName(StringRef Name); 313 314/// } 315// 316bool MBlazeAsmParser:: 317MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 318 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 319 MCStreamer &Out, unsigned &ErrorInfo, 320 bool MatchingInlineAsm) { 321 MCInst Inst; 322 switch (MatchInstructionImpl(Operands, Inst, ErrorInfo, 323 MatchingInlineAsm)) { 324 default: break; 325 case Match_Success: 326 Out.EmitInstruction(Inst); 327 return false; 328 case Match_MissingFeature: 329 return Error(IDLoc, "instruction use requires an option to be enabled"); 330 case Match_MnemonicFail: 331 return Error(IDLoc, "unrecognized instruction mnemonic"); 332 case Match_InvalidOperand: { 333 SMLoc ErrorLoc = IDLoc; 334 if (ErrorInfo != ~0U) { 335 if (ErrorInfo >= Operands.size()) 336 return Error(IDLoc, "too few operands for instruction"); 337 338 ErrorLoc = ((MBlazeOperand*)Operands[ErrorInfo])->getStartLoc(); 339 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 340 } 341 342 return Error(ErrorLoc, "invalid operand for instruction"); 343 } 344 } 345 346 llvm_unreachable("Implement any new match types added!"); 347} 348 349MBlazeOperand *MBlazeAsmParser:: 350ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 351 if (Operands.size() != 4) 352 return 0; 353 354 MBlazeOperand &Base = *(MBlazeOperand*)Operands[2]; 355 MBlazeOperand &Offset = *(MBlazeOperand*)Operands[3]; 356 357 SMLoc S = Base.getStartLoc(); 358 SMLoc O = Offset.getStartLoc(); 359 SMLoc E = Offset.getEndLoc(); 360 361 if (!Base.isReg()) { 362 Error(S, "base address must be a register"); 363 return 0; 364 } 365 366 if (!Offset.isReg() && !Offset.isImm()) { 367 Error(O, "offset must be a register or immediate"); 368 return 0; 369 } 370 371 MBlazeOperand *Op; 372 if (Offset.isReg()) 373 Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getReg(), S, E); 374 else 375 Op = MBlazeOperand::CreateMem(Base.getReg(), Offset.getImm(), S, E); 376 377 delete Operands.pop_back_val(); 378 delete Operands.pop_back_val(); 379 Operands.push_back(Op); 380 381 return Op; 382} 383 384bool MBlazeAsmParser::ParseRegister(unsigned &RegNo, 385 SMLoc &StartLoc, SMLoc &EndLoc) { 386 return (ParseRegister(RegNo) == 0); 387} 388 389MBlazeOperand *MBlazeAsmParser::ParseRegister(unsigned &RegNo) { 390 SMLoc S = Parser.getTok().getLoc(); 391 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 392 393 switch (getLexer().getKind()) { 394 default: return 0; 395 case AsmToken::Identifier: 396 RegNo = MatchRegisterName(getLexer().getTok().getIdentifier()); 397 if (RegNo == 0) 398 return 0; 399 400 getLexer().Lex(); 401 return MBlazeOperand::CreateReg(RegNo, S, E); 402 } 403} 404 405static unsigned MatchFslRegister(StringRef String) { 406 if (!String.startswith("rfsl")) 407 return -1; 408 409 unsigned regNum; 410 if (String.substr(4).getAsInteger(10,regNum)) 411 return -1; 412 413 return regNum; 414} 415 416MBlazeOperand *MBlazeAsmParser::ParseFsl() { 417 SMLoc S = Parser.getTok().getLoc(); 418 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 419 420 switch (getLexer().getKind()) { 421 default: return 0; 422 case AsmToken::Identifier: 423 unsigned reg = MatchFslRegister(getLexer().getTok().getIdentifier()); 424 if (reg >= 16) 425 return 0; 426 427 getLexer().Lex(); 428 const MCExpr *EVal = MCConstantExpr::Create(reg,getContext()); 429 return MBlazeOperand::CreateFslImm(EVal,S,E); 430 } 431} 432 433MBlazeOperand *MBlazeAsmParser::ParseImmediate() { 434 SMLoc S = Parser.getTok().getLoc(); 435 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 436 437 const MCExpr *EVal; 438 switch (getLexer().getKind()) { 439 default: return 0; 440 case AsmToken::LParen: 441 case AsmToken::Plus: 442 case AsmToken::Minus: 443 case AsmToken::Integer: 444 case AsmToken::Identifier: 445 if (getParser().ParseExpression(EVal)) 446 return 0; 447 448 return MBlazeOperand::CreateImm(EVal, S, E); 449 } 450} 451 452MBlazeOperand *MBlazeAsmParser:: 453ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 454 MBlazeOperand *Op; 455 456 // Attempt to parse the next token as a register name 457 unsigned RegNo; 458 Op = ParseRegister(RegNo); 459 460 // Attempt to parse the next token as an FSL immediate 461 if (!Op) 462 Op = ParseFsl(); 463 464 // Attempt to parse the next token as an immediate 465 if (!Op) 466 Op = ParseImmediate(); 467 468 // If the token could not be parsed then fail 469 if (!Op) { 470 Error(Parser.getTok().getLoc(), "unknown operand"); 471 return 0; 472 } 473 474 // Push the parsed operand into the list of operands 475 Operands.push_back(Op); 476 return Op; 477} 478 479/// Parse an mblaze instruction mnemonic followed by its operands. 480bool MBlazeAsmParser:: 481ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 482 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 483 // The first operands is the token for the instruction name 484 size_t dotLoc = Name.find('.'); 485 Operands.push_back(MBlazeOperand::CreateToken(Name.substr(0,dotLoc),NameLoc)); 486 if (dotLoc < Name.size()) 487 Operands.push_back(MBlazeOperand::CreateToken(Name.substr(dotLoc),NameLoc)); 488 489 // If there are no more operands then finish 490 if (getLexer().is(AsmToken::EndOfStatement)) 491 return false; 492 493 // Parse the first operand 494 if (!ParseOperand(Operands)) 495 return true; 496 497 while (getLexer().isNot(AsmToken::EndOfStatement) && 498 getLexer().is(AsmToken::Comma)) { 499 // Consume the comma token 500 getLexer().Lex(); 501 502 // Parse the next operand 503 if (!ParseOperand(Operands)) 504 return true; 505 } 506 507 // If the instruction requires a memory operand then we need to 508 // replace the last two operands (base+offset) with a single 509 // memory operand. 510 if (Name.startswith("lw") || Name.startswith("sw") || 511 Name.startswith("lh") || Name.startswith("sh") || 512 Name.startswith("lb") || Name.startswith("sb")) 513 return (ParseMemory(Operands) == NULL); 514 515 return false; 516} 517 518/// ParseDirective parses the MBlaze specific directives 519bool MBlazeAsmParser::ParseDirective(AsmToken DirectiveID) { 520 StringRef IDVal = DirectiveID.getIdentifier(); 521 if (IDVal == ".word") 522 return ParseDirectiveWord(2, DirectiveID.getLoc()); 523 return true; 524} 525 526/// ParseDirectiveWord 527/// ::= .word [ expression (, expression)* ] 528bool MBlazeAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) { 529 if (getLexer().isNot(AsmToken::EndOfStatement)) { 530 for (;;) { 531 const MCExpr *Value; 532 if (getParser().ParseExpression(Value)) 533 return true; 534 535 getParser().getStreamer().EmitValue(Value, Size, 0 /*addrspace*/); 536 537 if (getLexer().is(AsmToken::EndOfStatement)) 538 break; 539 540 // FIXME: Improve diagnostic. 541 if (getLexer().isNot(AsmToken::Comma)) 542 return Error(L, "unexpected token in directive"); 543 Parser.Lex(); 544 } 545 } 546 547 Parser.Lex(); 548 return false; 549} 550 551extern "C" void LLVMInitializeMBlazeAsmLexer(); 552 553/// Force static initialization. 554extern "C" void LLVMInitializeMBlazeAsmParser() { 555 RegisterMCAsmParser<MBlazeAsmParser> X(TheMBlazeTarget); 556 LLVMInitializeMBlazeAsmLexer(); 557} 558 559#define GET_REGISTER_MATCHER 560#define GET_MATCHER_IMPLEMENTATION 561#include "MBlazeGenAsmMatcher.inc" 562