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