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