MipsAsmParser.cpp revision 457ee1a12e2c52624af7fdb81cf938f6d8d96572
1//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#include "MCTargetDesc/MipsMCTargetDesc.h" 11#include "MipsRegisterInfo.h" 12#include "llvm/ADT/StringSwitch.h" 13#include "llvm/MC/MCContext.h" 14#include "llvm/MC/MCExpr.h" 15#include "llvm/MC/MCInst.h" 16#include "llvm/MC/MCParser/MCAsmLexer.h" 17#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 18#include "llvm/MC/MCStreamer.h" 19#include "llvm/MC/MCSubtargetInfo.h" 20#include "llvm/MC/MCSymbol.h" 21#include "llvm/MC/MCTargetAsmParser.h" 22#include "llvm/Support/TargetRegistry.h" 23 24using namespace llvm; 25 26namespace { 27class MipsAssemblerOptions { 28public: 29 MipsAssemblerOptions(): 30 aTReg(1), reorder(true), macro(true) { 31 } 32 33 unsigned getATRegNum() {return aTReg;} 34 bool setATReg(unsigned Reg); 35 36 bool isReorder() {return reorder;} 37 void setReorder() {reorder = true;} 38 void setNoreorder() {reorder = false;} 39 40 bool isMacro() {return macro;} 41 void setMacro() {macro = true;} 42 void setNomacro() {macro = false;} 43 44private: 45 unsigned aTReg; 46 bool reorder; 47 bool macro; 48}; 49} 50 51namespace { 52class MipsAsmParser : public MCTargetAsmParser { 53 54 enum FpFormatTy { 55 FP_FORMAT_NONE = -1, 56 FP_FORMAT_S, 57 FP_FORMAT_D, 58 FP_FORMAT_L, 59 FP_FORMAT_W 60 } FpFormat; 61 62 MCSubtargetInfo &STI; 63 MCAsmParser &Parser; 64 MipsAssemblerOptions Options; 65 66 67#define GET_ASSEMBLER_HEADER 68#include "MipsGenAsmMatcher.inc" 69 70 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 71 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 72 MCStreamer &Out, unsigned &ErrorInfo, 73 bool MatchingInlineAsm); 74 75 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 76 77 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 78 SMLoc NameLoc, 79 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 80 81 bool parseMathOperation(StringRef Name, SMLoc NameLoc, 82 SmallVectorImpl<MCParsedAsmOperand*> &Operands); 83 84 bool ParseDirective(AsmToken DirectiveID); 85 86 MipsAsmParser::OperandMatchResultTy 87 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 88 89 MipsAsmParser::OperandMatchResultTy 90 parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 91 92 MipsAsmParser::OperandMatchResultTy 93 parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 94 95 MipsAsmParser::OperandMatchResultTy 96 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 97 98 MipsAsmParser::OperandMatchResultTy 99 parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 100 101 MipsAsmParser::OperandMatchResultTy 102 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 103 104 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 105 StringRef Mnemonic); 106 107 int tryParseRegister(bool is64BitReg); 108 109 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 110 bool is64BitReg); 111 112 bool needsExpansion(MCInst &Inst); 113 114 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 115 SmallVectorImpl<MCInst> &Instructions); 116 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 117 SmallVectorImpl<MCInst> &Instructions); 118 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 119 SmallVectorImpl<MCInst> &Instructions); 120 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 121 SmallVectorImpl<MCInst> &Instructions); 122 bool reportParseError(StringRef ErrorMsg); 123 124 bool parseMemOffset(const MCExpr *&Res); 125 bool parseRelocOperand(const MCExpr *&Res); 126 127 bool parseDirectiveSet(); 128 129 bool parseSetAtDirective(); 130 bool parseSetNoAtDirective(); 131 bool parseSetMacroDirective(); 132 bool parseSetNoMacroDirective(); 133 bool parseSetReorderDirective(); 134 bool parseSetNoReorderDirective(); 135 136 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 137 138 bool isMips64() const { 139 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 140 } 141 142 bool isFP64() const { 143 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 144 } 145 146 int matchRegisterName(StringRef Symbol, bool is64BitReg); 147 148 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 149 150 void setFpFormat(FpFormatTy Format) { 151 FpFormat = Format; 152 } 153 154 void setDefaultFpFormat(); 155 156 void setFpFormat(StringRef Format); 157 158 FpFormatTy getFpFormat() {return FpFormat;} 159 160 bool requestsDoubleOperand(StringRef Mnemonic); 161 162 unsigned getReg(int RC,int RegNo); 163 164 unsigned getATReg(); 165public: 166 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 167 : MCTargetAsmParser(), STI(sti), Parser(parser) { 168 // Initialize the set of available features. 169 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 170 } 171 172 MCAsmParser &getParser() const { return Parser; } 173 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 174 175}; 176} 177 178namespace { 179 180/// MipsOperand - Instances of this class represent a parsed Mips machine 181/// instruction. 182class MipsOperand : public MCParsedAsmOperand { 183 184public: 185 enum RegisterKind { 186 Kind_None, 187 Kind_CPURegs, 188 Kind_CPU64Regs, 189 Kind_HWRegs, 190 Kind_HW64Regs, 191 Kind_FGR32Regs, 192 Kind_FGR64Regs, 193 Kind_AFGR32Regs, 194 Kind_CCRRegs 195 }; 196 197private: 198 enum KindTy { 199 k_CondCode, 200 k_CoprocNum, 201 k_Immediate, 202 k_Memory, 203 k_PostIndexRegister, 204 k_Register, 205 k_Token 206 } Kind; 207 208 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 209 210 union { 211 struct { 212 const char *Data; 213 unsigned Length; 214 } Tok; 215 216 struct { 217 unsigned RegNum; 218 RegisterKind Kind; 219 } Reg; 220 221 struct { 222 const MCExpr *Val; 223 } Imm; 224 225 struct { 226 unsigned Base; 227 const MCExpr *Off; 228 } Mem; 229 }; 230 231 SMLoc StartLoc, EndLoc; 232 233public: 234 void addRegOperands(MCInst &Inst, unsigned N) const { 235 assert(N == 1 && "Invalid number of operands!"); 236 Inst.addOperand(MCOperand::CreateReg(getReg())); 237 } 238 239 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 240 // Add as immediate when possible. Null MCExpr = 0. 241 if (Expr == 0) 242 Inst.addOperand(MCOperand::CreateImm(0)); 243 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 244 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 245 else 246 Inst.addOperand(MCOperand::CreateExpr(Expr)); 247 } 248 249 void addImmOperands(MCInst &Inst, unsigned N) const { 250 assert(N == 1 && "Invalid number of operands!"); 251 const MCExpr *Expr = getImm(); 252 addExpr(Inst,Expr); 253 } 254 255 void addMemOperands(MCInst &Inst, unsigned N) const { 256 assert(N == 2 && "Invalid number of operands!"); 257 258 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 259 260 const MCExpr *Expr = getMemOff(); 261 addExpr(Inst,Expr); 262 } 263 264 bool isReg() const { return Kind == k_Register; } 265 bool isImm() const { return Kind == k_Immediate; } 266 bool isToken() const { return Kind == k_Token; } 267 bool isMem() const { return Kind == k_Memory; } 268 269 StringRef getToken() const { 270 assert(Kind == k_Token && "Invalid access!"); 271 return StringRef(Tok.Data, Tok.Length); 272 } 273 274 unsigned getReg() const { 275 assert((Kind == k_Register) && "Invalid access!"); 276 return Reg.RegNum; 277 } 278 279 void setRegKind(RegisterKind RegKind) { 280 assert((Kind == k_Register) && "Invalid access!"); 281 Reg.Kind = RegKind; 282 } 283 284 const MCExpr *getImm() const { 285 assert((Kind == k_Immediate) && "Invalid access!"); 286 return Imm.Val; 287 } 288 289 unsigned getMemBase() const { 290 assert((Kind == k_Memory) && "Invalid access!"); 291 return Mem.Base; 292 } 293 294 const MCExpr *getMemOff() const { 295 assert((Kind == k_Memory) && "Invalid access!"); 296 return Mem.Off; 297 } 298 299 static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 300 MipsOperand *Op = new MipsOperand(k_Token); 301 Op->Tok.Data = Str.data(); 302 Op->Tok.Length = Str.size(); 303 Op->StartLoc = S; 304 Op->EndLoc = S; 305 return Op; 306 } 307 308 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 309 MipsOperand *Op = new MipsOperand(k_Register); 310 Op->Reg.RegNum = RegNum; 311 Op->StartLoc = S; 312 Op->EndLoc = E; 313 return Op; 314 } 315 316 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 317 MipsOperand *Op = new MipsOperand(k_Immediate); 318 Op->Imm.Val = Val; 319 Op->StartLoc = S; 320 Op->EndLoc = E; 321 return Op; 322 } 323 324 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 325 SMLoc S, SMLoc E) { 326 MipsOperand *Op = new MipsOperand(k_Memory); 327 Op->Mem.Base = Base; 328 Op->Mem.Off = Off; 329 Op->StartLoc = S; 330 Op->EndLoc = E; 331 return Op; 332 } 333 334 bool isCPURegsAsm() const { 335 return Kind == k_Register && Reg.Kind == Kind_CPURegs; 336 } 337 void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const { 338 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 339 } 340 341 bool isCPU64RegsAsm() const { 342 return Kind == k_Register && Reg.Kind == Kind_CPU64Regs; 343 } 344 void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const { 345 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 346 } 347 348 bool isHWRegsAsm() const { 349 assert((Kind == k_Register) && "Invalid access!"); 350 return Reg.Kind == Kind_HWRegs; 351 } 352 void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const { 353 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 354 } 355 356 bool isHW64RegsAsm() const { 357 assert((Kind == k_Register) && "Invalid access!"); 358 return Reg.Kind == Kind_HW64Regs; 359 } 360 void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const { 361 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 362 } 363 364 void addCCRAsmOperands(MCInst &Inst, unsigned N) const { 365 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 366 } 367 368 bool isCCRAsm() const { 369 assert((Kind == k_Register) && "Invalid access!"); 370 return Reg.Kind == Kind_CCRRegs; 371 } 372 373 /// getStartLoc - Get the location of the first token of this operand. 374 SMLoc getStartLoc() const { return StartLoc; } 375 /// getEndLoc - Get the location of the last token of this operand. 376 SMLoc getEndLoc() const { return EndLoc; } 377 378 virtual void print(raw_ostream &OS) const { 379 llvm_unreachable("unimplemented!"); 380 } 381}; 382} 383 384bool MipsAsmParser::needsExpansion(MCInst &Inst) { 385 386 switch(Inst.getOpcode()) { 387 case Mips::LoadImm32Reg: 388 case Mips::LoadAddr32Imm: 389 case Mips::LoadAddr32Reg: 390 return true; 391 default: 392 return false; 393 } 394} 395 396void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 397 SmallVectorImpl<MCInst> &Instructions){ 398 switch(Inst.getOpcode()) { 399 case Mips::LoadImm32Reg: 400 return expandLoadImm(Inst, IDLoc, Instructions); 401 case Mips::LoadAddr32Imm: 402 return expandLoadAddressImm(Inst,IDLoc,Instructions); 403 case Mips::LoadAddr32Reg: 404 return expandLoadAddressReg(Inst,IDLoc,Instructions); 405 } 406} 407 408void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 409 SmallVectorImpl<MCInst> &Instructions){ 410 MCInst tmpInst; 411 const MCOperand &ImmOp = Inst.getOperand(1); 412 assert(ImmOp.isImm() && "expected immediate operand kind"); 413 const MCOperand &RegOp = Inst.getOperand(0); 414 assert(RegOp.isReg() && "expected register operand kind"); 415 416 int ImmValue = ImmOp.getImm(); 417 tmpInst.setLoc(IDLoc); 418 if ( 0 <= ImmValue && ImmValue <= 65535) { 419 // for 0 <= j <= 65535. 420 // li d,j => ori d,$zero,j 421 tmpInst.setOpcode(Mips::ORi); 422 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 423 tmpInst.addOperand( 424 MCOperand::CreateReg(Mips::ZERO)); 425 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 426 Instructions.push_back(tmpInst); 427 } else if ( ImmValue < 0 && ImmValue >= -32768) { 428 // for -32768 <= j < 0. 429 // li d,j => addiu d,$zero,j 430 tmpInst.setOpcode(Mips::ADDiu); 431 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 432 tmpInst.addOperand( 433 MCOperand::CreateReg(Mips::ZERO)); 434 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 435 Instructions.push_back(tmpInst); 436 } else { 437 // for any other value of j that is representable as a 32-bit integer. 438 // li d,j => lui d,hi16(j) 439 // ori d,d,lo16(j) 440 tmpInst.setOpcode(Mips::LUi); 441 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 442 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 443 Instructions.push_back(tmpInst); 444 tmpInst.clear(); 445 tmpInst.setOpcode(Mips::ORi); 446 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 447 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 448 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 449 tmpInst.setLoc(IDLoc); 450 Instructions.push_back(tmpInst); 451 } 452} 453 454void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 455 SmallVectorImpl<MCInst> &Instructions){ 456 MCInst tmpInst; 457 const MCOperand &ImmOp = Inst.getOperand(2); 458 assert(ImmOp.isImm() && "expected immediate operand kind"); 459 const MCOperand &SrcRegOp = Inst.getOperand(1); 460 assert(SrcRegOp.isReg() && "expected register operand kind"); 461 const MCOperand &DstRegOp = Inst.getOperand(0); 462 assert(DstRegOp.isReg() && "expected register operand kind"); 463 int ImmValue = ImmOp.getImm(); 464 if ( -32768 <= ImmValue && ImmValue <= 65535) { 465 //for -32768 <= j <= 65535. 466 //la d,j(s) => addiu d,s,j 467 tmpInst.setOpcode(Mips::ADDiu); 468 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 469 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 470 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 471 Instructions.push_back(tmpInst); 472 } else { 473 //for any other value of j that is representable as a 32-bit integer. 474 //la d,j(s) => lui d,hi16(j) 475 // ori d,d,lo16(j) 476 // addu d,d,s 477 tmpInst.setOpcode(Mips::LUi); 478 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 479 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 480 Instructions.push_back(tmpInst); 481 tmpInst.clear(); 482 tmpInst.setOpcode(Mips::ORi); 483 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 484 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 485 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 486 Instructions.push_back(tmpInst); 487 tmpInst.clear(); 488 tmpInst.setOpcode(Mips::ADDu); 489 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 490 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 491 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 492 Instructions.push_back(tmpInst); 493 } 494} 495 496void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 497 SmallVectorImpl<MCInst> &Instructions){ 498 MCInst tmpInst; 499 const MCOperand &ImmOp = Inst.getOperand(1); 500 assert(ImmOp.isImm() && "expected immediate operand kind"); 501 const MCOperand &RegOp = Inst.getOperand(0); 502 assert(RegOp.isReg() && "expected register operand kind"); 503 int ImmValue = ImmOp.getImm(); 504 if ( -32768 <= ImmValue && ImmValue <= 65535) { 505 //for -32768 <= j <= 65535. 506 //la d,j => addiu d,$zero,j 507 tmpInst.setOpcode(Mips::ADDiu); 508 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 509 tmpInst.addOperand( 510 MCOperand::CreateReg(Mips::ZERO)); 511 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 512 Instructions.push_back(tmpInst); 513 } else { 514 //for any other value of j that is representable as a 32-bit integer. 515 //la d,j => lui d,hi16(j) 516 // ori d,d,lo16(j) 517 tmpInst.setOpcode(Mips::LUi); 518 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 519 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 520 Instructions.push_back(tmpInst); 521 tmpInst.clear(); 522 tmpInst.setOpcode(Mips::ORi); 523 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 524 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 525 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 526 Instructions.push_back(tmpInst); 527 } 528} 529 530bool MipsAsmParser:: 531MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 532 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 533 MCStreamer &Out, unsigned &ErrorInfo, 534 bool MatchingInlineAsm) { 535 MCInst Inst; 536 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 537 MatchingInlineAsm); 538 539 switch (MatchResult) { 540 default: break; 541 case Match_Success: { 542 if (needsExpansion(Inst)) { 543 SmallVector<MCInst, 4> Instructions; 544 expandInstruction(Inst, IDLoc, Instructions); 545 for(unsigned i =0; i < Instructions.size(); i++){ 546 Out.EmitInstruction(Instructions[i]); 547 } 548 } else { 549 Inst.setLoc(IDLoc); 550 Out.EmitInstruction(Inst); 551 } 552 return false; 553 } 554 case Match_MissingFeature: 555 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 556 return true; 557 case Match_InvalidOperand: { 558 SMLoc ErrorLoc = IDLoc; 559 if (ErrorInfo != ~0U) { 560 if (ErrorInfo >= Operands.size()) 561 return Error(IDLoc, "too few operands for instruction"); 562 563 ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc(); 564 if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc; 565 } 566 567 return Error(ErrorLoc, "invalid operand for instruction"); 568 } 569 case Match_MnemonicFail: 570 return Error(IDLoc, "invalid instruction"); 571 } 572 return true; 573} 574 575int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 576 577 int CC; 578 if (!is64BitReg) 579 CC = StringSwitch<unsigned>(Name) 580 .Case("zero", Mips::ZERO) 581 .Case("a0", Mips::A0) 582 .Case("a1", Mips::A1) 583 .Case("a2", Mips::A2) 584 .Case("a3", Mips::A3) 585 .Case("v0", Mips::V0) 586 .Case("v1", Mips::V1) 587 .Case("s0", Mips::S0) 588 .Case("s1", Mips::S1) 589 .Case("s2", Mips::S2) 590 .Case("s3", Mips::S3) 591 .Case("s4", Mips::S4) 592 .Case("s5", Mips::S5) 593 .Case("s6", Mips::S6) 594 .Case("s7", Mips::S7) 595 .Case("k0", Mips::K0) 596 .Case("k1", Mips::K1) 597 .Case("sp", Mips::SP) 598 .Case("fp", Mips::FP) 599 .Case("gp", Mips::GP) 600 .Case("ra", Mips::RA) 601 .Case("t0", Mips::T0) 602 .Case("t1", Mips::T1) 603 .Case("t2", Mips::T2) 604 .Case("t3", Mips::T3) 605 .Case("t4", Mips::T4) 606 .Case("t5", Mips::T5) 607 .Case("t6", Mips::T6) 608 .Case("t7", Mips::T7) 609 .Case("t8", Mips::T8) 610 .Case("t9", Mips::T9) 611 .Case("at", Mips::AT) 612 .Case("fcc0", Mips::FCC0) 613 .Default(-1); 614 else 615 CC = StringSwitch<unsigned>(Name) 616 .Case("zero", Mips::ZERO_64) 617 .Case("at", Mips::AT_64) 618 .Case("v0", Mips::V0_64) 619 .Case("v1", Mips::V1_64) 620 .Case("a0", Mips::A0_64) 621 .Case("a1", Mips::A1_64) 622 .Case("a2", Mips::A2_64) 623 .Case("a3", Mips::A3_64) 624 .Case("a4", Mips::T0_64) 625 .Case("a5", Mips::T1_64) 626 .Case("a6", Mips::T2_64) 627 .Case("a7", Mips::T3_64) 628 .Case("t4", Mips::T4_64) 629 .Case("t5", Mips::T5_64) 630 .Case("t6", Mips::T6_64) 631 .Case("t7", Mips::T7_64) 632 .Case("s0", Mips::S0_64) 633 .Case("s1", Mips::S1_64) 634 .Case("s2", Mips::S2_64) 635 .Case("s3", Mips::S3_64) 636 .Case("s4", Mips::S4_64) 637 .Case("s5", Mips::S5_64) 638 .Case("s6", Mips::S6_64) 639 .Case("s7", Mips::S7_64) 640 .Case("t8", Mips::T8_64) 641 .Case("t9", Mips::T9_64) 642 .Case("kt0", Mips::K0_64) 643 .Case("kt1", Mips::K1_64) 644 .Case("gp", Mips::GP_64) 645 .Case("sp", Mips::SP_64) 646 .Case("fp", Mips::FP_64) 647 .Case("s8", Mips::FP_64) 648 .Case("ra", Mips::RA_64) 649 .Default(-1); 650 651 if (CC != -1) 652 return CC; 653 654 if (Name[0] == 'f') { 655 StringRef NumString = Name.substr(1); 656 unsigned IntVal; 657 if( NumString.getAsInteger(10, IntVal)) 658 return -1; // not integer 659 if (IntVal > 31) 660 return -1; 661 662 FpFormatTy Format = getFpFormat(); 663 664 if (Format == FP_FORMAT_S || Format == FP_FORMAT_W) 665 return getReg(Mips::FGR32RegClassID, IntVal); 666 if (Format == FP_FORMAT_D) { 667 if(isFP64()) { 668 return getReg(Mips::FGR64RegClassID, IntVal); 669 } 670 // only even numbers available as register pairs 671 if (( IntVal > 31) || (IntVal%2 != 0)) 672 return -1; 673 return getReg(Mips::AFGR64RegClassID, IntVal/2); 674 } 675 } 676 677 return -1; 678} 679void MipsAsmParser::setDefaultFpFormat() { 680 681 if (isMips64() || isFP64()) 682 FpFormat = FP_FORMAT_D; 683 else 684 FpFormat = FP_FORMAT_S; 685} 686 687bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 688 689 bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 690 .Case("ldxc1", true) 691 .Case("ldc1", true) 692 .Case("sdxc1", true) 693 .Case("sdc1", true) 694 .Default(false); 695 696 return IsDouble; 697} 698void MipsAsmParser::setFpFormat(StringRef Format) { 699 700 FpFormat = StringSwitch<FpFormatTy>(Format.lower()) 701 .Case(".s", FP_FORMAT_S) 702 .Case(".d", FP_FORMAT_D) 703 .Case(".l", FP_FORMAT_L) 704 .Case(".w", FP_FORMAT_W) 705 .Default(FP_FORMAT_NONE); 706} 707 708bool MipsAssemblerOptions::setATReg(unsigned Reg) { 709 if (Reg > 31) 710 return false; 711 712 aTReg = Reg; 713 return true; 714} 715 716unsigned MipsAsmParser::getATReg() { 717 unsigned Reg = Options.getATRegNum(); 718 if (isMips64()) 719 return getReg(Mips::CPU64RegsRegClassID,Reg); 720 721 return getReg(Mips::CPURegsRegClassID,Reg); 722} 723 724unsigned MipsAsmParser::getReg(int RC,int RegNo) { 725 return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo); 726} 727 728int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 729 730 if (RegNum > 31) 731 return -1; 732 733 return getReg(RegClass, RegNum); 734} 735 736int MipsAsmParser::tryParseRegister(bool is64BitReg) { 737 const AsmToken &Tok = Parser.getTok(); 738 int RegNum = -1; 739 740 if (Tok.is(AsmToken::Identifier)) { 741 std::string lowerCase = Tok.getString().lower(); 742 RegNum = matchRegisterName(lowerCase, is64BitReg); 743 } else if (Tok.is(AsmToken::Integer)) 744 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 745 is64BitReg ? Mips::CPU64RegsRegClassID 746 : Mips::CPURegsRegClassID); 747 return RegNum; 748} 749 750bool MipsAsmParser:: 751 tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 752 bool is64BitReg){ 753 754 SMLoc S = Parser.getTok().getLoc(); 755 int RegNo = -1; 756 757 RegNo = tryParseRegister(is64BitReg); 758 if (RegNo == -1) 759 return true; 760 761 Operands.push_back(MipsOperand::CreateReg(RegNo, S, 762 Parser.getTok().getLoc())); 763 Parser.Lex(); // Eat register token. 764 return false; 765} 766 767bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands, 768 StringRef Mnemonic) { 769 // Check if the current operand has a custom associated parser, if so, try to 770 // custom parse the operand, or fallback to the general approach. 771 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 772 if (ResTy == MatchOperand_Success) 773 return false; 774 // If there wasn't a custom match, try the generic matcher below. Otherwise, 775 // there was a match, but an error occurred, in which case, just return that 776 // the operand parsing failed. 777 if (ResTy == MatchOperand_ParseFail) 778 return true; 779 780 switch (getLexer().getKind()) { 781 default: 782 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 783 return true; 784 case AsmToken::Dollar: { 785 // parse register 786 SMLoc S = Parser.getTok().getLoc(); 787 Parser.Lex(); // Eat dollar token. 788 // parse register operand 789 if (!tryParseRegisterOperand(Operands, isMips64())) { 790 if (getLexer().is(AsmToken::LParen)) { 791 // check if it is indexed addressing operand 792 Operands.push_back(MipsOperand::CreateToken("(", S)); 793 Parser.Lex(); // eat parenthesis 794 if (getLexer().isNot(AsmToken::Dollar)) 795 return true; 796 797 Parser.Lex(); // eat dollar 798 if (tryParseRegisterOperand(Operands, isMips64())) 799 return true; 800 801 if (!getLexer().is(AsmToken::RParen)) 802 return true; 803 804 S = Parser.getTok().getLoc(); 805 Operands.push_back(MipsOperand::CreateToken(")", S)); 806 Parser.Lex(); 807 } 808 return false; 809 } 810 // maybe it is a symbol reference 811 StringRef Identifier; 812 if (Parser.ParseIdentifier(Identifier)) 813 return true; 814 815 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 816 817 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 818 819 // Otherwise create a symbol ref. 820 const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, 821 getContext()); 822 823 Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 824 return false; 825 } 826 case AsmToken::Identifier: 827 case AsmToken::LParen: 828 case AsmToken::Minus: 829 case AsmToken::Plus: 830 case AsmToken::Integer: 831 case AsmToken::String: { 832 // quoted label names 833 const MCExpr *IdVal; 834 SMLoc S = Parser.getTok().getLoc(); 835 if (getParser().ParseExpression(IdVal)) 836 return true; 837 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 838 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 839 return false; 840 } 841 case AsmToken::Percent: { 842 // it is a symbol reference or constant expression 843 const MCExpr *IdVal; 844 SMLoc S = Parser.getTok().getLoc(); // start location of the operand 845 if (parseRelocOperand(IdVal)) 846 return true; 847 848 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 849 850 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 851 return false; 852 } // case AsmToken::Percent 853 } // switch(getLexer().getKind()) 854 return true; 855} 856 857bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 858 859 Parser.Lex(); // eat % token 860 const AsmToken &Tok = Parser.getTok(); // get next token, operation 861 if (Tok.isNot(AsmToken::Identifier)) 862 return true; 863 864 std::string Str = Tok.getIdentifier().str(); 865 866 Parser.Lex(); // eat identifier 867 // now make expression from the rest of the operand 868 const MCExpr *IdVal; 869 SMLoc EndLoc; 870 871 if (getLexer().getKind() == AsmToken::LParen) { 872 while (1) { 873 Parser.Lex(); // eat '(' token 874 if (getLexer().getKind() == AsmToken::Percent) { 875 Parser.Lex(); // eat % token 876 const AsmToken &nextTok = Parser.getTok(); 877 if (nextTok.isNot(AsmToken::Identifier)) 878 return true; 879 Str += "(%"; 880 Str += nextTok.getIdentifier(); 881 Parser.Lex(); // eat identifier 882 if (getLexer().getKind() != AsmToken::LParen) 883 return true; 884 } else 885 break; 886 } 887 if (getParser().ParseParenExpression(IdVal,EndLoc)) 888 return true; 889 890 while (getLexer().getKind() == AsmToken::RParen) 891 Parser.Lex(); // eat ')' token 892 893 } else 894 return true; // parenthesis must follow reloc operand 895 896 // Check the type of the expression 897 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) { 898 // it's a constant, evaluate lo or hi value 899 int Val = MCE->getValue(); 900 if (Str == "lo") { 901 Val = Val & 0xffff; 902 } else if (Str == "hi") { 903 Val = (Val & 0xffff0000) >> 16; 904 } 905 Res = MCConstantExpr::Create(Val, getContext()); 906 return false; 907 } 908 909 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) { 910 // it's a symbol, create symbolic expression from symbol 911 StringRef Symbol = MSRE->getSymbol().getName(); 912 MCSymbolRefExpr::VariantKind VK = getVariantKind(Str); 913 Res = MCSymbolRefExpr::Create(Symbol,VK,getContext()); 914 return false; 915 } 916 return true; 917} 918 919bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 920 SMLoc &EndLoc) { 921 922 StartLoc = Parser.getTok().getLoc(); 923 RegNo = tryParseRegister(isMips64()); 924 EndLoc = Parser.getTok().getLoc(); 925 return (RegNo == (unsigned)-1); 926} 927 928bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { 929 930 SMLoc S; 931 932 switch(getLexer().getKind()) { 933 default: 934 return true; 935 case AsmToken::Integer: 936 case AsmToken::Minus: 937 case AsmToken::Plus: 938 return (getParser().ParseExpression(Res)); 939 case AsmToken::Percent: 940 return parseRelocOperand(Res); 941 case AsmToken::LParen: 942 return false; // it's probably assuming 0 943 } 944 return true; 945} 946 947MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 948 SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 949 950 const MCExpr *IdVal = 0; 951 SMLoc S; 952 // first operand is the offset 953 S = Parser.getTok().getLoc(); 954 955 if (parseMemOffset(IdVal)) 956 return MatchOperand_ParseFail; 957 958 const AsmToken &Tok = Parser.getTok(); // get next token 959 if (Tok.isNot(AsmToken::LParen)) { 960 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 961 if (Mnemonic->getToken() == "la") { 962 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1); 963 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 964 return MatchOperand_Success; 965 } 966 Error(Parser.getTok().getLoc(), "'(' expected"); 967 return MatchOperand_ParseFail; 968 } 969 970 Parser.Lex(); // Eat '(' token. 971 972 const AsmToken &Tok1 = Parser.getTok(); // get next token 973 if (Tok1.is(AsmToken::Dollar)) { 974 Parser.Lex(); // Eat '$' token. 975 if (tryParseRegisterOperand(Operands, isMips64())) { 976 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 977 return MatchOperand_ParseFail; 978 } 979 980 } else { 981 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 982 return MatchOperand_ParseFail; 983 } 984 985 const AsmToken &Tok2 = Parser.getTok(); // get next token 986 if (Tok2.isNot(AsmToken::RParen)) { 987 Error(Parser.getTok().getLoc(), "')' expected"); 988 return MatchOperand_ParseFail; 989 } 990 991 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 992 993 Parser.Lex(); // Eat ')' token. 994 995 if (IdVal == 0) 996 IdVal = MCConstantExpr::Create(0, getContext()); 997 998 // now replace register operand with the mem operand 999 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1000 int RegNo = op->getReg(); 1001 // remove register from operands 1002 Operands.pop_back(); 1003 // and add memory operand 1004 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 1005 delete op; 1006 return MatchOperand_Success; 1007} 1008 1009MipsAsmParser::OperandMatchResultTy 1010MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1011 1012 if (!isMips64()) 1013 return MatchOperand_NoMatch; 1014 // if the first token is not '$' we have an error 1015 if (Parser.getTok().isNot(AsmToken::Dollar)) 1016 return MatchOperand_NoMatch; 1017 1018 Parser.Lex(); // Eat $ 1019 if(!tryParseRegisterOperand(Operands, true)) { 1020 // set the proper register kind 1021 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1022 op->setRegKind(MipsOperand::Kind_CPU64Regs); 1023 return MatchOperand_Success; 1024 } 1025 return MatchOperand_NoMatch; 1026} 1027 1028MipsAsmParser::OperandMatchResultTy 1029MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1030 1031 // if the first token is not '$' we have an error 1032 if (Parser.getTok().isNot(AsmToken::Dollar)) 1033 return MatchOperand_NoMatch; 1034 1035 Parser.Lex(); // Eat $ 1036 if(!tryParseRegisterOperand(Operands, false)) { 1037 // set the propper register kind 1038 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1039 op->setRegKind(MipsOperand::Kind_CPURegs); 1040 return MatchOperand_Success; 1041 } 1042 return MatchOperand_NoMatch; 1043} 1044 1045MipsAsmParser::OperandMatchResultTy 1046MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1047 1048 // if the first token is not '$' we have error 1049 if (Parser.getTok().isNot(AsmToken::Dollar)) 1050 return MatchOperand_NoMatch; 1051 SMLoc S = Parser.getTok().getLoc(); 1052 Parser.Lex(); // Eat $ 1053 1054 const AsmToken &Tok = Parser.getTok(); // get next token 1055 if (Tok.isNot(AsmToken::Integer)) 1056 return MatchOperand_NoMatch; 1057 1058 unsigned RegNum = Tok.getIntVal(); 1059 // at the moment only hwreg29 is supported 1060 if (RegNum != 29) 1061 return MatchOperand_ParseFail; 1062 1063 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 1064 Parser.getTok().getLoc()); 1065 op->setRegKind(MipsOperand::Kind_HWRegs); 1066 Operands.push_back(op); 1067 1068 Parser.Lex(); // Eat reg number 1069 return MatchOperand_Success; 1070} 1071 1072MipsAsmParser::OperandMatchResultTy 1073MipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1074 //if the first token is not '$' we have error 1075 if (Parser.getTok().isNot(AsmToken::Dollar)) 1076 return MatchOperand_NoMatch; 1077 SMLoc S = Parser.getTok().getLoc(); 1078 Parser.Lex(); // Eat $ 1079 1080 const AsmToken &Tok = Parser.getTok(); // get next token 1081 if (Tok.isNot(AsmToken::Integer)) 1082 return MatchOperand_NoMatch; 1083 1084 unsigned RegNum = Tok.getIntVal(); 1085 // at the moment only hwreg29 is supported 1086 if (RegNum != 29) 1087 return MatchOperand_ParseFail; 1088 1089 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 1090 Parser.getTok().getLoc()); 1091 op->setRegKind(MipsOperand::Kind_HWRegs); 1092 Operands.push_back(op); 1093 1094 Parser.Lex(); // Eat reg number 1095 return MatchOperand_Success; 1096} 1097 1098MipsAsmParser::OperandMatchResultTy 1099MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1100 unsigned RegNum; 1101 //if the first token is not '$' we have error 1102 if (Parser.getTok().isNot(AsmToken::Dollar)) 1103 return MatchOperand_NoMatch; 1104 SMLoc S = Parser.getTok().getLoc(); 1105 Parser.Lex(); // Eat $ 1106 1107 const AsmToken &Tok = Parser.getTok(); // get next token 1108 if (Tok.is(AsmToken::Integer)) { 1109 RegNum = Tok.getIntVal(); 1110 // at the moment only fcc0 is supported 1111 if (RegNum != 0) 1112 return MatchOperand_ParseFail; 1113 } else if (Tok.is(AsmToken::Identifier)) { 1114 // at the moment only fcc0 is supported 1115 if (Tok.getIdentifier() != "fcc0") 1116 return MatchOperand_ParseFail; 1117 } else 1118 return MatchOperand_NoMatch; 1119 1120 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 1121 Parser.getTok().getLoc()); 1122 op->setRegKind(MipsOperand::Kind_CCRRegs); 1123 Operands.push_back(op); 1124 1125 Parser.Lex(); // Eat reg number 1126 return MatchOperand_Success; 1127} 1128 1129MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1130 1131 MCSymbolRefExpr::VariantKind VK 1132 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1133 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1134 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1135 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1136 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1137 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1138 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1139 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1140 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1141 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1142 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1143 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1144 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1145 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1146 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1147 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1148 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1149 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1150 .Default(MCSymbolRefExpr::VK_None); 1151 1152 return VK; 1153} 1154 1155static int ConvertCcString(StringRef CondString) { 1156 int CC = StringSwitch<unsigned>(CondString) 1157 .Case(".f", 0) 1158 .Case(".un", 1) 1159 .Case(".eq", 2) 1160 .Case(".ueq", 3) 1161 .Case(".olt", 4) 1162 .Case(".ult", 5) 1163 .Case(".ole", 6) 1164 .Case(".ule", 7) 1165 .Case(".sf", 8) 1166 .Case(".ngle", 9) 1167 .Case(".seq", 10) 1168 .Case(".ngl", 11) 1169 .Case(".lt", 12) 1170 .Case(".nge", 13) 1171 .Case(".le", 14) 1172 .Case(".ngt", 15) 1173 .Default(-1); 1174 1175 return CC; 1176} 1177 1178bool MipsAsmParser:: 1179parseMathOperation(StringRef Name, SMLoc NameLoc, 1180 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1181 // split the format 1182 size_t Start = Name.find('.'), Next = Name.rfind('.'); 1183 StringRef Format1 = Name.slice(Start, Next); 1184 // and add the first format to the operands 1185 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 1186 // now for the second format 1187 StringRef Format2 = Name.slice(Next, StringRef::npos); 1188 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1189 1190 // set the format for the first register 1191 setFpFormat(Format1); 1192 1193 // Read the remaining operands. 1194 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1195 // Read the first operand. 1196 if (ParseOperand(Operands, Name)) { 1197 SMLoc Loc = getLexer().getLoc(); 1198 Parser.EatToEndOfStatement(); 1199 return Error(Loc, "unexpected token in argument list"); 1200 } 1201 1202 if (getLexer().isNot(AsmToken::Comma)) { 1203 SMLoc Loc = getLexer().getLoc(); 1204 Parser.EatToEndOfStatement(); 1205 return Error(Loc, "unexpected token in argument list"); 1206 1207 } 1208 Parser.Lex(); // Eat the comma. 1209 1210 //set the format for the first register 1211 setFpFormat(Format2); 1212 1213 // Parse and remember the operand. 1214 if (ParseOperand(Operands, Name)) { 1215 SMLoc Loc = getLexer().getLoc(); 1216 Parser.EatToEndOfStatement(); 1217 return Error(Loc, "unexpected token in argument list"); 1218 } 1219 } 1220 1221 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1222 SMLoc Loc = getLexer().getLoc(); 1223 Parser.EatToEndOfStatement(); 1224 return Error(Loc, "unexpected token in argument list"); 1225 } 1226 1227 Parser.Lex(); // Consume the EndOfStatement 1228 return false; 1229} 1230 1231bool MipsAsmParser:: 1232ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1233 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1234 // floating point instructions: should register be treated as double? 1235 if (requestsDoubleOperand(Name)) { 1236 setFpFormat(FP_FORMAT_D); 1237 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1238 } 1239 else { 1240 setDefaultFpFormat(); 1241 // Create the leading tokens for the mnemonic, split by '.' characters. 1242 size_t Start = 0, Next = Name.find('.'); 1243 StringRef Mnemonic = Name.slice(Start, Next); 1244 1245 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1246 1247 if (Next != StringRef::npos) { 1248 // there is a format token in mnemonic 1249 // StringRef Rest = Name.slice(Next, StringRef::npos); 1250 size_t Dot = Name.find('.', Next+1); 1251 StringRef Format = Name.slice(Next, Dot); 1252 if (Dot == StringRef::npos) //only one '.' in a string, it's a format 1253 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1254 else { 1255 if (Name.startswith("c.")){ 1256 // floating point compare, add '.' and immediate represent for cc 1257 Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1258 int Cc = ConvertCcString(Format); 1259 if (Cc == -1) { 1260 return Error(NameLoc, "Invalid conditional code"); 1261 } 1262 SMLoc E = SMLoc::getFromPointer( 1263 Parser.getTok().getLoc().getPointer() -1 ); 1264 Operands.push_back(MipsOperand::CreateImm( 1265 MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 1266 } else { 1267 // trunc, ceil, floor ... 1268 return parseMathOperation(Name, NameLoc, Operands); 1269 } 1270 1271 // the rest is a format 1272 Format = Name.slice(Dot, StringRef::npos); 1273 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1274 } 1275 1276 setFpFormat(Format); 1277 } 1278 } 1279 1280 // Read the remaining operands. 1281 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1282 // Read the first operand. 1283 if (ParseOperand(Operands, Name)) { 1284 SMLoc Loc = getLexer().getLoc(); 1285 Parser.EatToEndOfStatement(); 1286 return Error(Loc, "unexpected token in argument list"); 1287 } 1288 1289 while (getLexer().is(AsmToken::Comma) ) { 1290 Parser.Lex(); // Eat the comma. 1291 1292 // Parse and remember the operand. 1293 if (ParseOperand(Operands, Name)) { 1294 SMLoc Loc = getLexer().getLoc(); 1295 Parser.EatToEndOfStatement(); 1296 return Error(Loc, "unexpected token in argument list"); 1297 } 1298 } 1299 } 1300 1301 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1302 SMLoc Loc = getLexer().getLoc(); 1303 Parser.EatToEndOfStatement(); 1304 return Error(Loc, "unexpected token in argument list"); 1305 } 1306 1307 Parser.Lex(); // Consume the EndOfStatement 1308 return false; 1309} 1310 1311bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1312 SMLoc Loc = getLexer().getLoc(); 1313 Parser.EatToEndOfStatement(); 1314 return Error(Loc, ErrorMsg); 1315} 1316 1317bool MipsAsmParser::parseSetNoAtDirective() { 1318 // line should look like: 1319 // .set noat 1320 // set at reg to 0 1321 Options.setATReg(0); 1322 // eat noat 1323 Parser.Lex(); 1324 // if this is not the end of the statement, report error 1325 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1326 reportParseError("unexpected token in statement"); 1327 return false; 1328 } 1329 Parser.Lex(); // Consume the EndOfStatement 1330 return false; 1331} 1332bool MipsAsmParser::parseSetAtDirective() { 1333 // line can be 1334 // .set at - defaults to $1 1335 // or .set at=$reg 1336 getParser().Lex(); 1337 if (getLexer().is(AsmToken::EndOfStatement)) { 1338 Options.setATReg(1); 1339 Parser.Lex(); // Consume the EndOfStatement 1340 return false; 1341 } else if (getLexer().is(AsmToken::Equal)) { 1342 getParser().Lex(); //eat '=' 1343 if (getLexer().isNot(AsmToken::Dollar)) { 1344 reportParseError("unexpected token in statement"); 1345 return false; 1346 } 1347 Parser.Lex(); // eat '$' 1348 if (getLexer().isNot(AsmToken::Integer)) { 1349 reportParseError("unexpected token in statement"); 1350 return false; 1351 } 1352 const AsmToken &Reg = Parser.getTok(); 1353 if (!Options.setATReg(Reg.getIntVal())) { 1354 reportParseError("unexpected token in statement"); 1355 return false; 1356 } 1357 getParser().Lex(); //eat reg 1358 1359 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1360 reportParseError("unexpected token in statement"); 1361 return false; 1362 } 1363 Parser.Lex(); // Consume the EndOfStatement 1364 return false; 1365 } else { 1366 reportParseError("unexpected token in statement"); 1367 return false; 1368 } 1369} 1370 1371bool MipsAsmParser::parseSetReorderDirective() { 1372 Parser.Lex(); 1373 // if this is not the end of the statement, report error 1374 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1375 reportParseError("unexpected token in statement"); 1376 return false; 1377 } 1378 Options.setReorder(); 1379 Parser.Lex(); // Consume the EndOfStatement 1380 return false; 1381} 1382 1383bool MipsAsmParser::parseSetNoReorderDirective() { 1384 Parser.Lex(); 1385 // if this is not the end of the statement, report error 1386 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1387 reportParseError("unexpected token in statement"); 1388 return false; 1389 } 1390 Options.setNoreorder(); 1391 Parser.Lex(); // Consume the EndOfStatement 1392 return false; 1393} 1394 1395bool MipsAsmParser::parseSetMacroDirective() { 1396 Parser.Lex(); 1397 // if this is not the end of the statement, report error 1398 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1399 reportParseError("unexpected token in statement"); 1400 return false; 1401 } 1402 Options.setMacro(); 1403 Parser.Lex(); // Consume the EndOfStatement 1404 return false; 1405} 1406 1407bool MipsAsmParser::parseSetNoMacroDirective() { 1408 Parser.Lex(); 1409 // if this is not the end of the statement, report error 1410 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1411 reportParseError("`noreorder' must be set before `nomacro'"); 1412 return false; 1413 } 1414 if (Options.isReorder()) { 1415 reportParseError("`noreorder' must be set before `nomacro'"); 1416 return false; 1417 } 1418 Options.setNomacro(); 1419 Parser.Lex(); // Consume the EndOfStatement 1420 return false; 1421} 1422bool MipsAsmParser::parseDirectiveSet() { 1423 1424 // get next token 1425 const AsmToken &Tok = Parser.getTok(); 1426 1427 if (Tok.getString() == "noat") { 1428 return parseSetNoAtDirective(); 1429 } else if (Tok.getString() == "at") { 1430 return parseSetAtDirective(); 1431 } else if (Tok.getString() == "reorder") { 1432 return parseSetReorderDirective(); 1433 } else if (Tok.getString() == "noreorder") { 1434 return parseSetNoReorderDirective(); 1435 } else if (Tok.getString() == "macro") { 1436 return parseSetMacroDirective(); 1437 } else if (Tok.getString() == "nomacro") { 1438 return parseSetNoMacroDirective(); 1439 } else if (Tok.getString() == "nomips16") { 1440 // ignore this directive for now 1441 Parser.EatToEndOfStatement(); 1442 return false; 1443 } else if (Tok.getString() == "nomicromips") { 1444 // ignore this directive for now 1445 Parser.EatToEndOfStatement(); 1446 return false; 1447 } 1448 return true; 1449} 1450 1451bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1452 1453 if (DirectiveID.getString() == ".ent") { 1454 // ignore this directive for now 1455 Parser.Lex(); 1456 return false; 1457 } 1458 1459 if (DirectiveID.getString() == ".end") { 1460 // ignore this directive for now 1461 Parser.Lex(); 1462 return false; 1463 } 1464 1465 if (DirectiveID.getString() == ".frame") { 1466 // ignore this directive for now 1467 Parser.EatToEndOfStatement(); 1468 return false; 1469 } 1470 1471 if (DirectiveID.getString() == ".set") { 1472 return parseDirectiveSet(); 1473 } 1474 1475 if (DirectiveID.getString() == ".fmask") { 1476 // ignore this directive for now 1477 Parser.EatToEndOfStatement(); 1478 return false; 1479 } 1480 1481 if (DirectiveID.getString() == ".mask") { 1482 // ignore this directive for now 1483 Parser.EatToEndOfStatement(); 1484 return false; 1485 } 1486 1487 if (DirectiveID.getString() == ".gpword") { 1488 // ignore this directive for now 1489 Parser.EatToEndOfStatement(); 1490 return false; 1491 } 1492 1493 return true; 1494} 1495 1496extern "C" void LLVMInitializeMipsAsmParser() { 1497 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1498 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1499 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1500 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1501} 1502 1503#define GET_REGISTER_MATCHER 1504#define GET_MATCHER_IMPLEMENTATION 1505#include "MipsGenAsmMatcher.inc" 1506