MipsAsmParser.cpp revision 490c7d97737ea7719efcea7321d3cfa3984b0027
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 1075 if (!isMips64()) 1076 return MatchOperand_NoMatch; 1077 //if the first token is not '$' we have error 1078 if (Parser.getTok().isNot(AsmToken::Dollar)) 1079 return MatchOperand_NoMatch; 1080 SMLoc S = Parser.getTok().getLoc(); 1081 Parser.Lex(); // Eat $ 1082 1083 const AsmToken &Tok = Parser.getTok(); // get next token 1084 if (Tok.isNot(AsmToken::Integer)) 1085 return MatchOperand_NoMatch; 1086 1087 unsigned RegNum = Tok.getIntVal(); 1088 // at the moment only hwreg29 is supported 1089 if (RegNum != 29) 1090 return MatchOperand_ParseFail; 1091 1092 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 1093 Parser.getTok().getLoc()); 1094 op->setRegKind(MipsOperand::Kind_HW64Regs); 1095 Operands.push_back(op); 1096 1097 Parser.Lex(); // Eat reg number 1098 return MatchOperand_Success; 1099} 1100 1101MipsAsmParser::OperandMatchResultTy 1102MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1103 unsigned RegNum; 1104 //if the first token is not '$' we have error 1105 if (Parser.getTok().isNot(AsmToken::Dollar)) 1106 return MatchOperand_NoMatch; 1107 SMLoc S = Parser.getTok().getLoc(); 1108 Parser.Lex(); // Eat $ 1109 1110 const AsmToken &Tok = Parser.getTok(); // get next token 1111 if (Tok.is(AsmToken::Integer)) { 1112 RegNum = Tok.getIntVal(); 1113 // at the moment only fcc0 is supported 1114 if (RegNum != 0) 1115 return MatchOperand_ParseFail; 1116 } else if (Tok.is(AsmToken::Identifier)) { 1117 // at the moment only fcc0 is supported 1118 if (Tok.getIdentifier() != "fcc0") 1119 return MatchOperand_ParseFail; 1120 } else 1121 return MatchOperand_NoMatch; 1122 1123 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 1124 Parser.getTok().getLoc()); 1125 op->setRegKind(MipsOperand::Kind_CCRRegs); 1126 Operands.push_back(op); 1127 1128 Parser.Lex(); // Eat reg number 1129 return MatchOperand_Success; 1130} 1131 1132MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1133 1134 MCSymbolRefExpr::VariantKind VK 1135 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1136 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1137 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1138 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1139 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1140 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1141 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1142 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1143 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1144 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1145 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1146 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1147 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1148 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1149 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1150 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1151 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1152 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1153 .Default(MCSymbolRefExpr::VK_None); 1154 1155 return VK; 1156} 1157 1158static int ConvertCcString(StringRef CondString) { 1159 int CC = StringSwitch<unsigned>(CondString) 1160 .Case(".f", 0) 1161 .Case(".un", 1) 1162 .Case(".eq", 2) 1163 .Case(".ueq", 3) 1164 .Case(".olt", 4) 1165 .Case(".ult", 5) 1166 .Case(".ole", 6) 1167 .Case(".ule", 7) 1168 .Case(".sf", 8) 1169 .Case(".ngle", 9) 1170 .Case(".seq", 10) 1171 .Case(".ngl", 11) 1172 .Case(".lt", 12) 1173 .Case(".nge", 13) 1174 .Case(".le", 14) 1175 .Case(".ngt", 15) 1176 .Default(-1); 1177 1178 return CC; 1179} 1180 1181bool MipsAsmParser:: 1182parseMathOperation(StringRef Name, SMLoc NameLoc, 1183 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1184 // split the format 1185 size_t Start = Name.find('.'), Next = Name.rfind('.'); 1186 StringRef Format1 = Name.slice(Start, Next); 1187 // and add the first format to the operands 1188 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 1189 // now for the second format 1190 StringRef Format2 = Name.slice(Next, StringRef::npos); 1191 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1192 1193 // set the format for the first register 1194 setFpFormat(Format1); 1195 1196 // Read the remaining operands. 1197 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1198 // Read the first operand. 1199 if (ParseOperand(Operands, Name)) { 1200 SMLoc Loc = getLexer().getLoc(); 1201 Parser.EatToEndOfStatement(); 1202 return Error(Loc, "unexpected token in argument list"); 1203 } 1204 1205 if (getLexer().isNot(AsmToken::Comma)) { 1206 SMLoc Loc = getLexer().getLoc(); 1207 Parser.EatToEndOfStatement(); 1208 return Error(Loc, "unexpected token in argument list"); 1209 1210 } 1211 Parser.Lex(); // Eat the comma. 1212 1213 //set the format for the first register 1214 setFpFormat(Format2); 1215 1216 // Parse and remember the operand. 1217 if (ParseOperand(Operands, Name)) { 1218 SMLoc Loc = getLexer().getLoc(); 1219 Parser.EatToEndOfStatement(); 1220 return Error(Loc, "unexpected token in argument list"); 1221 } 1222 } 1223 1224 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1225 SMLoc Loc = getLexer().getLoc(); 1226 Parser.EatToEndOfStatement(); 1227 return Error(Loc, "unexpected token in argument list"); 1228 } 1229 1230 Parser.Lex(); // Consume the EndOfStatement 1231 return false; 1232} 1233 1234bool MipsAsmParser:: 1235ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1236 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1237 // floating point instructions: should register be treated as double? 1238 if (requestsDoubleOperand(Name)) { 1239 setFpFormat(FP_FORMAT_D); 1240 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1241 } 1242 else { 1243 setDefaultFpFormat(); 1244 // Create the leading tokens for the mnemonic, split by '.' characters. 1245 size_t Start = 0, Next = Name.find('.'); 1246 StringRef Mnemonic = Name.slice(Start, Next); 1247 1248 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1249 1250 if (Next != StringRef::npos) { 1251 // there is a format token in mnemonic 1252 // StringRef Rest = Name.slice(Next, StringRef::npos); 1253 size_t Dot = Name.find('.', Next+1); 1254 StringRef Format = Name.slice(Next, Dot); 1255 if (Dot == StringRef::npos) //only one '.' in a string, it's a format 1256 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1257 else { 1258 if (Name.startswith("c.")){ 1259 // floating point compare, add '.' and immediate represent for cc 1260 Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1261 int Cc = ConvertCcString(Format); 1262 if (Cc == -1) { 1263 return Error(NameLoc, "Invalid conditional code"); 1264 } 1265 SMLoc E = SMLoc::getFromPointer( 1266 Parser.getTok().getLoc().getPointer() -1 ); 1267 Operands.push_back(MipsOperand::CreateImm( 1268 MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 1269 } else { 1270 // trunc, ceil, floor ... 1271 return parseMathOperation(Name, NameLoc, Operands); 1272 } 1273 1274 // the rest is a format 1275 Format = Name.slice(Dot, StringRef::npos); 1276 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1277 } 1278 1279 setFpFormat(Format); 1280 } 1281 } 1282 1283 // Read the remaining operands. 1284 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1285 // Read the first operand. 1286 if (ParseOperand(Operands, Name)) { 1287 SMLoc Loc = getLexer().getLoc(); 1288 Parser.EatToEndOfStatement(); 1289 return Error(Loc, "unexpected token in argument list"); 1290 } 1291 1292 while (getLexer().is(AsmToken::Comma) ) { 1293 Parser.Lex(); // Eat the comma. 1294 1295 // Parse and remember the operand. 1296 if (ParseOperand(Operands, Name)) { 1297 SMLoc Loc = getLexer().getLoc(); 1298 Parser.EatToEndOfStatement(); 1299 return Error(Loc, "unexpected token in argument list"); 1300 } 1301 } 1302 } 1303 1304 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1305 SMLoc Loc = getLexer().getLoc(); 1306 Parser.EatToEndOfStatement(); 1307 return Error(Loc, "unexpected token in argument list"); 1308 } 1309 1310 Parser.Lex(); // Consume the EndOfStatement 1311 return false; 1312} 1313 1314bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1315 SMLoc Loc = getLexer().getLoc(); 1316 Parser.EatToEndOfStatement(); 1317 return Error(Loc, ErrorMsg); 1318} 1319 1320bool MipsAsmParser::parseSetNoAtDirective() { 1321 // line should look like: 1322 // .set noat 1323 // set at reg to 0 1324 Options.setATReg(0); 1325 // eat noat 1326 Parser.Lex(); 1327 // if this is not the end of the statement, report error 1328 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1329 reportParseError("unexpected token in statement"); 1330 return false; 1331 } 1332 Parser.Lex(); // Consume the EndOfStatement 1333 return false; 1334} 1335bool MipsAsmParser::parseSetAtDirective() { 1336 // line can be 1337 // .set at - defaults to $1 1338 // or .set at=$reg 1339 getParser().Lex(); 1340 if (getLexer().is(AsmToken::EndOfStatement)) { 1341 Options.setATReg(1); 1342 Parser.Lex(); // Consume the EndOfStatement 1343 return false; 1344 } else if (getLexer().is(AsmToken::Equal)) { 1345 getParser().Lex(); //eat '=' 1346 if (getLexer().isNot(AsmToken::Dollar)) { 1347 reportParseError("unexpected token in statement"); 1348 return false; 1349 } 1350 Parser.Lex(); // eat '$' 1351 if (getLexer().isNot(AsmToken::Integer)) { 1352 reportParseError("unexpected token in statement"); 1353 return false; 1354 } 1355 const AsmToken &Reg = Parser.getTok(); 1356 if (!Options.setATReg(Reg.getIntVal())) { 1357 reportParseError("unexpected token in statement"); 1358 return false; 1359 } 1360 getParser().Lex(); //eat reg 1361 1362 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1363 reportParseError("unexpected token in statement"); 1364 return false; 1365 } 1366 Parser.Lex(); // Consume the EndOfStatement 1367 return false; 1368 } else { 1369 reportParseError("unexpected token in statement"); 1370 return false; 1371 } 1372} 1373 1374bool MipsAsmParser::parseSetReorderDirective() { 1375 Parser.Lex(); 1376 // if this is not the end of the statement, report error 1377 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1378 reportParseError("unexpected token in statement"); 1379 return false; 1380 } 1381 Options.setReorder(); 1382 Parser.Lex(); // Consume the EndOfStatement 1383 return false; 1384} 1385 1386bool MipsAsmParser::parseSetNoReorderDirective() { 1387 Parser.Lex(); 1388 // if this is not the end of the statement, report error 1389 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1390 reportParseError("unexpected token in statement"); 1391 return false; 1392 } 1393 Options.setNoreorder(); 1394 Parser.Lex(); // Consume the EndOfStatement 1395 return false; 1396} 1397 1398bool MipsAsmParser::parseSetMacroDirective() { 1399 Parser.Lex(); 1400 // if this is not the end of the statement, report error 1401 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1402 reportParseError("unexpected token in statement"); 1403 return false; 1404 } 1405 Options.setMacro(); 1406 Parser.Lex(); // Consume the EndOfStatement 1407 return false; 1408} 1409 1410bool MipsAsmParser::parseSetNoMacroDirective() { 1411 Parser.Lex(); 1412 // if this is not the end of the statement, report error 1413 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1414 reportParseError("`noreorder' must be set before `nomacro'"); 1415 return false; 1416 } 1417 if (Options.isReorder()) { 1418 reportParseError("`noreorder' must be set before `nomacro'"); 1419 return false; 1420 } 1421 Options.setNomacro(); 1422 Parser.Lex(); // Consume the EndOfStatement 1423 return false; 1424} 1425bool MipsAsmParser::parseDirectiveSet() { 1426 1427 // get next token 1428 const AsmToken &Tok = Parser.getTok(); 1429 1430 if (Tok.getString() == "noat") { 1431 return parseSetNoAtDirective(); 1432 } else if (Tok.getString() == "at") { 1433 return parseSetAtDirective(); 1434 } else if (Tok.getString() == "reorder") { 1435 return parseSetReorderDirective(); 1436 } else if (Tok.getString() == "noreorder") { 1437 return parseSetNoReorderDirective(); 1438 } else if (Tok.getString() == "macro") { 1439 return parseSetMacroDirective(); 1440 } else if (Tok.getString() == "nomacro") { 1441 return parseSetNoMacroDirective(); 1442 } else if (Tok.getString() == "nomips16") { 1443 // ignore this directive for now 1444 Parser.EatToEndOfStatement(); 1445 return false; 1446 } else if (Tok.getString() == "nomicromips") { 1447 // ignore this directive for now 1448 Parser.EatToEndOfStatement(); 1449 return false; 1450 } 1451 return true; 1452} 1453 1454bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1455 1456 if (DirectiveID.getString() == ".ent") { 1457 // ignore this directive for now 1458 Parser.Lex(); 1459 return false; 1460 } 1461 1462 if (DirectiveID.getString() == ".end") { 1463 // ignore this directive for now 1464 Parser.Lex(); 1465 return false; 1466 } 1467 1468 if (DirectiveID.getString() == ".frame") { 1469 // ignore this directive for now 1470 Parser.EatToEndOfStatement(); 1471 return false; 1472 } 1473 1474 if (DirectiveID.getString() == ".set") { 1475 return parseDirectiveSet(); 1476 } 1477 1478 if (DirectiveID.getString() == ".fmask") { 1479 // ignore this directive for now 1480 Parser.EatToEndOfStatement(); 1481 return false; 1482 } 1483 1484 if (DirectiveID.getString() == ".mask") { 1485 // ignore this directive for now 1486 Parser.EatToEndOfStatement(); 1487 return false; 1488 } 1489 1490 if (DirectiveID.getString() == ".gpword") { 1491 // ignore this directive for now 1492 Parser.EatToEndOfStatement(); 1493 return false; 1494 } 1495 1496 return true; 1497} 1498 1499extern "C" void LLVMInitializeMipsAsmParser() { 1500 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1501 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1502 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1503 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1504} 1505 1506#define GET_REGISTER_MATCHER 1507#define GET_MATCHER_IMPLEMENTATION 1508#include "MipsGenAsmMatcher.inc" 1509