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