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