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