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