MipsAsmParser.cpp revision 99cb622041a0839c7dfcf0263c5102a305a0fdb5
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 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 88 89 MipsAsmParser::OperandMatchResultTy 90 parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 91 92 MipsAsmParser::OperandMatchResultTy 93 parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 94 95 MipsAsmParser::OperandMatchResultTy 96 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 97 98 MipsAsmParser::OperandMatchResultTy 99 parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 100 101 MipsAsmParser::OperandMatchResultTy 102 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands); 103 104 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 105 unsigned RegisterClass); 106 107 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, 108 StringRef Mnemonic); 109 110 int tryParseRegister(bool is64BitReg); 111 112 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands, 113 bool is64BitReg); 114 115 bool needsExpansion(MCInst &Inst); 116 117 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 118 SmallVectorImpl<MCInst> &Instructions); 119 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 120 SmallVectorImpl<MCInst> &Instructions); 121 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 122 SmallVectorImpl<MCInst> &Instructions); 123 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 124 SmallVectorImpl<MCInst> &Instructions); 125 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 126 SmallVectorImpl<MCInst> &Instructions, 127 bool isLoad,bool isImmOpnd); 128 bool reportParseError(StringRef ErrorMsg); 129 130 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 131 bool parseRelocOperand(const MCExpr *&Res); 132 133 const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 134 135 bool isEvaluated(const MCExpr *Expr); 136 bool parseDirectiveSet(); 137 138 bool parseSetAtDirective(); 139 bool parseSetNoAtDirective(); 140 bool parseSetMacroDirective(); 141 bool parseSetNoMacroDirective(); 142 bool parseSetReorderDirective(); 143 bool parseSetNoReorderDirective(); 144 145 bool parseSetAssignment(); 146 147 bool parseDirectiveWord(unsigned Size, SMLoc L); 148 149 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 150 151 bool isMips64() const { 152 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 153 } 154 155 bool isFP64() const { 156 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 157 } 158 159 int matchRegisterName(StringRef Symbol, bool is64BitReg); 160 161 int matchCPURegisterName(StringRef Symbol); 162 163 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 164 165 void setFpFormat(FpFormatTy Format) { 166 FpFormat = Format; 167 } 168 169 void setDefaultFpFormat(); 170 171 void setFpFormat(StringRef Format); 172 173 FpFormatTy getFpFormat() {return FpFormat;} 174 175 bool requestsDoubleOperand(StringRef Mnemonic); 176 177 unsigned getReg(int RC, int RegNo); 178 179 int getATReg(); 180 181 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 182 SmallVectorImpl<MCInst> &Instructions); 183public: 184 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser) 185 : MCTargetAsmParser(), STI(sti), Parser(parser) { 186 // Initialize the set of available features. 187 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 188 } 189 190 MCAsmParser &getParser() const { return Parser; } 191 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 192 193}; 194} 195 196namespace { 197 198/// MipsOperand - Instances of this class represent a parsed Mips machine 199/// instruction. 200class MipsOperand : public MCParsedAsmOperand { 201 202public: 203 enum RegisterKind { 204 Kind_None, 205 Kind_CPURegs, 206 Kind_CPU64Regs, 207 Kind_HWRegs, 208 Kind_HW64Regs, 209 Kind_FGR32Regs, 210 Kind_FGR64Regs, 211 Kind_AFGR64Regs, 212 Kind_CCRRegs 213 }; 214 215private: 216 enum KindTy { 217 k_CondCode, 218 k_CoprocNum, 219 k_Immediate, 220 k_Memory, 221 k_PostIndexRegister, 222 k_Register, 223 k_Token 224 } Kind; 225 226 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 227 228 struct Token { 229 const char *Data; 230 unsigned Length; 231 }; 232 233 struct RegOp { 234 unsigned RegNum; 235 RegisterKind Kind; 236 }; 237 238 struct ImmOp { 239 const MCExpr *Val; 240 }; 241 242 struct MemOp { 243 unsigned Base; 244 const MCExpr *Off; 245 }; 246 247 union { 248 struct Token Tok; 249 struct RegOp Reg; 250 struct ImmOp Imm; 251 struct MemOp Mem; 252 }; 253 254 SMLoc StartLoc, EndLoc; 255 256public: 257 void addRegOperands(MCInst &Inst, unsigned N) const { 258 assert(N == 1 && "Invalid number of operands!"); 259 Inst.addOperand(MCOperand::CreateReg(getReg())); 260 } 261 262 void addExpr(MCInst &Inst, const MCExpr *Expr) const{ 263 // Add as immediate when possible. Null MCExpr = 0. 264 if (Expr == 0) 265 Inst.addOperand(MCOperand::CreateImm(0)); 266 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 267 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 268 else 269 Inst.addOperand(MCOperand::CreateExpr(Expr)); 270 } 271 272 void addImmOperands(MCInst &Inst, unsigned N) const { 273 assert(N == 1 && "Invalid number of operands!"); 274 const MCExpr *Expr = getImm(); 275 addExpr(Inst, Expr); 276 } 277 278 void addMemOperands(MCInst &Inst, unsigned N) const { 279 assert(N == 2 && "Invalid number of operands!"); 280 281 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 282 283 const MCExpr *Expr = getMemOff(); 284 addExpr(Inst, Expr); 285 } 286 287 bool isReg() const { return Kind == k_Register; } 288 bool isImm() const { return Kind == k_Immediate; } 289 bool isToken() const { return Kind == k_Token; } 290 bool isMem() const { return Kind == k_Memory; } 291 292 StringRef getToken() const { 293 assert(Kind == k_Token && "Invalid access!"); 294 return StringRef(Tok.Data, Tok.Length); 295 } 296 297 unsigned getReg() const { 298 assert((Kind == k_Register) && "Invalid access!"); 299 return Reg.RegNum; 300 } 301 302 void setRegKind(RegisterKind RegKind) { 303 assert((Kind == k_Register) && "Invalid access!"); 304 Reg.Kind = RegKind; 305 } 306 307 const MCExpr *getImm() const { 308 assert((Kind == k_Immediate) && "Invalid access!"); 309 return Imm.Val; 310 } 311 312 unsigned getMemBase() const { 313 assert((Kind == k_Memory) && "Invalid access!"); 314 return Mem.Base; 315 } 316 317 const MCExpr *getMemOff() const { 318 assert((Kind == k_Memory) && "Invalid access!"); 319 return Mem.Off; 320 } 321 322 static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 323 MipsOperand *Op = new MipsOperand(k_Token); 324 Op->Tok.Data = Str.data(); 325 Op->Tok.Length = Str.size(); 326 Op->StartLoc = S; 327 Op->EndLoc = S; 328 return Op; 329 } 330 331 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 332 MipsOperand *Op = new MipsOperand(k_Register); 333 Op->Reg.RegNum = RegNum; 334 Op->StartLoc = S; 335 Op->EndLoc = E; 336 return Op; 337 } 338 339 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 340 MipsOperand *Op = new MipsOperand(k_Immediate); 341 Op->Imm.Val = Val; 342 Op->StartLoc = S; 343 Op->EndLoc = E; 344 return Op; 345 } 346 347 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, 348 SMLoc S, SMLoc E) { 349 MipsOperand *Op = new MipsOperand(k_Memory); 350 Op->Mem.Base = Base; 351 Op->Mem.Off = Off; 352 Op->StartLoc = S; 353 Op->EndLoc = E; 354 return Op; 355 } 356 357 bool isCPURegsAsm() const { 358 return Kind == k_Register && Reg.Kind == Kind_CPURegs; 359 } 360 void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const { 361 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 362 } 363 364 bool isCPU64RegsAsm() const { 365 return Kind == k_Register && Reg.Kind == Kind_CPU64Regs; 366 } 367 void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const { 368 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 369 } 370 371 bool isHWRegsAsm() const { 372 assert((Kind == k_Register) && "Invalid access!"); 373 return Reg.Kind == Kind_HWRegs; 374 } 375 void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const { 376 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 377 } 378 379 bool isHW64RegsAsm() const { 380 assert((Kind == k_Register) && "Invalid access!"); 381 return Reg.Kind == Kind_HW64Regs; 382 } 383 void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const { 384 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 385 } 386 387 void addCCRAsmOperands(MCInst &Inst, unsigned N) const { 388 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 389 } 390 391 bool isCCRAsm() const { 392 assert((Kind == k_Register) && "Invalid access!"); 393 return Reg.Kind == Kind_CCRRegs; 394 } 395 396 /// getStartLoc - Get the location of the first token of this operand. 397 SMLoc getStartLoc() const { 398 return StartLoc; 399 } 400 /// getEndLoc - Get the location of the last token of this operand. 401 SMLoc getEndLoc() const { 402 return EndLoc; 403 } 404 405 virtual void print(raw_ostream &OS) const { 406 llvm_unreachable("unimplemented!"); 407 } 408}; // class MipsOperand 409} // namespace 410 411namespace llvm { 412extern const MCInstrDesc MipsInsts[]; 413} 414static const MCInstrDesc &getInstDesc(unsigned Opcode) { 415 return MipsInsts[Opcode]; 416} 417 418bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 419 SmallVectorImpl<MCInst> &Instructions) { 420 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 421 Inst.setLoc(IDLoc); 422 if (MCID.hasDelaySlot() && Options.isReorder()) { 423 // If this instruction has a delay slot and .set reorder is active, 424 // emit a NOP after it. 425 Instructions.push_back(Inst); 426 MCInst NopInst; 427 NopInst.setOpcode(Mips::SLL); 428 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 429 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 430 NopInst.addOperand(MCOperand::CreateImm(0)); 431 Instructions.push_back(NopInst); 432 return false; 433 } 434 435 if (MCID.mayLoad() || MCID.mayStore()) { 436 // Check the offset of memory operand, if it is a symbol 437 // reference or immediate we may have to expand instructions. 438 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 439 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 440 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) 441 || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 442 MCOperand &Op = Inst.getOperand(i); 443 if (Op.isImm()) { 444 int MemOffset = Op.getImm(); 445 if (MemOffset < -32768 || MemOffset > 32767) { 446 // Offset can't exceed 16bit value. 447 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 448 return false; 449 } 450 } else if (Op.isExpr()) { 451 const MCExpr *Expr = Op.getExpr(); 452 if (Expr->getKind() == MCExpr::SymbolRef) { 453 const MCSymbolRefExpr *SR = 454 static_cast<const MCSymbolRefExpr*>(Expr); 455 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 456 // Expand symbol. 457 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 458 return false; 459 } 460 } else if (!isEvaluated(Expr)) { 461 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 462 return false; 463 } 464 } 465 } 466 } // for 467 } // if load/store 468 469 if (needsExpansion(Inst)) 470 expandInstruction(Inst, IDLoc, Instructions); 471 else 472 Instructions.push_back(Inst); 473 474 return false; 475} 476 477bool MipsAsmParser::needsExpansion(MCInst &Inst) { 478 479 switch (Inst.getOpcode()) { 480 case Mips::LoadImm32Reg: 481 case Mips::LoadAddr32Imm: 482 case Mips::LoadAddr32Reg: 483 return true; 484 default: 485 return false; 486 } 487} 488 489void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 490 SmallVectorImpl<MCInst> &Instructions) { 491 switch (Inst.getOpcode()) { 492 case Mips::LoadImm32Reg: 493 return expandLoadImm(Inst, IDLoc, Instructions); 494 case Mips::LoadAddr32Imm: 495 return expandLoadAddressImm(Inst, IDLoc, Instructions); 496 case Mips::LoadAddr32Reg: 497 return expandLoadAddressReg(Inst, IDLoc, Instructions); 498 } 499} 500 501void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 502 SmallVectorImpl<MCInst> &Instructions) { 503 MCInst tmpInst; 504 const MCOperand &ImmOp = Inst.getOperand(1); 505 assert(ImmOp.isImm() && "expected immediate operand kind"); 506 const MCOperand &RegOp = Inst.getOperand(0); 507 assert(RegOp.isReg() && "expected register operand kind"); 508 509 int ImmValue = ImmOp.getImm(); 510 tmpInst.setLoc(IDLoc); 511 if (0 <= ImmValue && ImmValue <= 65535) { 512 // For 0 <= j <= 65535. 513 // li d,j => ori d,$zero,j 514 tmpInst.setOpcode(Mips::ORi); 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 if (ImmValue < 0 && ImmValue >= -32768) { 520 // For -32768 <= j < 0. 521 // li d,j => addiu d,$zero,j 522 tmpInst.setOpcode(Mips::ADDiu); 523 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 524 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 525 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 526 Instructions.push_back(tmpInst); 527 } else { 528 // For any other value of j that is representable as a 32-bit integer. 529 // li d,j => lui d,hi16(j) 530 // ori d,d,lo16(j) 531 tmpInst.setOpcode(Mips::LUi); 532 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 533 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 534 Instructions.push_back(tmpInst); 535 tmpInst.clear(); 536 tmpInst.setOpcode(Mips::ORi); 537 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 538 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 539 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 540 tmpInst.setLoc(IDLoc); 541 Instructions.push_back(tmpInst); 542 } 543} 544 545void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 546 SmallVectorImpl<MCInst> &Instructions) { 547 MCInst tmpInst; 548 const MCOperand &ImmOp = Inst.getOperand(2); 549 assert(ImmOp.isImm() && "expected immediate operand kind"); 550 const MCOperand &SrcRegOp = Inst.getOperand(1); 551 assert(SrcRegOp.isReg() && "expected register operand kind"); 552 const MCOperand &DstRegOp = Inst.getOperand(0); 553 assert(DstRegOp.isReg() && "expected register operand kind"); 554 int ImmValue = ImmOp.getImm(); 555 if (-32768 <= ImmValue && ImmValue <= 65535) { 556 // For -32768 <= j <= 65535. 557 // la d,j(s) => addiu d,s,j 558 tmpInst.setOpcode(Mips::ADDiu); 559 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 560 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 561 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 562 Instructions.push_back(tmpInst); 563 } else { 564 // For any other value of j that is representable as a 32-bit integer. 565 // la d,j(s) => lui d,hi16(j) 566 // ori d,d,lo16(j) 567 // addu d,d,s 568 tmpInst.setOpcode(Mips::LUi); 569 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 570 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 571 Instructions.push_back(tmpInst); 572 tmpInst.clear(); 573 tmpInst.setOpcode(Mips::ORi); 574 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 575 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 576 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 577 Instructions.push_back(tmpInst); 578 tmpInst.clear(); 579 tmpInst.setOpcode(Mips::ADDu); 580 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 581 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 582 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 583 Instructions.push_back(tmpInst); 584 } 585} 586 587void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 588 SmallVectorImpl<MCInst> &Instructions) { 589 MCInst tmpInst; 590 const MCOperand &ImmOp = Inst.getOperand(1); 591 assert(ImmOp.isImm() && "expected immediate operand kind"); 592 const MCOperand &RegOp = Inst.getOperand(0); 593 assert(RegOp.isReg() && "expected register operand kind"); 594 int ImmValue = ImmOp.getImm(); 595 if (-32768 <= ImmValue && ImmValue <= 65535) { 596 // For -32768 <= j <= 65535. 597 // la d,j => addiu d,$zero,j 598 tmpInst.setOpcode(Mips::ADDiu); 599 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 600 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 601 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 602 Instructions.push_back(tmpInst); 603 } else { 604 // For any other value of j that is representable as a 32-bit integer. 605 // la d,j => lui d,hi16(j) 606 // ori d,d,lo16(j) 607 tmpInst.setOpcode(Mips::LUi); 608 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 609 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 610 Instructions.push_back(tmpInst); 611 tmpInst.clear(); 612 tmpInst.setOpcode(Mips::ORi); 613 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 614 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 615 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 616 Instructions.push_back(tmpInst); 617 } 618} 619 620void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 621 SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) { 622 const MCSymbolRefExpr *SR; 623 MCInst TempInst; 624 unsigned ImmOffset, HiOffset, LoOffset; 625 const MCExpr *ExprOffset; 626 unsigned TmpRegNum; 627 unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID 628 : Mips::CPURegsRegClassID, getATReg()); 629 // 1st operand is either the source or destination register. 630 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 631 unsigned RegOpNum = Inst.getOperand(0).getReg(); 632 // 2nd operand is the base register. 633 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 634 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 635 // 3rd operand is either an immediate or expression. 636 if (isImmOpnd) { 637 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 638 ImmOffset = Inst.getOperand(2).getImm(); 639 LoOffset = ImmOffset & 0x0000ffff; 640 HiOffset = (ImmOffset & 0xffff0000) >> 16; 641 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 642 if (LoOffset & 0x8000) 643 HiOffset++; 644 } else 645 ExprOffset = Inst.getOperand(2).getExpr(); 646 // All instructions will have the same location. 647 TempInst.setLoc(IDLoc); 648 // 1st instruction in expansion is LUi. For load instruction we can use 649 // the dst register as a temporary if base and dst are different, 650 // but for stores we must use $at. 651 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 652 TempInst.setOpcode(Mips::LUi); 653 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 654 if (isImmOpnd) 655 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 656 else { 657 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 658 SR = static_cast<const MCSymbolRefExpr*>(ExprOffset); 659 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 660 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 661 getContext()); 662 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 663 } else { 664 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 665 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 666 } 667 } 668 // Add the instruction to the list. 669 Instructions.push_back(TempInst); 670 // Prepare TempInst for next instruction. 671 TempInst.clear(); 672 // Add temp register to base. 673 TempInst.setOpcode(Mips::ADDu); 674 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 675 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 676 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 677 Instructions.push_back(TempInst); 678 TempInst.clear(); 679 // And finaly, create original instruction with low part 680 // of offset and new base. 681 TempInst.setOpcode(Inst.getOpcode()); 682 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 683 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 684 if (isImmOpnd) 685 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 686 else { 687 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 688 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 689 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 690 getContext()); 691 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 692 } else { 693 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 694 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 695 } 696 } 697 Instructions.push_back(TempInst); 698 TempInst.clear(); 699} 700 701bool MipsAsmParser:: 702MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 703 SmallVectorImpl<MCParsedAsmOperand*> &Operands, 704 MCStreamer &Out, unsigned &ErrorInfo, 705 bool MatchingInlineAsm) { 706 MCInst Inst; 707 SmallVector<MCInst, 8> Instructions; 708 unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo, 709 MatchingInlineAsm); 710 711 switch (MatchResult) { 712 default: 713 break; 714 case Match_Success: { 715 if (processInstruction(Inst, IDLoc, Instructions)) 716 return true; 717 for (unsigned i = 0; i < Instructions.size(); i++) 718 Out.EmitInstruction(Instructions[i]); 719 return false; 720 } 721 case Match_MissingFeature: 722 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 723 return true; 724 case Match_InvalidOperand: { 725 SMLoc ErrorLoc = IDLoc; 726 if (ErrorInfo != ~0U) { 727 if (ErrorInfo >= Operands.size()) 728 return Error(IDLoc, "too few operands for instruction"); 729 730 ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc(); 731 if (ErrorLoc == SMLoc()) 732 ErrorLoc = IDLoc; 733 } 734 735 return Error(ErrorLoc, "invalid operand for instruction"); 736 } 737 case Match_MnemonicFail: 738 return Error(IDLoc, "invalid instruction"); 739 } 740 return true; 741} 742 743int MipsAsmParser::matchCPURegisterName(StringRef Name) { 744 int CC; 745 746 if (Name == "at") 747 return getATReg(); 748 749 CC = StringSwitch<unsigned>(Name) 750 .Case("zero", 0) 751 .Case("a0", 4) 752 .Case("a1", 5) 753 .Case("a2", 6) 754 .Case("a3", 7) 755 .Case("v0", 2) 756 .Case("v1", 3) 757 .Case("s0", 16) 758 .Case("s1", 17) 759 .Case("s2", 18) 760 .Case("s3", 19) 761 .Case("s4", 20) 762 .Case("s5", 21) 763 .Case("s6", 22) 764 .Case("s7", 23) 765 .Case("k0", 26) 766 .Case("k1", 27) 767 .Case("sp", 29) 768 .Case("fp", 30) 769 .Case("gp", 28) 770 .Case("ra", 31) 771 .Case("t0", 8) 772 .Case("t1", 9) 773 .Case("t2", 10) 774 .Case("t3", 11) 775 .Case("t4", 12) 776 .Case("t5", 13) 777 .Case("t6", 14) 778 .Case("t7", 15) 779 .Case("t8", 24) 780 .Case("t9", 25) 781 .Default(-1); 782 783 // Although SGI documentation just cuts out t0-t3 for n32/n64, 784 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 785 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 786 if (isMips64() && 8 <= CC && CC <= 11) 787 CC += 4; 788 789 if (CC == -1 && isMips64()) 790 CC = StringSwitch<unsigned>(Name) 791 .Case("a4", 8) 792 .Case("a5", 9) 793 .Case("a6", 10) 794 .Case("a7", 11) 795 .Case("kt0", 26) 796 .Case("kt1", 27) 797 .Case("s8", 30) 798 .Default(-1); 799 800 return CC; 801} 802 803int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 804 805 if (Name.equals("fcc0")) 806 return Mips::FCC0; 807 808 int CC; 809 CC = matchCPURegisterName(Name); 810 if (CC != -1) 811 return matchRegisterByNumber(CC, is64BitReg ? Mips::CPU64RegsRegClassID 812 : Mips::CPURegsRegClassID); 813 814 if (Name[0] == 'f') { 815 StringRef NumString = Name.substr(1); 816 unsigned IntVal; 817 if (NumString.getAsInteger(10, IntVal)) 818 return -1; // This is not an integer. 819 if (IntVal > 31) 820 return -1; 821 822 FpFormatTy Format = getFpFormat(); 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 837 return -1; 838} 839 840void MipsAsmParser::setDefaultFpFormat() { 841 842 if (isMips64() || isFP64()) 843 FpFormat = FP_FORMAT_D; 844 else 845 FpFormat = FP_FORMAT_S; 846} 847 848bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){ 849 850 bool IsDouble = StringSwitch<bool>(Mnemonic.lower()) 851 .Case("ldxc1", true) 852 .Case("ldc1", true) 853 .Case("sdxc1", true) 854 .Case("sdc1", true) 855 .Default(false); 856 857 return IsDouble; 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::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1257 1258 if (!isMips64()) 1259 return MatchOperand_NoMatch; 1260 if (getLexer().getKind() == AsmToken::Identifier) { 1261 if (searchSymbolAlias(Operands, MipsOperand::Kind_CPU64Regs)) 1262 return MatchOperand_Success; 1263 return MatchOperand_NoMatch; 1264 } 1265 // If the first token is not '$', we have an error. 1266 if (Parser.getTok().isNot(AsmToken::Dollar)) 1267 return MatchOperand_NoMatch; 1268 1269 Parser.Lex(); // Eat $ 1270 if (!tryParseRegisterOperand(Operands, true)) { 1271 // Set the proper register kind. 1272 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1273 op->setRegKind(MipsOperand::Kind_CPU64Regs); 1274 return MatchOperand_Success; 1275 } 1276 return MatchOperand_NoMatch; 1277} 1278 1279bool MipsAsmParser::searchSymbolAlias( 1280 SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegisterKind) { 1281 1282 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1283 if (Sym) { 1284 SMLoc S = Parser.getTok().getLoc(); 1285 const MCExpr *Expr; 1286 if (Sym->isVariable()) 1287 Expr = Sym->getVariableValue(); 1288 else 1289 return false; 1290 if (Expr->getKind() == MCExpr::SymbolRef) { 1291 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr); 1292 const StringRef DefSymbol = Ref->getSymbol().getName(); 1293 if (DefSymbol.startswith("$")) { 1294 int RegNum = -1; 1295 APInt IntVal(32, -1); 1296 if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) 1297 RegNum = matchRegisterByNumber(IntVal.getZExtValue(), 1298 isMips64() 1299 ? Mips::CPU64RegsRegClassID 1300 : Mips::CPURegsRegClassID); 1301 else 1302 // Lookup for the register with corresponding name 1303 RegNum = matchRegisterName(DefSymbol.substr(1), isMips64()); 1304 if (RegNum > -1) { 1305 Parser.Lex(); 1306 MipsOperand *op = MipsOperand::CreateReg(RegNum, S, 1307 Parser.getTok().getLoc()); 1308 op->setRegKind((MipsOperand::RegisterKind) RegisterKind); 1309 Operands.push_back(op); 1310 return true; 1311 } 1312 } 1313 } else if (Expr->getKind() == MCExpr::Constant) { 1314 Parser.Lex(); 1315 const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr); 1316 MipsOperand *op = MipsOperand::CreateImm(Const, S, 1317 Parser.getTok().getLoc()); 1318 Operands.push_back(op); 1319 return true; 1320 } 1321 } 1322 return false; 1323} 1324 1325MipsAsmParser::OperandMatchResultTy 1326MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1327 1328 if (getLexer().getKind() == AsmToken::Identifier) { 1329 if (searchSymbolAlias(Operands, MipsOperand::Kind_CPURegs)) 1330 return MatchOperand_Success; 1331 return MatchOperand_NoMatch; 1332 } 1333 // If the first token is not '$' we have an error. 1334 if (Parser.getTok().isNot(AsmToken::Dollar)) 1335 return MatchOperand_NoMatch; 1336 1337 Parser.Lex(); // Eat $ 1338 if (!tryParseRegisterOperand(Operands, false)) { 1339 // Set the proper register kind. 1340 MipsOperand* op = static_cast<MipsOperand*>(Operands.back()); 1341 op->setRegKind(MipsOperand::Kind_CPURegs); 1342 return MatchOperand_Success; 1343 } 1344 return MatchOperand_NoMatch; 1345} 1346 1347MipsAsmParser::OperandMatchResultTy 1348MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1349 1350 if (isMips64()) 1351 return MatchOperand_NoMatch; 1352 1353 // If the first token is not '$' we have error. 1354 if (Parser.getTok().isNot(AsmToken::Dollar)) 1355 return MatchOperand_NoMatch; 1356 SMLoc S = Parser.getTok().getLoc(); 1357 Parser.Lex(); // Eat the '$'. 1358 1359 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1360 if (Tok.isNot(AsmToken::Integer)) 1361 return MatchOperand_NoMatch; 1362 1363 unsigned RegNum = Tok.getIntVal(); 1364 // At the moment only hwreg29 is supported. 1365 if (RegNum != 29) 1366 return MatchOperand_ParseFail; 1367 1368 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S, 1369 Parser.getTok().getLoc()); 1370 op->setRegKind(MipsOperand::Kind_HWRegs); 1371 Operands.push_back(op); 1372 1373 Parser.Lex(); // Eat the register number. 1374 return MatchOperand_Success; 1375} 1376 1377MipsAsmParser::OperandMatchResultTy 1378MipsAsmParser::parseHW64Regs( 1379 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1380 1381 if (!isMips64()) 1382 return MatchOperand_NoMatch; 1383 // If the first token is not '$' we have an error. 1384 if (Parser.getTok().isNot(AsmToken::Dollar)) 1385 return MatchOperand_NoMatch; 1386 SMLoc S = Parser.getTok().getLoc(); 1387 Parser.Lex(); // Eat $ 1388 1389 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1390 if (Tok.isNot(AsmToken::Integer)) 1391 return MatchOperand_NoMatch; 1392 1393 unsigned RegNum = Tok.getIntVal(); 1394 // At the moment only hwreg29 is supported. 1395 if (RegNum != 29) 1396 return MatchOperand_ParseFail; 1397 1398 MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S, 1399 Parser.getTok().getLoc()); 1400 op->setRegKind(MipsOperand::Kind_HW64Regs); 1401 Operands.push_back(op); 1402 1403 Parser.Lex(); // Eat the register number. 1404 return MatchOperand_Success; 1405} 1406 1407MipsAsmParser::OperandMatchResultTy 1408MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1409 unsigned RegNum; 1410 // If the first token is not '$' we have an error. 1411 if (Parser.getTok().isNot(AsmToken::Dollar)) 1412 return MatchOperand_NoMatch; 1413 SMLoc S = Parser.getTok().getLoc(); 1414 Parser.Lex(); // Eat the '$' 1415 1416 const AsmToken &Tok = Parser.getTok(); // Get next token. 1417 if (Tok.is(AsmToken::Integer)) { 1418 RegNum = Tok.getIntVal(); 1419 // At the moment only fcc0 is supported. 1420 if (RegNum != 0) 1421 return MatchOperand_ParseFail; 1422 } else if (Tok.is(AsmToken::Identifier)) { 1423 // At the moment only fcc0 is supported. 1424 if (Tok.getIdentifier() != "fcc0") 1425 return MatchOperand_ParseFail; 1426 } else 1427 return MatchOperand_NoMatch; 1428 1429 MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S, 1430 Parser.getTok().getLoc()); 1431 op->setRegKind(MipsOperand::Kind_CCRRegs); 1432 Operands.push_back(op); 1433 1434 Parser.Lex(); // Eat the register number. 1435 return MatchOperand_Success; 1436} 1437 1438MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 1439 1440 MCSymbolRefExpr::VariantKind VK 1441 = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 1442 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 1443 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 1444 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 1445 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 1446 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 1447 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 1448 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 1449 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 1450 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 1451 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 1452 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 1453 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 1454 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 1455 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 1456 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 1457 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 1458 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 1459 .Default(MCSymbolRefExpr::VK_None); 1460 1461 return VK; 1462} 1463// Converts condition string to immediate operand value. 1464static int ConvertCcString(StringRef CondString) { 1465 int CC = StringSwitch<unsigned>(CondString) 1466 .Case(".f", 0) 1467 .Case(".un", 1) 1468 .Case(".eq", 2) 1469 .Case(".ueq", 3) 1470 .Case(".olt", 4) 1471 .Case(".ult", 5) 1472 .Case(".ole", 6) 1473 .Case(".ule", 7) 1474 .Case(".sf", 8) 1475 .Case(".ngle", 9) 1476 .Case(".seq", 10) 1477 .Case(".ngl", 11) 1478 .Case(".lt", 12) 1479 .Case(".nge", 13) 1480 .Case(".le", 14) 1481 .Case(".ngt", 15) 1482 .Default(-1); 1483 1484 return CC; 1485} 1486 1487bool MipsAsmParser:: 1488parseMathOperation(StringRef Name, SMLoc NameLoc, 1489 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1490 // Split the format. 1491 size_t Start = Name.find('.'), Next = Name.rfind('.'); 1492 StringRef Format1 = Name.slice(Start, Next); 1493 // Add the first format to the operands. 1494 Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc)); 1495 // Now for the second format. 1496 StringRef Format2 = Name.slice(Next, StringRef::npos); 1497 Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc)); 1498 1499 // Set the format for the first register. 1500 setFpFormat(Format1); 1501 1502 // Read the remaining operands. 1503 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1504 // Read the first operand. 1505 if (ParseOperand(Operands, Name)) { 1506 SMLoc Loc = getLexer().getLoc(); 1507 Parser.eatToEndOfStatement(); 1508 return Error(Loc, "unexpected token in argument list"); 1509 } 1510 1511 if (getLexer().isNot(AsmToken::Comma)) { 1512 SMLoc Loc = getLexer().getLoc(); 1513 Parser.eatToEndOfStatement(); 1514 return Error(Loc, "unexpected token in argument list"); 1515 } 1516 Parser.Lex(); // Eat the comma. 1517 1518 // Set the format for the first register 1519 setFpFormat(Format2); 1520 1521 // Parse and remember the operand. 1522 if (ParseOperand(Operands, Name)) { 1523 SMLoc Loc = getLexer().getLoc(); 1524 Parser.eatToEndOfStatement(); 1525 return Error(Loc, "unexpected token in argument list"); 1526 } 1527 } 1528 1529 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1530 SMLoc Loc = getLexer().getLoc(); 1531 Parser.eatToEndOfStatement(); 1532 return Error(Loc, "unexpected token in argument list"); 1533 } 1534 1535 Parser.Lex(); // Consume the EndOfStatement. 1536 return false; 1537} 1538 1539bool MipsAsmParser:: 1540ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 1541 SmallVectorImpl<MCParsedAsmOperand*> &Operands) { 1542 StringRef Mnemonic; 1543 // Floating point instructions: Should the register be treated as a double? 1544 if (requestsDoubleOperand(Name)) { 1545 setFpFormat(FP_FORMAT_D); 1546 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 1547 Mnemonic = Name; 1548 } else { 1549 setDefaultFpFormat(); 1550 // Create the leading tokens for the mnemonic, split by '.' characters. 1551 size_t Start = 0, Next = Name.find('.'); 1552 Mnemonic = Name.slice(Start, Next); 1553 1554 Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc)); 1555 1556 if (Next != StringRef::npos) { 1557 // There is a format token in mnemonic. 1558 size_t Dot = Name.find('.', Next + 1); 1559 StringRef Format = Name.slice(Next, Dot); 1560 if (Dot == StringRef::npos) // Only one '.' in a string, it's a format. 1561 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1562 else { 1563 if (Name.startswith("c.")) { 1564 // Floating point compare, add '.' and immediate represent for cc. 1565 Operands.push_back(MipsOperand::CreateToken(".", NameLoc)); 1566 int Cc = ConvertCcString(Format); 1567 if (Cc == -1) { 1568 return Error(NameLoc, "Invalid conditional code"); 1569 } 1570 SMLoc E = SMLoc::getFromPointer( 1571 Parser.getTok().getLoc().getPointer() - 1); 1572 Operands.push_back( 1573 MipsOperand::CreateImm(MCConstantExpr::Create(Cc, getContext()), 1574 NameLoc, E)); 1575 } else { 1576 // trunc, ceil, floor ... 1577 return parseMathOperation(Name, NameLoc, Operands); 1578 } 1579 1580 // The rest is a format. 1581 Format = Name.slice(Dot, StringRef::npos); 1582 Operands.push_back(MipsOperand::CreateToken(Format, NameLoc)); 1583 } 1584 1585 setFpFormat(Format); 1586 } 1587 } 1588 1589 // Read the remaining operands. 1590 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1591 // Read the first operand. 1592 if (ParseOperand(Operands, Mnemonic)) { 1593 SMLoc Loc = getLexer().getLoc(); 1594 Parser.eatToEndOfStatement(); 1595 return Error(Loc, "unexpected token in argument list"); 1596 } 1597 1598 while (getLexer().is(AsmToken::Comma)) { 1599 Parser.Lex(); // Eat the comma. 1600 1601 // Parse and remember the operand. 1602 if (ParseOperand(Operands, Name)) { 1603 SMLoc Loc = getLexer().getLoc(); 1604 Parser.eatToEndOfStatement(); 1605 return Error(Loc, "unexpected token in argument list"); 1606 } 1607 } 1608 } 1609 1610 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1611 SMLoc Loc = getLexer().getLoc(); 1612 Parser.eatToEndOfStatement(); 1613 return Error(Loc, "unexpected token in argument list"); 1614 } 1615 1616 Parser.Lex(); // Consume the EndOfStatement. 1617 return false; 1618} 1619 1620bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 1621 SMLoc Loc = getLexer().getLoc(); 1622 Parser.eatToEndOfStatement(); 1623 return Error(Loc, ErrorMsg); 1624} 1625 1626bool MipsAsmParser::parseSetNoAtDirective() { 1627 // Line should look like: ".set noat". 1628 // set at reg to 0. 1629 Options.setATReg(0); 1630 // eat noat 1631 Parser.Lex(); 1632 // If this is not the end of the statement, report an error. 1633 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1634 reportParseError("unexpected token in statement"); 1635 return false; 1636 } 1637 Parser.Lex(); // Consume the EndOfStatement. 1638 return false; 1639} 1640 1641bool MipsAsmParser::parseSetAtDirective() { 1642 // Line can be .set at - defaults to $1 1643 // or .set at=$reg 1644 int AtRegNo; 1645 getParser().Lex(); 1646 if (getLexer().is(AsmToken::EndOfStatement)) { 1647 Options.setATReg(1); 1648 Parser.Lex(); // Consume the EndOfStatement. 1649 return false; 1650 } else if (getLexer().is(AsmToken::Equal)) { 1651 getParser().Lex(); // Eat the '='. 1652 if (getLexer().isNot(AsmToken::Dollar)) { 1653 reportParseError("unexpected token in statement"); 1654 return false; 1655 } 1656 Parser.Lex(); // Eat the '$'. 1657 const AsmToken &Reg = Parser.getTok(); 1658 if (Reg.is(AsmToken::Identifier)) { 1659 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 1660 } else if (Reg.is(AsmToken::Integer)) { 1661 AtRegNo = Reg.getIntVal(); 1662 } else { 1663 reportParseError("unexpected token in statement"); 1664 return false; 1665 } 1666 1667 if (AtRegNo < 1 || AtRegNo > 31) { 1668 reportParseError("unexpected token in statement"); 1669 return false; 1670 } 1671 1672 if (!Options.setATReg(AtRegNo)) { 1673 reportParseError("unexpected token in statement"); 1674 return false; 1675 } 1676 getParser().Lex(); // Eat the register. 1677 1678 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1679 reportParseError("unexpected token in statement"); 1680 return false; 1681 } 1682 Parser.Lex(); // Consume the EndOfStatement. 1683 return false; 1684 } else { 1685 reportParseError("unexpected token in statement"); 1686 return false; 1687 } 1688} 1689 1690bool MipsAsmParser::parseSetReorderDirective() { 1691 Parser.Lex(); 1692 // If this is not the end of the statement, report an error. 1693 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1694 reportParseError("unexpected token in statement"); 1695 return false; 1696 } 1697 Options.setReorder(); 1698 Parser.Lex(); // Consume the EndOfStatement. 1699 return false; 1700} 1701 1702bool MipsAsmParser::parseSetNoReorderDirective() { 1703 Parser.Lex(); 1704 // If this is not the end of the statement, report an error. 1705 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1706 reportParseError("unexpected token in statement"); 1707 return false; 1708 } 1709 Options.setNoreorder(); 1710 Parser.Lex(); // Consume the EndOfStatement. 1711 return false; 1712} 1713 1714bool MipsAsmParser::parseSetMacroDirective() { 1715 Parser.Lex(); 1716 // If this is not the end of the statement, report an error. 1717 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1718 reportParseError("unexpected token in statement"); 1719 return false; 1720 } 1721 Options.setMacro(); 1722 Parser.Lex(); // Consume the EndOfStatement. 1723 return false; 1724} 1725 1726bool MipsAsmParser::parseSetNoMacroDirective() { 1727 Parser.Lex(); 1728 // If this is not the end of the statement, report an error. 1729 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1730 reportParseError("`noreorder' must be set before `nomacro'"); 1731 return false; 1732 } 1733 if (Options.isReorder()) { 1734 reportParseError("`noreorder' must be set before `nomacro'"); 1735 return false; 1736 } 1737 Options.setNomacro(); 1738 Parser.Lex(); // Consume the EndOfStatement. 1739 return false; 1740} 1741 1742bool MipsAsmParser::parseSetAssignment() { 1743 StringRef Name; 1744 const MCExpr *Value; 1745 1746 if (Parser.parseIdentifier(Name)) 1747 reportParseError("expected identifier after .set"); 1748 1749 if (getLexer().isNot(AsmToken::Comma)) 1750 return reportParseError("unexpected token in .set directive"); 1751 Lex(); // Eat comma 1752 1753 if (getLexer().is(AsmToken::Dollar)) { 1754 MCSymbol *Symbol; 1755 SMLoc DollarLoc = getLexer().getLoc(); 1756 // Consume the dollar sign, and check for a following identifier. 1757 Parser.Lex(); 1758 // We have a '$' followed by something, make sure they are adjacent. 1759 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 1760 return true; 1761 StringRef Res = StringRef(DollarLoc.getPointer(), 1762 getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); 1763 Symbol = getContext().GetOrCreateSymbol(Res); 1764 Parser.Lex(); 1765 Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, 1766 getContext()); 1767 } else if (Parser.parseExpression(Value)) 1768 return reportParseError("expected valid expression after comma"); 1769 1770 // Check if the Name already exists as a symbol. 1771 MCSymbol *Sym = getContext().LookupSymbol(Name); 1772 if (Sym) 1773 return reportParseError("symbol already defined"); 1774 Sym = getContext().GetOrCreateSymbol(Name); 1775 Sym->setVariableValue(Value); 1776 1777 return false; 1778} 1779 1780bool MipsAsmParser::parseDirectiveSet() { 1781 1782 // Get the next token. 1783 const AsmToken &Tok = Parser.getTok(); 1784 1785 if (Tok.getString() == "noat") { 1786 return parseSetNoAtDirective(); 1787 } else if (Tok.getString() == "at") { 1788 return parseSetAtDirective(); 1789 } else if (Tok.getString() == "reorder") { 1790 return parseSetReorderDirective(); 1791 } else if (Tok.getString() == "noreorder") { 1792 return parseSetNoReorderDirective(); 1793 } else if (Tok.getString() == "macro") { 1794 return parseSetMacroDirective(); 1795 } else if (Tok.getString() == "nomacro") { 1796 return parseSetNoMacroDirective(); 1797 } else if (Tok.getString() == "nomips16") { 1798 // Ignore this directive for now. 1799 Parser.eatToEndOfStatement(); 1800 return false; 1801 } else if (Tok.getString() == "nomicromips") { 1802 // Ignore this directive for now. 1803 Parser.eatToEndOfStatement(); 1804 return false; 1805 } else { 1806 // It is just an identifier, look for an assignment. 1807 parseSetAssignment(); 1808 return false; 1809 } 1810 1811 return true; 1812} 1813 1814/// parseDirectiveWord 1815/// ::= .word [ expression (, expression)* ] 1816bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 1817 if (getLexer().isNot(AsmToken::EndOfStatement)) { 1818 for (;;) { 1819 const MCExpr *Value; 1820 if (getParser().parseExpression(Value)) 1821 return true; 1822 1823 getParser().getStreamer().EmitValue(Value, Size); 1824 1825 if (getLexer().is(AsmToken::EndOfStatement)) 1826 break; 1827 1828 // FIXME: Improve diagnostic. 1829 if (getLexer().isNot(AsmToken::Comma)) 1830 return Error(L, "unexpected token in directive"); 1831 Parser.Lex(); 1832 } 1833 } 1834 1835 Parser.Lex(); 1836 return false; 1837} 1838 1839bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 1840 1841 StringRef IDVal = DirectiveID.getString(); 1842 1843 if (IDVal == ".ent") { 1844 // Ignore this directive for now. 1845 Parser.Lex(); 1846 return false; 1847 } 1848 1849 if (IDVal == ".end") { 1850 // Ignore this directive for now. 1851 Parser.Lex(); 1852 return false; 1853 } 1854 1855 if (IDVal == ".frame") { 1856 // Ignore this directive for now. 1857 Parser.eatToEndOfStatement(); 1858 return false; 1859 } 1860 1861 if (IDVal == ".set") { 1862 return parseDirectiveSet(); 1863 } 1864 1865 if (IDVal == ".fmask") { 1866 // Ignore this directive for now. 1867 Parser.eatToEndOfStatement(); 1868 return false; 1869 } 1870 1871 if (IDVal == ".mask") { 1872 // Ignore this directive for now. 1873 Parser.eatToEndOfStatement(); 1874 return false; 1875 } 1876 1877 if (IDVal == ".gpword") { 1878 // Ignore this directive for now. 1879 Parser.eatToEndOfStatement(); 1880 return false; 1881 } 1882 1883 if (IDVal == ".word") { 1884 parseDirectiveWord(4, DirectiveID.getLoc()); 1885 return false; 1886 } 1887 1888 return true; 1889} 1890 1891extern "C" void LLVMInitializeMipsAsmParser() { 1892 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 1893 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 1894 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 1895 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 1896} 1897 1898#define GET_REGISTER_MATCHER 1899#define GET_MATCHER_IMPLEMENTATION 1900#include "MipsGenAsmMatcher.inc" 1901