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