MipsAsmParser.cpp revision 77217229ba1bbc92f3a53099fa91bcdaa7797da8
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 int LoSign = Val & 0x8000; 892 Val = (Val & 0xffff0000) >> 16; 893 //lower part is treated as signed int, so if it is negative 894 //we must add 1 to hi part to compensate 895 if (LoSign) 896 Val++; 897 } 898 Res = MCConstantExpr::Create(Val, getContext()); 899 return false; 900 } 901 902 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) { 903 // it's a symbol, create symbolic expression from symbol 904 StringRef Symbol = MSRE->getSymbol().getName(); 905 MCSymbolRefExpr::VariantKind VK = getVariantKind(Str); 906 Res = MCSymbolRefExpr::Create(Symbol,VK,getContext()); 907 return false; 908 } 909 return true; 910} 911 912bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 913 SMLoc &EndLoc) { 914 915 StartLoc = Parser.getTok().getLoc(); 916 RegNo = tryParseRegister(isMips64()); 917 EndLoc = Parser.getTok().getLoc(); 918 return (RegNo == (unsigned)-1); 919} 920 921bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) { 922 923 SMLoc S; 924 925 switch(getLexer().getKind()) { 926 default: 927 return true; 928 case AsmToken::Integer: 929 case AsmToken::Minus: 930 case AsmToken::Plus: 931 return (getParser().parseExpression(Res)); 932 case AsmToken::Percent: 933 return parseRelocOperand(Res); 934 case AsmToken::LParen: 935 return false; // it's probably assuming 0 936 } 937 return true; 938} 939 940MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 941 SmallVectorImpl<MCParsedAsmOperand*>&Operands) { 942 943 const MCExpr *IdVal = 0; 944 SMLoc S; 945 // first operand is the offset 946 S = Parser.getTok().getLoc(); 947 948 if (parseMemOffset(IdVal)) 949 return MatchOperand_ParseFail; 950 951 const AsmToken &Tok = Parser.getTok(); // get next token 952 if (Tok.isNot(AsmToken::LParen)) { 953 MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]); 954 if (Mnemonic->getToken() == "la") { 955 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1); 956 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 957 return MatchOperand_Success; 958 } 959 Error(Parser.getTok().getLoc(), "'(' expected"); 960 return MatchOperand_ParseFail; 961 } 962 963 Parser.Lex(); // Eat '(' token. 964 965 const AsmToken &Tok1 = Parser.getTok(); // get next token 966 if (Tok1.is(AsmToken::Dollar)) { 967 Parser.Lex(); // Eat '$' token. 968 if (tryParseRegisterOperand(Operands, isMips64())) { 969 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 970 return MatchOperand_ParseFail; 971 } 972 973 } else { 974 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 975 return MatchOperand_ParseFail; 976 } 977 978 const AsmToken &Tok2 = Parser.getTok(); // get next token 979 if (Tok2.isNot(AsmToken::RParen)) { 980 Error(Parser.getTok().getLoc(), "')' expected"); 981 return MatchOperand_ParseFail; 982 } 983 984 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 985 986 Parser.Lex(); // Eat ')' token. 987 988 if (IdVal == 0) 989 IdVal = MCConstantExpr::Create(0, getContext()); 990 991 // now replace register operand with the mem operand 992 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 993 int RegNo = op->getReg(); 994 // remove register from operands 995 Operands.pop_back(); 996 // and add memory operand 997 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 998 delete op; 999 return MatchOperand_Success; 1000} 1001 1002MipsAsmParser::OperandMatchResultTy 1003MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1004 1005 if (!isMips64()) 1006 return MatchOperand_NoMatch; 1007 // if the first token is not '$' we have an error 1008 if (Parser.getTok().isNot(AsmToken::Dollar)) 1009 return MatchOperand_NoMatch; 1010 1011 Parser.Lex(); // Eat $ 1012 if(!tryParseRegisterOperand(Operands, true)) { 1013 // set the proper register kind 1014 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1015 op->setRegKind(MipsOperand::Kind_CPU64Regs); 1016 return MatchOperand_Success; 1017 } 1018 return MatchOperand_NoMatch; 1019} 1020 1021MipsAsmParser::OperandMatchResultTy 1022MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1023 1024 // if the first token is not '$' we have an error 1025 if (Parser.getTok().isNot(AsmToken::Dollar)) 1026 return MatchOperand_NoMatch; 1027 1028 Parser.Lex(); // Eat $ 1029 if(!tryParseRegisterOperand(Operands, false)) { 1030 // set the propper register kind 1031 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1032 op->setRegKind(MipsOperand::Kind_CPURegs); 1033 return MatchOperand_Success; 1034 } 1035 return MatchOperand_NoMatch; 1036} 1037 1038MipsAsmParser::OperandMatchResultTy 1039MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1040 1041 if (isMips64()) 1042 return MatchOperand_NoMatch; 1043 1044 // if the first token is not '$' we have error 1045 if (Parser.getTok().isNot(AsmToken::Dollar)) 1046 return MatchOperand_NoMatch; 1047 SMLoc S = Parser.getTok().getLoc(); 1048 Parser.Lex(); // Eat $ 1049 1050 const AsmToken &Tok = Parser.getTok(); // get next token 1051 if (Tok.isNot(AsmToken::Integer)) 1052 return MatchOperand_NoMatch; 1053 1054 unsigned RegNum = Tok.getIntVal(); 1055 // at the moment only hwreg29 is supported 1056 if (RegNum != 29) 1057 return MatchOperand_ParseFail; 1058 1059 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 1060 Parser.getTok().getLoc()); 1061 op->setRegKind(MipsOperand::Kind_HWRegs); 1062 Operands.push_back(op); 1063 1064 Parser.Lex(); // Eat reg number 1065 return MatchOperand_Success; 1066} 1067 1068MipsAsmParser::OperandMatchResultTy 1069MipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1070 1071 if (!isMips64()) 1072 return MatchOperand_NoMatch; 1073 //if the first token is not '$' we have error 1074 if (Parser.getTok().isNot(AsmToken::Dollar)) 1075 return MatchOperand_NoMatch; 1076 SMLoc S = Parser.getTok().getLoc(); 1077 Parser.Lex(); // Eat $ 1078 1079 const AsmToken &Tok = Parser.getTok(); // get next token 1080 if (Tok.isNot(AsmToken::Integer)) 1081 return MatchOperand_NoMatch; 1082 1083 unsigned RegNum = Tok.getIntVal(); 1084 // at the moment only hwreg29 is supported 1085 if (RegNum != 29) 1086 return MatchOperand_ParseFail; 1087 1088 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 1089 Parser.getTok().getLoc()); 1090 op->setRegKind(MipsOperand::Kind_HW64Regs); 1091 Operands.push_back(op); 1092 1093 Parser.Lex(); // Eat reg number 1094 return MatchOperand_Success; 1095} 1096 1097MipsAsmParser::OperandMatchResultTy 1098MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1099 unsigned RegNum; 1100 //if the first token is not '$' we have error 1101 if (Parser.getTok().isNot(AsmToken::Dollar)) 1102 return MatchOperand_NoMatch; 1103 SMLoc S = Parser.getTok().getLoc(); 1104 Parser.Lex(); // Eat $ 1105 1106 const AsmToken &Tok = Parser.getTok(); // get next token 1107 if (Tok.is(AsmToken::Integer)) { 1108 RegNum = Tok.getIntVal(); 1109 // at the moment only fcc0 is supported 1110 if (RegNum != 0) 1111 return MatchOperand_ParseFail; 1112 } else if (Tok.is(AsmToken::Identifier)) { 1113 // at the moment only fcc0 is supported 1114 if (Tok.getIdentifier() != "fcc0") 1115 return MatchOperand_ParseFail; 1116 } else 1117 return MatchOperand_NoMatch; 1118 1119 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 1120 Parser.getTok().getLoc()); 1121 op->setRegKind(MipsOperand::Kind_CCRRegs); 1122 Operands.push_back(op); 1123 1124 Parser.Lex(); // Eat reg number 1125 return MatchOperand_Success; 1126} 1127 1128MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1129 1130 MCSymbolRefExpr::VariantKind VK 1131 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1132 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1133 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1134 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1135 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1136 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1137 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1138 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1139 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1140 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1141 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1142 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1143 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1144 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1145 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1146 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1147 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1148 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1149 .Default(MCSymbolRefExpr::VK_None); 1150 1151 return VK; 1152} 1153 1154static int ConvertCcString(StringRef CondString) { 1155 int CC = StringSwitch<unsigned>(CondString) 1156 .Case(".f", 0) 1157 .Case(".un", 1) 1158 .Case(".eq", 2) 1159 .Case(".ueq", 3) 1160 .Case(".olt", 4) 1161 .Case(".ult", 5) 1162 .Case(".ole", 6) 1163 .Case(".ule", 7) 1164 .Case(".sf", 8) 1165 .Case(".ngle", 9) 1166 .Case(".seq", 10) 1167 .Case(".ngl", 11) 1168 .Case(".lt", 12) 1169 .Case(".nge", 13) 1170 .Case(".le", 14) 1171 .Case(".ngt", 15) 1172 .Default(-1); 1173 1174 return CC; 1175} 1176 1177bool MipsAsmParser:: 1178parseMathOperation(StringRef Name, SMLoc NameLoc, 1179 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1180 // split the format 1181 size_t Start = Name.find('.'), Next = Name.rfind('.'); 1182 StringRef Format1 = Name.slice(Start, Next); 1183 // and add the first format to the operands 1184 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 1185 // now for the second format 1186 StringRef Format2 = Name.slice(Next, StringRef::npos); 1187 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1188 1189 // set the format for the first register 1190 setFpFormat(Format1); 1191 1192 // Read the remaining operands. 1193 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1194 // Read the first operand. 1195 if (ParseOperand(Operands, Name)) { 1196 SMLoc Loc = getLexer().getLoc(); 1197 Parser.eatToEndOfStatement(); 1198 return Error(Loc, "unexpected token in argument list"); 1199 } 1200 1201 if (getLexer().isNot(AsmToken::Comma)) { 1202 SMLoc Loc = getLexer().getLoc(); 1203 Parser.eatToEndOfStatement(); 1204 return Error(Loc, "unexpected token in argument list"); 1205 1206 } 1207 Parser.Lex(); // Eat the comma. 1208 1209 //set the format for the first register 1210 setFpFormat(Format2); 1211 1212 // Parse and remember the operand. 1213 if (ParseOperand(Operands, Name)) { 1214 SMLoc Loc = getLexer().getLoc(); 1215 Parser.eatToEndOfStatement(); 1216 return Error(Loc, "unexpected token in argument list"); 1217 } 1218 } 1219 1220 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1221 SMLoc Loc = getLexer().getLoc(); 1222 Parser.eatToEndOfStatement(); 1223 return Error(Loc, "unexpected token in argument list"); 1224 } 1225 1226 Parser.Lex(); // Consume the EndOfStatement 1227 return false; 1228} 1229 1230bool MipsAsmParser:: 1231ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1232 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1233 StringRef Mnemonic; 1234 // floating point instructions: should register be treated as double? 1235 if (requestsDoubleOperand(Name)) { 1236 setFpFormat(FP_FORMAT_D); 1237 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1238 Mnemonic = Name; 1239 } 1240 else { 1241 setDefaultFpFormat(); 1242 // Create the leading tokens for the mnemonic, split by '.' characters. 1243 size_t Start = 0, Next = Name.find('.'); 1244 Mnemonic = Name.slice(Start, Next); 1245 1246 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1247 1248 if (Next != StringRef::npos) { 1249 // there is a format token in mnemonic 1250 // StringRef Rest = Name.slice(Next, StringRef::npos); 1251 size_t Dot = Name.find('.', Next+1); 1252 StringRef Format = Name.slice(Next, Dot); 1253 if (Dot == StringRef::npos) //only one '.' in a string, it's a format 1254 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1255 else { 1256 if (Name.startswith("c.")){ 1257 // floating point compare, add '.' and immediate represent for cc 1258 Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1259 int Cc = ConvertCcString(Format); 1260 if (Cc == -1) { 1261 return Error(NameLoc, "Invalid conditional code"); 1262 } 1263 SMLoc E = SMLoc::getFromPointer( 1264 Parser.getTok().getLoc().getPointer() -1 ); 1265 Operands.push_back(MipsOperand::CreateImm( 1266 MCConstantExpr::Create(Cc, getContext()), NameLoc, E)); 1267 } else { 1268 // trunc, ceil, floor ... 1269 return parseMathOperation(Name, NameLoc, Operands); 1270 } 1271 1272 // the rest is a format 1273 Format = Name.slice(Dot, StringRef::npos); 1274 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1275 } 1276 1277 setFpFormat(Format); 1278 } 1279 } 1280 1281 // Read the remaining operands. 1282 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1283 // Read the first operand. 1284 if (ParseOperand(Operands, Mnemonic)) { 1285 SMLoc Loc = getLexer().getLoc(); 1286 Parser.eatToEndOfStatement(); 1287 return Error(Loc, "unexpected token in argument list"); 1288 } 1289 1290 while (getLexer().is(AsmToken::Comma) ) { 1291 Parser.Lex(); // Eat the comma. 1292 1293 // Parse and remember the operand. 1294 if (ParseOperand(Operands, Name)) { 1295 SMLoc Loc = getLexer().getLoc(); 1296 Parser.eatToEndOfStatement(); 1297 return Error(Loc, "unexpected token in argument list"); 1298 } 1299 } 1300 } 1301 1302 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1303 SMLoc Loc = getLexer().getLoc(); 1304 Parser.eatToEndOfStatement(); 1305 return Error(Loc, "unexpected token in argument list"); 1306 } 1307 1308 Parser.Lex(); // Consume the EndOfStatement 1309 return false; 1310} 1311 1312bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1313 SMLoc Loc = getLexer().getLoc(); 1314 Parser.eatToEndOfStatement(); 1315 return Error(Loc, ErrorMsg); 1316} 1317 1318bool MipsAsmParser::parseSetNoAtDirective() { 1319 // line should look like: 1320 // .set noat 1321 // set at reg to 0 1322 Options.setATReg(0); 1323 // eat noat 1324 Parser.Lex(); 1325 // if this is not the end of the statement, report error 1326 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1327 reportParseError("unexpected token in statement"); 1328 return false; 1329 } 1330 Parser.Lex(); // Consume the EndOfStatement 1331 return false; 1332} 1333bool MipsAsmParser::parseSetAtDirective() { 1334 // line can be 1335 // .set at - defaults to $1 1336 // or .set at=$reg 1337 int AtRegNo; 1338 getParser().Lex(); 1339 if (getLexer().is(AsmToken::EndOfStatement)) { 1340 Options.setATReg(1); 1341 Parser.Lex(); // Consume the EndOfStatement 1342 return false; 1343 } else if (getLexer().is(AsmToken::Equal)) { 1344 getParser().Lex(); //eat '=' 1345 if (getLexer().isNot(AsmToken::Dollar)) { 1346 reportParseError("unexpected token in statement"); 1347 return false; 1348 } 1349 Parser.Lex(); // eat '$' 1350 const AsmToken &Reg = Parser.getTok(); 1351 if (Reg.is(AsmToken::Identifier)) { 1352 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 1353 } else if (Reg.is(AsmToken::Integer)) { 1354 AtRegNo = Reg.getIntVal(); 1355 } else { 1356 reportParseError("unexpected token in statement"); 1357 return false; 1358 } 1359 1360 if ( AtRegNo < 1 || AtRegNo > 31) { 1361 reportParseError("unexpected token in statement"); 1362 return false; 1363 } 1364 1365 if (!Options.setATReg(AtRegNo)) { 1366 reportParseError("unexpected token in statement"); 1367 return false; 1368 } 1369 getParser().Lex(); //eat reg 1370 1371 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1372 reportParseError("unexpected token in statement"); 1373 return false; 1374 } 1375 Parser.Lex(); // Consume the EndOfStatement 1376 return false; 1377 } else { 1378 reportParseError("unexpected token in statement"); 1379 return false; 1380 } 1381} 1382 1383bool MipsAsmParser::parseSetReorderDirective() { 1384 Parser.Lex(); 1385 // if this is not the end of the statement, report error 1386 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1387 reportParseError("unexpected token in statement"); 1388 return false; 1389 } 1390 Options.setReorder(); 1391 Parser.Lex(); // Consume the EndOfStatement 1392 return false; 1393} 1394 1395bool MipsAsmParser::parseSetNoReorderDirective() { 1396 Parser.Lex(); 1397 // if this is not the end of the statement, report error 1398 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1399 reportParseError("unexpected token in statement"); 1400 return false; 1401 } 1402 Options.setNoreorder(); 1403 Parser.Lex(); // Consume the EndOfStatement 1404 return false; 1405} 1406 1407bool MipsAsmParser::parseSetMacroDirective() { 1408 Parser.Lex(); 1409 // if this is not the end of the statement, report error 1410 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1411 reportParseError("unexpected token in statement"); 1412 return false; 1413 } 1414 Options.setMacro(); 1415 Parser.Lex(); // Consume the EndOfStatement 1416 return false; 1417} 1418 1419bool MipsAsmParser::parseSetNoMacroDirective() { 1420 Parser.Lex(); 1421 // if this is not the end of the statement, report error 1422 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1423 reportParseError("`noreorder' must be set before `nomacro'"); 1424 return false; 1425 } 1426 if (Options.isReorder()) { 1427 reportParseError("`noreorder' must be set before `nomacro'"); 1428 return false; 1429 } 1430 Options.setNomacro(); 1431 Parser.Lex(); // Consume the EndOfStatement 1432 return false; 1433} 1434bool MipsAsmParser::parseDirectiveSet() { 1435 1436 // get next token 1437 const AsmToken &Tok = Parser.getTok(); 1438 1439 if (Tok.getString() == "noat") { 1440 return parseSetNoAtDirective(); 1441 } else if (Tok.getString() == "at") { 1442 return parseSetAtDirective(); 1443 } else if (Tok.getString() == "reorder") { 1444 return parseSetReorderDirective(); 1445 } else if (Tok.getString() == "noreorder") { 1446 return parseSetNoReorderDirective(); 1447 } else if (Tok.getString() == "macro") { 1448 return parseSetMacroDirective(); 1449 } else if (Tok.getString() == "nomacro") { 1450 return parseSetNoMacroDirective(); 1451 } else if (Tok.getString() == "nomips16") { 1452 // ignore this directive for now 1453 Parser.eatToEndOfStatement(); 1454 return false; 1455 } else if (Tok.getString() == "nomicromips") { 1456 // ignore this directive for now 1457 Parser.eatToEndOfStatement(); 1458 return false; 1459 } 1460 1461 return true; 1462} 1463 1464/// parseDirectiveWord 1465/// ::= .word [ expression (, expression)* ] 1466bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1467 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1468 for (;;) { 1469 const MCExpr *Value; 1470 if (getParser().parseExpression(Value)) 1471 return true; 1472 1473 getParser().getStreamer().EmitValue(Value, Size); 1474 1475 if (getLexer().is(AsmToken::EndOfStatement)) 1476 break; 1477 1478 // FIXME: Improve diagnostic. 1479 if (getLexer().isNot(AsmToken::Comma)) 1480 return Error(L, "unexpected token in directive"); 1481 Parser.Lex(); 1482 } 1483 } 1484 1485 Parser.Lex(); 1486 return false; 1487} 1488 1489bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1490 1491 StringRef IDVal = DirectiveID.getString(); 1492 1493 if ( IDVal == ".ent") { 1494 // ignore this directive for now 1495 Parser.Lex(); 1496 return false; 1497 } 1498 1499 if (IDVal == ".end") { 1500 // ignore this directive for now 1501 Parser.Lex(); 1502 return false; 1503 } 1504 1505 if (IDVal == ".frame") { 1506 // ignore this directive for now 1507 Parser.eatToEndOfStatement(); 1508 return false; 1509 } 1510 1511 if (IDVal == ".set") { 1512 return parseDirectiveSet(); 1513 } 1514 1515 if (IDVal == ".fmask") { 1516 // ignore this directive for now 1517 Parser.eatToEndOfStatement(); 1518 return false; 1519 } 1520 1521 if (IDVal == ".mask") { 1522 // ignore this directive for now 1523 Parser.eatToEndOfStatement(); 1524 return false; 1525 } 1526 1527 if (IDVal == ".gpword") { 1528 // ignore this directive for now 1529 Parser.eatToEndOfStatement(); 1530 return false; 1531 } 1532 1533 if (IDVal == ".word") { 1534 parseDirectiveWord(4, DirectiveID.getLoc()); 1535 return false; 1536 } 1537 1538 return true; 1539} 1540 1541extern "C" void LLVMInitializeMipsAsmParser() { 1542 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1543 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1544 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1545 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1546} 1547 1548#define GET_REGISTER_MATCHER 1549#define GET_MATCHER_IMPLEMENTATION 1550#include "MipsGenAsmMatcher.inc" 1551