MipsAsmParser.cpp revision 2263a2ca72e21206d45a69532004a0b17881e733
1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===// 2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// The LLVM Compiler Infrastructure 4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source 6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// License. See LICENSE.TXT for details. 7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// 88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//===----------------------------------------------------------------------===// 9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "MCTargetDesc/MipsMCTargetDesc.h" 11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "MipsRegisterInfo.h" 12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "MipsTargetStreamer.h" 13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "llvm/ADT/StringSwitch.h" 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCContext.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCExpr.h" 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCInst.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCParser/MCAsmLexer.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCParser/MCParsedAsmOperand.h" 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCStreamer.h" 208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/MC/MCSubtargetInfo.h" 218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/MC/MCSymbol.h" 228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/MC/MCTargetAsmParser.h" 238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/Support/TargetRegistry.h" 248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/ADT/APInt.h" 258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using namespace llvm; 27 28namespace llvm { 29class MCInstrInfo; 30} 31 32namespace { 33class MipsAssemblerOptions { 34public: 35 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {} 36 37 unsigned getATRegNum() { return aTReg; } 38 bool setATReg(unsigned Reg); 39 40 bool isReorder() { return reorder; } 41 void setReorder() { reorder = true; } 42 void setNoreorder() { reorder = false; } 43 44 bool isMacro() { return macro; } 45 void setMacro() { macro = true; } 46 void setNomacro() { macro = false; } 47 48private: 49 unsigned aTReg; 50 bool reorder; 51 bool macro; 52}; 53} 54 55namespace { 56class MipsAsmParser : public MCTargetAsmParser { 57 58 MipsTargetStreamer &getTargetStreamer() { 59 MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer(); 60 return static_cast<MipsTargetStreamer &>(TS); 61 } 62 63 MCSubtargetInfo &STI; 64 MCAsmParser &Parser; 65 MipsAssemblerOptions Options; 66 bool hasConsumedDollar; 67 68#define GET_ASSEMBLER_HEADER 69#include "MipsGenAsmMatcher.inc" 70 71 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode, 72 SmallVectorImpl<MCParsedAsmOperand *> &Operands, 73 MCStreamer &Out, unsigned &ErrorInfo, 74 bool MatchingInlineAsm); 75 76 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc); 77 78 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, 79 SMLoc NameLoc, 80 SmallVectorImpl<MCParsedAsmOperand *> &Operands); 81 82 bool ParseDirective(AsmToken DirectiveID); 83 84 MipsAsmParser::OperandMatchResultTy 85 parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind); 86 87 MipsAsmParser::OperandMatchResultTy 88 parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind); 89 90 MipsAsmParser::OperandMatchResultTy 91 parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 92 int RegKind); 93 94 MipsAsmParser::OperandMatchResultTy 95 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 96 97 bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 98 int RegKind); 99 100 MipsAsmParser::OperandMatchResultTy 101 parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 102 103 MipsAsmParser::OperandMatchResultTy 104 parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 105 106 MipsAsmParser::OperandMatchResultTy 107 parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 108 109 MipsAsmParser::OperandMatchResultTy 110 parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 111 112 MipsAsmParser::OperandMatchResultTy 113 parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 114 115 MipsAsmParser::OperandMatchResultTy 116 parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 117 118 MipsAsmParser::OperandMatchResultTy 119 parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 120 121 MipsAsmParser::OperandMatchResultTy 122 parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 123 124 MipsAsmParser::OperandMatchResultTy 125 parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 126 127 MipsAsmParser::OperandMatchResultTy 128 parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 129 130 MipsAsmParser::OperandMatchResultTy 131 parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 132 133 MipsAsmParser::OperandMatchResultTy 134 parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 135 136 MipsAsmParser::OperandMatchResultTy 137 parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 138 139 MipsAsmParser::OperandMatchResultTy 140 parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 141 142 MipsAsmParser::OperandMatchResultTy 143 parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 144 145 MipsAsmParser::OperandMatchResultTy 146 parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 147 148 MipsAsmParser::OperandMatchResultTy 149 parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 150 151 MipsAsmParser::OperandMatchResultTy 152 parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 153 154 MipsAsmParser::OperandMatchResultTy 155 parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 156 157 MipsAsmParser::OperandMatchResultTy 158 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands); 159 160 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 161 unsigned RegKind); 162 163 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &, 164 StringRef Mnemonic); 165 166 int tryParseRegister(bool is64BitReg); 167 168 bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 169 bool is64BitReg); 170 171 bool needsExpansion(MCInst &Inst); 172 173 void expandInstruction(MCInst &Inst, SMLoc IDLoc, 174 SmallVectorImpl<MCInst> &Instructions); 175 void expandLoadImm(MCInst &Inst, SMLoc IDLoc, 176 SmallVectorImpl<MCInst> &Instructions); 177 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 178 SmallVectorImpl<MCInst> &Instructions); 179 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 180 SmallVectorImpl<MCInst> &Instructions); 181 void expandMemInst(MCInst &Inst, SMLoc IDLoc, 182 SmallVectorImpl<MCInst> &Instructions, bool isLoad, 183 bool isImmOpnd); 184 bool reportParseError(StringRef ErrorMsg); 185 186 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr); 187 bool parseRelocOperand(const MCExpr *&Res); 188 189 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr); 190 191 bool isEvaluated(const MCExpr *Expr); 192 bool parseDirectiveSet(); 193 bool parseDirectiveMipsHackStocg(); 194 bool parseDirectiveMipsHackELFFlags(); 195 196 bool parseSetAtDirective(); 197 bool parseSetNoAtDirective(); 198 bool parseSetMacroDirective(); 199 bool parseSetNoMacroDirective(); 200 bool parseSetReorderDirective(); 201 bool parseSetNoReorderDirective(); 202 203 bool parseSetAssignment(); 204 205 bool parseDirectiveWord(unsigned Size, SMLoc L); 206 bool parseDirectiveGpWord(); 207 208 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol); 209 210 bool isMips64() const { 211 return (STI.getFeatureBits() & Mips::FeatureMips64) != 0; 212 } 213 214 bool isFP64() const { 215 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0; 216 } 217 218 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; } 219 220 int matchRegisterName(StringRef Symbol, bool is64BitReg); 221 222 int matchCPURegisterName(StringRef Symbol); 223 224 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass); 225 226 int matchFPURegisterName(StringRef Name); 227 228 int matchFCCRegisterName(StringRef Name); 229 230 int matchACRegisterName(StringRef Name); 231 232 int matchMSA128RegisterName(StringRef Name); 233 234 int matchMSA128CtrlRegisterName(StringRef Name); 235 236 int regKindToRegClass(int RegKind); 237 238 unsigned getReg(int RC, int RegNo); 239 240 int getATReg(); 241 242 bool processInstruction(MCInst &Inst, SMLoc IDLoc, 243 SmallVectorImpl<MCInst> &Instructions); 244 245 // Helper function that checks if the value of a vector index is within the 246 // boundaries of accepted values for each RegisterKind 247 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0 248 bool validateMSAIndex(int Val, int RegKind); 249 250public: 251 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser, 252 const MCInstrInfo &MII) 253 : MCTargetAsmParser(), STI(sti), Parser(parser), 254 hasConsumedDollar(false) { 255 // Initialize the set of available features. 256 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits())); 257 } 258 259 MCAsmParser &getParser() const { return Parser; } 260 MCAsmLexer &getLexer() const { return Parser.getLexer(); } 261}; 262} 263 264namespace { 265 266/// MipsOperand - Instances of this class represent a parsed Mips machine 267/// instruction. 268class MipsOperand : public MCParsedAsmOperand { 269 270public: 271 enum RegisterKind { 272 Kind_None, 273 Kind_GPR32, 274 Kind_GPR64, 275 Kind_HWRegs, 276 Kind_FGR32Regs, 277 Kind_FGRH32Regs, 278 Kind_FGR64Regs, 279 Kind_AFGR64Regs, 280 Kind_CCRRegs, 281 Kind_FCCRegs, 282 Kind_ACC64DSP, 283 Kind_LO32DSP, 284 Kind_HI32DSP, 285 Kind_COP2, 286 Kind_MSA128BRegs, 287 Kind_MSA128HRegs, 288 Kind_MSA128WRegs, 289 Kind_MSA128DRegs, 290 Kind_MSA128CtrlRegs 291 }; 292 293private: 294 enum KindTy { 295 k_CondCode, 296 k_CoprocNum, 297 k_Immediate, 298 k_Memory, 299 k_PostIndexRegister, 300 k_Register, 301 k_PtrReg, 302 k_Token 303 } Kind; 304 305 MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {} 306 307 struct Token { 308 const char *Data; 309 unsigned Length; 310 }; 311 312 struct RegOp { 313 unsigned RegNum; 314 RegisterKind Kind; 315 }; 316 317 struct ImmOp { 318 const MCExpr *Val; 319 }; 320 321 struct MemOp { 322 unsigned Base; 323 const MCExpr *Off; 324 }; 325 326 union { 327 struct Token Tok; 328 struct RegOp Reg; 329 struct ImmOp Imm; 330 struct MemOp Mem; 331 }; 332 333 SMLoc StartLoc, EndLoc; 334 335public: 336 void addRegOperands(MCInst &Inst, unsigned N) const { 337 assert(N == 1 && "Invalid number of operands!"); 338 Inst.addOperand(MCOperand::CreateReg(getReg())); 339 } 340 341 void addPtrRegOperands(MCInst &Inst, unsigned N) const { 342 assert(N == 1 && "Invalid number of operands!"); 343 Inst.addOperand(MCOperand::CreateReg(getPtrReg())); 344 } 345 346 void addExpr(MCInst &Inst, const MCExpr *Expr) const { 347 // Add as immediate when possible. Null MCExpr = 0. 348 if (Expr == 0) 349 Inst.addOperand(MCOperand::CreateImm(0)); 350 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr)) 351 Inst.addOperand(MCOperand::CreateImm(CE->getValue())); 352 else 353 Inst.addOperand(MCOperand::CreateExpr(Expr)); 354 } 355 356 void addImmOperands(MCInst &Inst, unsigned N) const { 357 assert(N == 1 && "Invalid number of operands!"); 358 const MCExpr *Expr = getImm(); 359 addExpr(Inst, Expr); 360 } 361 362 void addMemOperands(MCInst &Inst, unsigned N) const { 363 assert(N == 2 && "Invalid number of operands!"); 364 365 Inst.addOperand(MCOperand::CreateReg(getMemBase())); 366 367 const MCExpr *Expr = getMemOff(); 368 addExpr(Inst, Expr); 369 } 370 371 bool isReg() const { return Kind == k_Register; } 372 bool isImm() const { return Kind == k_Immediate; } 373 bool isToken() const { return Kind == k_Token; } 374 bool isMem() const { return Kind == k_Memory; } 375 bool isPtrReg() const { return Kind == k_PtrReg; } 376 bool isInvNum() const { return Kind == k_Immediate; } 377 378 StringRef getToken() const { 379 assert(Kind == k_Token && "Invalid access!"); 380 return StringRef(Tok.Data, Tok.Length); 381 } 382 383 unsigned getReg() const { 384 assert((Kind == k_Register) && "Invalid access!"); 385 return Reg.RegNum; 386 } 387 388 unsigned getPtrReg() const { 389 assert((Kind == k_PtrReg) && "Invalid access!"); 390 return Reg.RegNum; 391 } 392 393 void setRegKind(RegisterKind RegKind) { 394 assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!"); 395 Reg.Kind = RegKind; 396 } 397 398 const MCExpr *getImm() const { 399 assert((Kind == k_Immediate) && "Invalid access!"); 400 return Imm.Val; 401 } 402 403 unsigned getMemBase() const { 404 assert((Kind == k_Memory) && "Invalid access!"); 405 return Mem.Base; 406 } 407 408 const MCExpr *getMemOff() const { 409 assert((Kind == k_Memory) && "Invalid access!"); 410 return Mem.Off; 411 } 412 413 static MipsOperand *CreateToken(StringRef Str, SMLoc S) { 414 MipsOperand *Op = new MipsOperand(k_Token); 415 Op->Tok.Data = Str.data(); 416 Op->Tok.Length = Str.size(); 417 Op->StartLoc = S; 418 Op->EndLoc = S; 419 return Op; 420 } 421 422 static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) { 423 MipsOperand *Op = new MipsOperand(k_Register); 424 Op->Reg.RegNum = RegNum; 425 Op->StartLoc = S; 426 Op->EndLoc = E; 427 return Op; 428 } 429 430 static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) { 431 MipsOperand *Op = new MipsOperand(k_PtrReg); 432 Op->Reg.RegNum = RegNum; 433 Op->StartLoc = S; 434 Op->EndLoc = E; 435 return Op; 436 } 437 438 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) { 439 MipsOperand *Op = new MipsOperand(k_Immediate); 440 Op->Imm.Val = Val; 441 Op->StartLoc = S; 442 Op->EndLoc = E; 443 return Op; 444 } 445 446 static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S, 447 SMLoc E) { 448 MipsOperand *Op = new MipsOperand(k_Memory); 449 Op->Mem.Base = Base; 450 Op->Mem.Off = Off; 451 Op->StartLoc = S; 452 Op->EndLoc = E; 453 return Op; 454 } 455 456 bool isGPR32Asm() const { 457 return Kind == k_Register && Reg.Kind == Kind_GPR32; 458 } 459 void addRegAsmOperands(MCInst &Inst, unsigned N) const { 460 Inst.addOperand(MCOperand::CreateReg(Reg.RegNum)); 461 } 462 463 bool isGPR64Asm() const { 464 return Kind == k_Register && Reg.Kind == Kind_GPR64; 465 } 466 467 bool isHWRegsAsm() const { 468 assert((Kind == k_Register) && "Invalid access!"); 469 return Reg.Kind == Kind_HWRegs; 470 } 471 472 bool isCCRAsm() const { 473 assert((Kind == k_Register) && "Invalid access!"); 474 return Reg.Kind == Kind_CCRRegs; 475 } 476 477 bool isAFGR64Asm() const { 478 return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs; 479 } 480 481 bool isFGR64Asm() const { 482 return Kind == k_Register && Reg.Kind == Kind_FGR64Regs; 483 } 484 485 bool isFGR32Asm() const { 486 return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs; 487 } 488 489 bool isFGRH32Asm() const { 490 return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs; 491 } 492 493 bool isFCCRegsAsm() const { 494 return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs; 495 } 496 497 bool isACC64DSPAsm() const { 498 return Kind == k_Register && Reg.Kind == Kind_ACC64DSP; 499 } 500 501 bool isLO32DSPAsm() const { 502 return Kind == k_Register && Reg.Kind == Kind_LO32DSP; 503 } 504 505 bool isHI32DSPAsm() const { 506 return Kind == k_Register && Reg.Kind == Kind_HI32DSP; 507 } 508 509 bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; } 510 511 bool isMSA128BAsm() const { 512 return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs; 513 } 514 515 bool isMSA128HAsm() const { 516 return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs; 517 } 518 519 bool isMSA128WAsm() const { 520 return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs; 521 } 522 523 bool isMSA128DAsm() const { 524 return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs; 525 } 526 527 bool isMSA128CRAsm() const { 528 return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs; 529 } 530 531 /// getStartLoc - Get the location of the first token of this operand. 532 SMLoc getStartLoc() const { return StartLoc; } 533 /// getEndLoc - Get the location of the last token of this operand. 534 SMLoc getEndLoc() const { return EndLoc; } 535 536 virtual void print(raw_ostream &OS) const { 537 llvm_unreachable("unimplemented!"); 538 } 539}; // class MipsOperand 540} // namespace 541 542namespace llvm { 543extern const MCInstrDesc MipsInsts[]; 544} 545static const MCInstrDesc &getInstDesc(unsigned Opcode) { 546 return MipsInsts[Opcode]; 547} 548 549bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc, 550 SmallVectorImpl<MCInst> &Instructions) { 551 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode()); 552 Inst.setLoc(IDLoc); 553 if (MCID.hasDelaySlot() && Options.isReorder()) { 554 // If this instruction has a delay slot and .set reorder is active, 555 // emit a NOP after it. 556 Instructions.push_back(Inst); 557 MCInst NopInst; 558 NopInst.setOpcode(Mips::SLL); 559 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 560 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 561 NopInst.addOperand(MCOperand::CreateImm(0)); 562 Instructions.push_back(NopInst); 563 return false; 564 } 565 566 if (MCID.mayLoad() || MCID.mayStore()) { 567 // Check the offset of memory operand, if it is a symbol 568 // reference or immediate we may have to expand instructions. 569 for (unsigned i = 0; i < MCID.getNumOperands(); i++) { 570 const MCOperandInfo &OpInfo = MCID.OpInfo[i]; 571 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) || 572 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) { 573 MCOperand &Op = Inst.getOperand(i); 574 if (Op.isImm()) { 575 int MemOffset = Op.getImm(); 576 if (MemOffset < -32768 || MemOffset > 32767) { 577 // Offset can't exceed 16bit value. 578 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true); 579 return false; 580 } 581 } else if (Op.isExpr()) { 582 const MCExpr *Expr = Op.getExpr(); 583 if (Expr->getKind() == MCExpr::SymbolRef) { 584 const MCSymbolRefExpr *SR = 585 static_cast<const MCSymbolRefExpr *>(Expr); 586 if (SR->getKind() == MCSymbolRefExpr::VK_None) { 587 // Expand symbol. 588 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 589 return false; 590 } 591 } else if (!isEvaluated(Expr)) { 592 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false); 593 return false; 594 } 595 } 596 } 597 } // for 598 } // if load/store 599 600 if (needsExpansion(Inst)) 601 expandInstruction(Inst, IDLoc, Instructions); 602 else 603 Instructions.push_back(Inst); 604 605 return false; 606} 607 608bool MipsAsmParser::needsExpansion(MCInst &Inst) { 609 610 switch (Inst.getOpcode()) { 611 case Mips::LoadImm32Reg: 612 case Mips::LoadAddr32Imm: 613 case Mips::LoadAddr32Reg: 614 return true; 615 default: 616 return false; 617 } 618} 619 620void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc, 621 SmallVectorImpl<MCInst> &Instructions) { 622 switch (Inst.getOpcode()) { 623 case Mips::LoadImm32Reg: 624 return expandLoadImm(Inst, IDLoc, Instructions); 625 case Mips::LoadAddr32Imm: 626 return expandLoadAddressImm(Inst, IDLoc, Instructions); 627 case Mips::LoadAddr32Reg: 628 return expandLoadAddressReg(Inst, IDLoc, Instructions); 629 } 630} 631 632void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc, 633 SmallVectorImpl<MCInst> &Instructions) { 634 MCInst tmpInst; 635 const MCOperand &ImmOp = Inst.getOperand(1); 636 assert(ImmOp.isImm() && "expected immediate operand kind"); 637 const MCOperand &RegOp = Inst.getOperand(0); 638 assert(RegOp.isReg() && "expected register operand kind"); 639 640 int ImmValue = ImmOp.getImm(); 641 tmpInst.setLoc(IDLoc); 642 if (0 <= ImmValue && ImmValue <= 65535) { 643 // For 0 <= j <= 65535. 644 // li d,j => ori d,$zero,j 645 tmpInst.setOpcode(Mips::ORi); 646 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 647 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 648 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 649 Instructions.push_back(tmpInst); 650 } else if (ImmValue < 0 && ImmValue >= -32768) { 651 // For -32768 <= j < 0. 652 // li d,j => addiu d,$zero,j 653 tmpInst.setOpcode(Mips::ADDiu); 654 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 655 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 656 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 657 Instructions.push_back(tmpInst); 658 } else { 659 // For any other value of j that is representable as a 32-bit integer. 660 // li d,j => lui d,hi16(j) 661 // ori d,d,lo16(j) 662 tmpInst.setOpcode(Mips::LUi); 663 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 664 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 665 Instructions.push_back(tmpInst); 666 tmpInst.clear(); 667 tmpInst.setOpcode(Mips::ORi); 668 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 669 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 670 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 671 tmpInst.setLoc(IDLoc); 672 Instructions.push_back(tmpInst); 673 } 674} 675 676void 677MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc, 678 SmallVectorImpl<MCInst> &Instructions) { 679 MCInst tmpInst; 680 const MCOperand &ImmOp = Inst.getOperand(2); 681 assert(ImmOp.isImm() && "expected immediate operand kind"); 682 const MCOperand &SrcRegOp = Inst.getOperand(1); 683 assert(SrcRegOp.isReg() && "expected register operand kind"); 684 const MCOperand &DstRegOp = Inst.getOperand(0); 685 assert(DstRegOp.isReg() && "expected register operand kind"); 686 int ImmValue = ImmOp.getImm(); 687 if (-32768 <= ImmValue && ImmValue <= 65535) { 688 // For -32768 <= j <= 65535. 689 // la d,j(s) => addiu d,s,j 690 tmpInst.setOpcode(Mips::ADDiu); 691 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 692 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 693 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 694 Instructions.push_back(tmpInst); 695 } else { 696 // For any other value of j that is representable as a 32-bit integer. 697 // la d,j(s) => lui d,hi16(j) 698 // ori d,d,lo16(j) 699 // addu d,d,s 700 tmpInst.setOpcode(Mips::LUi); 701 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 702 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 703 Instructions.push_back(tmpInst); 704 tmpInst.clear(); 705 tmpInst.setOpcode(Mips::ORi); 706 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 707 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 708 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 709 Instructions.push_back(tmpInst); 710 tmpInst.clear(); 711 tmpInst.setOpcode(Mips::ADDu); 712 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 713 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg())); 714 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg())); 715 Instructions.push_back(tmpInst); 716 } 717} 718 719void 720MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc, 721 SmallVectorImpl<MCInst> &Instructions) { 722 MCInst tmpInst; 723 const MCOperand &ImmOp = Inst.getOperand(1); 724 assert(ImmOp.isImm() && "expected immediate operand kind"); 725 const MCOperand &RegOp = Inst.getOperand(0); 726 assert(RegOp.isReg() && "expected register operand kind"); 727 int ImmValue = ImmOp.getImm(); 728 if (-32768 <= ImmValue && ImmValue <= 65535) { 729 // For -32768 <= j <= 65535. 730 // la d,j => addiu d,$zero,j 731 tmpInst.setOpcode(Mips::ADDiu); 732 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 733 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO)); 734 tmpInst.addOperand(MCOperand::CreateImm(ImmValue)); 735 Instructions.push_back(tmpInst); 736 } else { 737 // For any other value of j that is representable as a 32-bit integer. 738 // la d,j => lui d,hi16(j) 739 // ori d,d,lo16(j) 740 tmpInst.setOpcode(Mips::LUi); 741 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 742 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16)); 743 Instructions.push_back(tmpInst); 744 tmpInst.clear(); 745 tmpInst.setOpcode(Mips::ORi); 746 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 747 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg())); 748 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff)); 749 Instructions.push_back(tmpInst); 750 } 751} 752 753void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, 754 SmallVectorImpl<MCInst> &Instructions, 755 bool isLoad, bool isImmOpnd) { 756 const MCSymbolRefExpr *SR; 757 MCInst TempInst; 758 unsigned ImmOffset, HiOffset, LoOffset; 759 const MCExpr *ExprOffset; 760 unsigned TmpRegNum; 761 unsigned AtRegNum = getReg( 762 (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg()); 763 // 1st operand is either the source or destination register. 764 assert(Inst.getOperand(0).isReg() && "expected register operand kind"); 765 unsigned RegOpNum = Inst.getOperand(0).getReg(); 766 // 2nd operand is the base register. 767 assert(Inst.getOperand(1).isReg() && "expected register operand kind"); 768 unsigned BaseRegNum = Inst.getOperand(1).getReg(); 769 // 3rd operand is either an immediate or expression. 770 if (isImmOpnd) { 771 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind"); 772 ImmOffset = Inst.getOperand(2).getImm(); 773 LoOffset = ImmOffset & 0x0000ffff; 774 HiOffset = (ImmOffset & 0xffff0000) >> 16; 775 // If msb of LoOffset is 1(negative number) we must increment HiOffset. 776 if (LoOffset & 0x8000) 777 HiOffset++; 778 } else 779 ExprOffset = Inst.getOperand(2).getExpr(); 780 // All instructions will have the same location. 781 TempInst.setLoc(IDLoc); 782 // 1st instruction in expansion is LUi. For load instruction we can use 783 // the dst register as a temporary if base and dst are different, 784 // but for stores we must use $at. 785 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum; 786 TempInst.setOpcode(Mips::LUi); 787 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 788 if (isImmOpnd) 789 TempInst.addOperand(MCOperand::CreateImm(HiOffset)); 790 else { 791 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 792 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset); 793 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create( 794 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI, 795 getContext()); 796 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 797 } else { 798 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi"); 799 TempInst.addOperand(MCOperand::CreateExpr(HiExpr)); 800 } 801 } 802 // Add the instruction to the list. 803 Instructions.push_back(TempInst); 804 // Prepare TempInst for next instruction. 805 TempInst.clear(); 806 // Add temp register to base. 807 TempInst.setOpcode(Mips::ADDu); 808 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 809 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 810 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum)); 811 Instructions.push_back(TempInst); 812 TempInst.clear(); 813 // And finaly, create original instruction with low part 814 // of offset and new base. 815 TempInst.setOpcode(Inst.getOpcode()); 816 TempInst.addOperand(MCOperand::CreateReg(RegOpNum)); 817 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum)); 818 if (isImmOpnd) 819 TempInst.addOperand(MCOperand::CreateImm(LoOffset)); 820 else { 821 if (ExprOffset->getKind() == MCExpr::SymbolRef) { 822 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create( 823 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO, 824 getContext()); 825 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 826 } else { 827 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo"); 828 TempInst.addOperand(MCOperand::CreateExpr(LoExpr)); 829 } 830 } 831 Instructions.push_back(TempInst); 832 TempInst.clear(); 833} 834 835bool MipsAsmParser::MatchAndEmitInstruction( 836 SMLoc IDLoc, unsigned &Opcode, 837 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out, 838 unsigned &ErrorInfo, bool MatchingInlineAsm) { 839 MCInst Inst; 840 SmallVector<MCInst, 8> Instructions; 841 unsigned MatchResult = 842 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm); 843 844 switch (MatchResult) { 845 default: 846 break; 847 case Match_Success: { 848 if (processInstruction(Inst, IDLoc, Instructions)) 849 return true; 850 for (unsigned i = 0; i < Instructions.size(); i++) 851 Out.EmitInstruction(Instructions[i]); 852 return false; 853 } 854 case Match_MissingFeature: 855 Error(IDLoc, "instruction requires a CPU feature not currently enabled"); 856 return true; 857 case Match_InvalidOperand: { 858 SMLoc ErrorLoc = IDLoc; 859 if (ErrorInfo != ~0U) { 860 if (ErrorInfo >= Operands.size()) 861 return Error(IDLoc, "too few operands for instruction"); 862 863 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc(); 864 if (ErrorLoc == SMLoc()) 865 ErrorLoc = IDLoc; 866 } 867 868 return Error(ErrorLoc, "invalid operand for instruction"); 869 } 870 case Match_MnemonicFail: 871 return Error(IDLoc, "invalid instruction"); 872 } 873 return true; 874} 875 876int MipsAsmParser::matchCPURegisterName(StringRef Name) { 877 int CC; 878 879 if (Name == "at") 880 return getATReg(); 881 882 CC = StringSwitch<unsigned>(Name) 883 .Case("zero", 0) 884 .Case("a0", 4) 885 .Case("a1", 5) 886 .Case("a2", 6) 887 .Case("a3", 7) 888 .Case("v0", 2) 889 .Case("v1", 3) 890 .Case("s0", 16) 891 .Case("s1", 17) 892 .Case("s2", 18) 893 .Case("s3", 19) 894 .Case("s4", 20) 895 .Case("s5", 21) 896 .Case("s6", 22) 897 .Case("s7", 23) 898 .Case("k0", 26) 899 .Case("k1", 27) 900 .Case("sp", 29) 901 .Case("fp", 30) 902 .Case("gp", 28) 903 .Case("ra", 31) 904 .Case("t0", 8) 905 .Case("t1", 9) 906 .Case("t2", 10) 907 .Case("t3", 11) 908 .Case("t4", 12) 909 .Case("t5", 13) 910 .Case("t6", 14) 911 .Case("t7", 15) 912 .Case("t8", 24) 913 .Case("t9", 25) 914 .Default(-1); 915 916 // Although SGI documentation just cuts out t0-t3 for n32/n64, 917 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7 918 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7. 919 if (isMips64() && 8 <= CC && CC <= 11) 920 CC += 4; 921 922 if (CC == -1 && isMips64()) 923 CC = StringSwitch<unsigned>(Name) 924 .Case("a4", 8) 925 .Case("a5", 9) 926 .Case("a6", 10) 927 .Case("a7", 11) 928 .Case("kt0", 26) 929 .Case("kt1", 27) 930 .Case("s8", 30) 931 .Default(-1); 932 933 return CC; 934} 935 936int MipsAsmParser::matchFPURegisterName(StringRef Name) { 937 938 if (Name[0] == 'f') { 939 StringRef NumString = Name.substr(1); 940 unsigned IntVal; 941 if (NumString.getAsInteger(10, IntVal)) 942 return -1; // This is not an integer. 943 if (IntVal > 31) // Maximum index for fpu register. 944 return -1; 945 return IntVal; 946 } 947 return -1; 948} 949 950int MipsAsmParser::matchFCCRegisterName(StringRef Name) { 951 952 if (Name.startswith("fcc")) { 953 StringRef NumString = Name.substr(3); 954 unsigned IntVal; 955 if (NumString.getAsInteger(10, IntVal)) 956 return -1; // This is not an integer. 957 if (IntVal > 7) // There are only 8 fcc registers. 958 return -1; 959 return IntVal; 960 } 961 return -1; 962} 963 964int MipsAsmParser::matchACRegisterName(StringRef Name) { 965 966 if (Name.startswith("ac")) { 967 StringRef NumString = Name.substr(2); 968 unsigned IntVal; 969 if (NumString.getAsInteger(10, IntVal)) 970 return -1; // This is not an integer. 971 if (IntVal > 3) // There are only 3 acc registers. 972 return -1; 973 return IntVal; 974 } 975 return -1; 976} 977 978int MipsAsmParser::matchMSA128RegisterName(StringRef Name) { 979 unsigned IntVal; 980 981 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal)) 982 return -1; 983 984 if (IntVal > 31) 985 return -1; 986 987 return IntVal; 988} 989 990int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) { 991 int CC; 992 993 CC = StringSwitch<unsigned>(Name) 994 .Case("msair", 0) 995 .Case("msacsr", 1) 996 .Case("msaaccess", 2) 997 .Case("msasave", 3) 998 .Case("msamodify", 4) 999 .Case("msarequest", 5) 1000 .Case("msamap", 6) 1001 .Case("msaunmap", 7) 1002 .Default(-1); 1003 1004 return CC; 1005} 1006 1007int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) { 1008 1009 int CC; 1010 CC = matchCPURegisterName(Name); 1011 if (CC != -1) 1012 return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID 1013 : Mips::GPR32RegClassID); 1014 CC = matchFPURegisterName(Name); 1015 // TODO: decide about fpu register class 1016 if (CC != -1) 1017 return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID 1018 : Mips::FGR32RegClassID); 1019 return matchMSA128RegisterName(Name); 1020} 1021 1022int MipsAsmParser::regKindToRegClass(int RegKind) { 1023 1024 switch (RegKind) { 1025 case MipsOperand::Kind_GPR32: 1026 return Mips::GPR32RegClassID; 1027 case MipsOperand::Kind_GPR64: 1028 return Mips::GPR64RegClassID; 1029 case MipsOperand::Kind_HWRegs: 1030 return Mips::HWRegsRegClassID; 1031 case MipsOperand::Kind_FGR32Regs: 1032 return Mips::FGR32RegClassID; 1033 case MipsOperand::Kind_FGRH32Regs: 1034 return Mips::FGRH32RegClassID; 1035 case MipsOperand::Kind_FGR64Regs: 1036 return Mips::FGR64RegClassID; 1037 case MipsOperand::Kind_AFGR64Regs: 1038 return Mips::AFGR64RegClassID; 1039 case MipsOperand::Kind_CCRRegs: 1040 return Mips::CCRRegClassID; 1041 case MipsOperand::Kind_ACC64DSP: 1042 return Mips::ACC64DSPRegClassID; 1043 case MipsOperand::Kind_FCCRegs: 1044 return Mips::FCCRegClassID; 1045 case MipsOperand::Kind_MSA128BRegs: 1046 return Mips::MSA128BRegClassID; 1047 case MipsOperand::Kind_MSA128HRegs: 1048 return Mips::MSA128HRegClassID; 1049 case MipsOperand::Kind_MSA128WRegs: 1050 return Mips::MSA128WRegClassID; 1051 case MipsOperand::Kind_MSA128DRegs: 1052 return Mips::MSA128DRegClassID; 1053 case MipsOperand::Kind_MSA128CtrlRegs: 1054 return Mips::MSACtrlRegClassID; 1055 default: 1056 return -1; 1057 } 1058} 1059 1060bool MipsAssemblerOptions::setATReg(unsigned Reg) { 1061 if (Reg > 31) 1062 return false; 1063 1064 aTReg = Reg; 1065 return true; 1066} 1067 1068int MipsAsmParser::getATReg() { return Options.getATRegNum(); } 1069 1070unsigned MipsAsmParser::getReg(int RC, int RegNo) { 1071 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo); 1072} 1073 1074int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) { 1075 if (RegNum > 1076 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs()) 1077 return -1; 1078 1079 return getReg(RegClass, RegNum); 1080} 1081 1082int MipsAsmParser::tryParseRegister(bool is64BitReg) { 1083 const AsmToken &Tok = Parser.getTok(); 1084 int RegNum = -1; 1085 1086 if (Tok.is(AsmToken::Identifier)) { 1087 std::string lowerCase = Tok.getString().lower(); 1088 RegNum = matchRegisterName(lowerCase, is64BitReg); 1089 } else if (Tok.is(AsmToken::Integer)) 1090 RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()), 1091 is64BitReg ? Mips::GPR64RegClassID 1092 : Mips::GPR32RegClassID); 1093 return RegNum; 1094} 1095 1096bool MipsAsmParser::tryParseRegisterOperand( 1097 SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) { 1098 1099 SMLoc S = Parser.getTok().getLoc(); 1100 int RegNo = -1; 1101 1102 RegNo = tryParseRegister(is64BitReg); 1103 if (RegNo == -1) 1104 return true; 1105 1106 Operands.push_back( 1107 MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc())); 1108 Parser.Lex(); // Eat register token. 1109 return false; 1110} 1111 1112bool 1113MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 1114 StringRef Mnemonic) { 1115 // Check if the current operand has a custom associated parser, if so, try to 1116 // custom parse the operand, or fallback to the general approach. 1117 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic); 1118 if (ResTy == MatchOperand_Success) 1119 return false; 1120 // If there wasn't a custom match, try the generic matcher below. Otherwise, 1121 // there was a match, but an error occurred, in which case, just return that 1122 // the operand parsing failed. 1123 if (ResTy == MatchOperand_ParseFail) 1124 return true; 1125 1126 switch (getLexer().getKind()) { 1127 default: 1128 Error(Parser.getTok().getLoc(), "unexpected token in operand"); 1129 return true; 1130 case AsmToken::Dollar: { 1131 // Parse the register. 1132 SMLoc S = Parser.getTok().getLoc(); 1133 Parser.Lex(); // Eat dollar token. 1134 // Parse the register operand. 1135 if (!tryParseRegisterOperand(Operands, isMips64())) { 1136 if (getLexer().is(AsmToken::LParen)) { 1137 // Check if it is indexed addressing operand. 1138 Operands.push_back(MipsOperand::CreateToken("(", S)); 1139 Parser.Lex(); // Eat the parenthesis. 1140 if (getLexer().isNot(AsmToken::Dollar)) 1141 return true; 1142 1143 Parser.Lex(); // Eat the dollar 1144 if (tryParseRegisterOperand(Operands, isMips64())) 1145 return true; 1146 1147 if (!getLexer().is(AsmToken::RParen)) 1148 return true; 1149 1150 S = Parser.getTok().getLoc(); 1151 Operands.push_back(MipsOperand::CreateToken(")", S)); 1152 Parser.Lex(); 1153 } 1154 return false; 1155 } 1156 // Maybe it is a symbol reference. 1157 StringRef Identifier; 1158 if (Parser.parseIdentifier(Identifier)) 1159 return true; 1160 1161 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1162 1163 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier); 1164 1165 // Otherwise create a symbol reference. 1166 const MCExpr *Res = 1167 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext()); 1168 1169 Operands.push_back(MipsOperand::CreateImm(Res, S, E)); 1170 return false; 1171 } 1172 case AsmToken::Identifier: 1173 // Look for the existing symbol, we should check if 1174 // we need to assigne the propper RegisterKind. 1175 if (searchSymbolAlias(Operands, MipsOperand::Kind_None)) 1176 return false; 1177 // Else drop to expression parsing. 1178 case AsmToken::LParen: 1179 case AsmToken::Minus: 1180 case AsmToken::Plus: 1181 case AsmToken::Integer: 1182 case AsmToken::String: { 1183 // Quoted label names. 1184 const MCExpr *IdVal; 1185 SMLoc S = Parser.getTok().getLoc(); 1186 if (getParser().parseExpression(IdVal)) 1187 return true; 1188 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1189 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1190 return false; 1191 } 1192 case AsmToken::Percent: { 1193 // It is a symbol reference or constant expression. 1194 const MCExpr *IdVal; 1195 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand. 1196 if (parseRelocOperand(IdVal)) 1197 return true; 1198 1199 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1200 1201 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1202 return false; 1203 } // case AsmToken::Percent 1204 } // switch(getLexer().getKind()) 1205 return true; 1206} 1207 1208const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr, 1209 StringRef RelocStr) { 1210 const MCExpr *Res; 1211 // Check the type of the expression. 1212 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) { 1213 // It's a constant, evaluate lo or hi value. 1214 if (RelocStr == "lo") { 1215 short Val = MCE->getValue(); 1216 Res = MCConstantExpr::Create(Val, getContext()); 1217 } else if (RelocStr == "hi") { 1218 int Val = MCE->getValue(); 1219 int LoSign = Val & 0x8000; 1220 Val = (Val & 0xffff0000) >> 16; 1221 // Lower part is treated as a signed int, so if it is negative 1222 // we must add 1 to the hi part to compensate. 1223 if (LoSign) 1224 Val++; 1225 Res = MCConstantExpr::Create(Val, getContext()); 1226 } else { 1227 llvm_unreachable("Invalid RelocStr value"); 1228 } 1229 return Res; 1230 } 1231 1232 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) { 1233 // It's a symbol, create a symbolic expression from the symbol. 1234 StringRef Symbol = MSRE->getSymbol().getName(); 1235 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr); 1236 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext()); 1237 return Res; 1238 } 1239 1240 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1241 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr); 1242 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr); 1243 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext()); 1244 return Res; 1245 } 1246 1247 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) { 1248 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr); 1249 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext()); 1250 return Res; 1251 } 1252 // Just return the original expression. 1253 return Expr; 1254} 1255 1256bool MipsAsmParser::isEvaluated(const MCExpr *Expr) { 1257 1258 switch (Expr->getKind()) { 1259 case MCExpr::Constant: 1260 return true; 1261 case MCExpr::SymbolRef: 1262 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None); 1263 case MCExpr::Binary: 1264 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) { 1265 if (!isEvaluated(BE->getLHS())) 1266 return false; 1267 return isEvaluated(BE->getRHS()); 1268 } 1269 case MCExpr::Unary: 1270 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr()); 1271 default: 1272 return false; 1273 } 1274 return false; 1275} 1276 1277bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) { 1278 Parser.Lex(); // Eat the % token. 1279 const AsmToken &Tok = Parser.getTok(); // Get next token, operation. 1280 if (Tok.isNot(AsmToken::Identifier)) 1281 return true; 1282 1283 std::string Str = Tok.getIdentifier().str(); 1284 1285 Parser.Lex(); // Eat the identifier. 1286 // Now make an expression from the rest of the operand. 1287 const MCExpr *IdVal; 1288 SMLoc EndLoc; 1289 1290 if (getLexer().getKind() == AsmToken::LParen) { 1291 while (1) { 1292 Parser.Lex(); // Eat the '(' token. 1293 if (getLexer().getKind() == AsmToken::Percent) { 1294 Parser.Lex(); // Eat the % token. 1295 const AsmToken &nextTok = Parser.getTok(); 1296 if (nextTok.isNot(AsmToken::Identifier)) 1297 return true; 1298 Str += "(%"; 1299 Str += nextTok.getIdentifier(); 1300 Parser.Lex(); // Eat the identifier. 1301 if (getLexer().getKind() != AsmToken::LParen) 1302 return true; 1303 } else 1304 break; 1305 } 1306 if (getParser().parseParenExpression(IdVal, EndLoc)) 1307 return true; 1308 1309 while (getLexer().getKind() == AsmToken::RParen) 1310 Parser.Lex(); // Eat the ')' token. 1311 1312 } else 1313 return true; // Parenthesis must follow the relocation operand. 1314 1315 Res = evaluateRelocExpr(IdVal, Str); 1316 return false; 1317} 1318 1319bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, 1320 SMLoc &EndLoc) { 1321 StartLoc = Parser.getTok().getLoc(); 1322 RegNo = tryParseRegister(isMips64()); 1323 EndLoc = Parser.getTok().getLoc(); 1324 return (RegNo == (unsigned)-1); 1325} 1326 1327bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) { 1328 SMLoc S; 1329 bool Result = true; 1330 1331 while (getLexer().getKind() == AsmToken::LParen) 1332 Parser.Lex(); 1333 1334 switch (getLexer().getKind()) { 1335 default: 1336 return true; 1337 case AsmToken::Identifier: 1338 case AsmToken::LParen: 1339 case AsmToken::Integer: 1340 case AsmToken::Minus: 1341 case AsmToken::Plus: 1342 if (isParenExpr) 1343 Result = getParser().parseParenExpression(Res, S); 1344 else 1345 Result = (getParser().parseExpression(Res)); 1346 while (getLexer().getKind() == AsmToken::RParen) 1347 Parser.Lex(); 1348 break; 1349 case AsmToken::Percent: 1350 Result = parseRelocOperand(Res); 1351 } 1352 return Result; 1353} 1354 1355MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand( 1356 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1357 1358 const MCExpr *IdVal = 0; 1359 SMLoc S; 1360 bool isParenExpr = false; 1361 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch; 1362 // First operand is the offset. 1363 S = Parser.getTok().getLoc(); 1364 1365 if (getLexer().getKind() == AsmToken::LParen) { 1366 Parser.Lex(); 1367 isParenExpr = true; 1368 } 1369 1370 if (getLexer().getKind() != AsmToken::Dollar) { 1371 if (parseMemOffset(IdVal, isParenExpr)) 1372 return MatchOperand_ParseFail; 1373 1374 const AsmToken &Tok = Parser.getTok(); // Get the next token. 1375 if (Tok.isNot(AsmToken::LParen)) { 1376 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]); 1377 if (Mnemonic->getToken() == "la") { 1378 SMLoc E = 1379 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1380 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E)); 1381 return MatchOperand_Success; 1382 } 1383 if (Tok.is(AsmToken::EndOfStatement)) { 1384 SMLoc E = 1385 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1386 1387 // Zero register assumed, add a memory operand with ZERO as its base. 1388 Operands.push_back(MipsOperand::CreateMem( 1389 isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E)); 1390 return MatchOperand_Success; 1391 } 1392 Error(Parser.getTok().getLoc(), "'(' expected"); 1393 return MatchOperand_ParseFail; 1394 } 1395 1396 Parser.Lex(); // Eat the '(' token. 1397 } 1398 1399 Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64 1400 : (int)MipsOperand::Kind_GPR32); 1401 if (Res != MatchOperand_Success) 1402 return Res; 1403 1404 if (Parser.getTok().isNot(AsmToken::RParen)) { 1405 Error(Parser.getTok().getLoc(), "')' expected"); 1406 return MatchOperand_ParseFail; 1407 } 1408 1409 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 1410 1411 Parser.Lex(); // Eat the ')' token. 1412 1413 if (IdVal == 0) 1414 IdVal = MCConstantExpr::Create(0, getContext()); 1415 1416 // Replace the register operand with the memory operand. 1417 MipsOperand *op = static_cast<MipsOperand *>(Operands.back()); 1418 int RegNo = op->getReg(); 1419 // Remove the register from the operands. 1420 Operands.pop_back(); 1421 // Add the memory operand. 1422 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) { 1423 int64_t Imm; 1424 if (IdVal->EvaluateAsAbsolute(Imm)) 1425 IdVal = MCConstantExpr::Create(Imm, getContext()); 1426 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef) 1427 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(), 1428 getContext()); 1429 } 1430 1431 Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E)); 1432 delete op; 1433 return MatchOperand_Success; 1434} 1435 1436bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 1437 int RegKind) { 1438 // If the first token is not '$' we have an error. 1439 if (Parser.getTok().isNot(AsmToken::Dollar)) 1440 return false; 1441 1442 SMLoc S = Parser.getTok().getLoc(); 1443 Parser.Lex(); 1444 AsmToken::TokenKind TkKind = getLexer().getKind(); 1445 int Reg; 1446 1447 if (TkKind == AsmToken::Integer) { 1448 Reg = matchRegisterByNumber(Parser.getTok().getIntVal(), 1449 regKindToRegClass(RegKind)); 1450 if (Reg == -1) 1451 return false; 1452 } else if (TkKind == AsmToken::Identifier) { 1453 if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1) 1454 return false; 1455 Reg = getReg(regKindToRegClass(RegKind), Reg); 1456 } else { 1457 return false; 1458 } 1459 1460 MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc()); 1461 Op->setRegKind((MipsOperand::RegisterKind)RegKind); 1462 Operands.push_back(Op); 1463 Parser.Lex(); 1464 return true; 1465} 1466 1467MipsAsmParser::OperandMatchResultTy 1468MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1469 MipsOperand::RegisterKind RegKind = 1470 isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32; 1471 1472 // Parse index register. 1473 if (!parsePtrReg(Operands, RegKind)) 1474 return MatchOperand_NoMatch; 1475 1476 // Parse '('. 1477 if (Parser.getTok().isNot(AsmToken::LParen)) 1478 return MatchOperand_NoMatch; 1479 1480 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1481 Parser.Lex(); 1482 1483 // Parse base register. 1484 if (!parsePtrReg(Operands, RegKind)) 1485 return MatchOperand_NoMatch; 1486 1487 // Parse ')'. 1488 if (Parser.getTok().isNot(AsmToken::RParen)) 1489 return MatchOperand_NoMatch; 1490 1491 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1492 Parser.Lex(); 1493 1494 return MatchOperand_Success; 1495} 1496 1497MipsAsmParser::OperandMatchResultTy 1498MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 1499 int RegKind) { 1500 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1501 if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) { 1502 if (searchSymbolAlias(Operands, Kind)) 1503 return MatchOperand_Success; 1504 return MatchOperand_NoMatch; 1505 } 1506 SMLoc S = Parser.getTok().getLoc(); 1507 // If the first token is not '$', we have an error. 1508 if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar) 1509 return MatchOperand_NoMatch; 1510 if (!hasConsumedDollar) { 1511 Parser.Lex(); // Eat the '$' 1512 hasConsumedDollar = true; 1513 } 1514 if (getLexer().getKind() == AsmToken::Identifier) { 1515 int RegNum = -1; 1516 std::string RegName = Parser.getTok().getString().lower(); 1517 // Match register by name 1518 switch (RegKind) { 1519 case MipsOperand::Kind_GPR32: 1520 case MipsOperand::Kind_GPR64: 1521 RegNum = matchCPURegisterName(RegName); 1522 break; 1523 case MipsOperand::Kind_AFGR64Regs: 1524 case MipsOperand::Kind_FGR64Regs: 1525 case MipsOperand::Kind_FGR32Regs: 1526 case MipsOperand::Kind_FGRH32Regs: 1527 RegNum = matchFPURegisterName(RegName); 1528 if (RegKind == MipsOperand::Kind_AFGR64Regs) 1529 RegNum /= 2; 1530 else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64()) 1531 if (RegNum != -1 && RegNum % 2 != 0) 1532 Warning(S, "Float register should be even."); 1533 break; 1534 case MipsOperand::Kind_FCCRegs: 1535 RegNum = matchFCCRegisterName(RegName); 1536 break; 1537 case MipsOperand::Kind_ACC64DSP: 1538 RegNum = matchACRegisterName(RegName); 1539 break; 1540 default: 1541 break; // No match, value is set to -1. 1542 } 1543 // No match found, return _NoMatch to give a chance to other round. 1544 if (RegNum < 0) 1545 return MatchOperand_NoMatch; 1546 1547 int RegVal = getReg(regKindToRegClass(Kind), RegNum); 1548 if (RegVal == -1) 1549 return MatchOperand_NoMatch; 1550 1551 MipsOperand *Op = 1552 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc()); 1553 Op->setRegKind(Kind); 1554 Operands.push_back(Op); 1555 hasConsumedDollar = false; 1556 Parser.Lex(); // Eat the register name. 1557 return MatchOperand_Success; 1558 } else if (getLexer().getKind() == AsmToken::Integer) { 1559 unsigned RegNum = Parser.getTok().getIntVal(); 1560 if (Kind == MipsOperand::Kind_HWRegs) { 1561 if (RegNum != 29) 1562 return MatchOperand_NoMatch; 1563 // Only hwreg 29 is supported, found at index 0. 1564 RegNum = 0; 1565 } 1566 int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind)); 1567 if (Reg == -1) 1568 return MatchOperand_NoMatch; 1569 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1570 Op->setRegKind(Kind); 1571 Operands.push_back(Op); 1572 hasConsumedDollar = false; 1573 Parser.Lex(); // Eat the register number. 1574 if ((RegKind == MipsOperand::Kind_GPR32) && 1575 (getLexer().is(AsmToken::LParen))) { 1576 // Check if it is indexed addressing operand. 1577 Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc())); 1578 Parser.Lex(); // Eat the parenthesis. 1579 if (parseRegs(Operands, RegKind) != MatchOperand_Success) 1580 return MatchOperand_NoMatch; 1581 if (getLexer().isNot(AsmToken::RParen)) 1582 return MatchOperand_NoMatch; 1583 Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc())); 1584 Parser.Lex(); 1585 } 1586 return MatchOperand_Success; 1587 } 1588 return MatchOperand_NoMatch; 1589} 1590 1591bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) { 1592 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1593 1594 if (Val < 0) 1595 return false; 1596 1597 switch (Kind) { 1598 default: 1599 return false; 1600 case MipsOperand::Kind_MSA128BRegs: 1601 return Val < 16; 1602 case MipsOperand::Kind_MSA128HRegs: 1603 return Val < 8; 1604 case MipsOperand::Kind_MSA128WRegs: 1605 return Val < 4; 1606 case MipsOperand::Kind_MSA128DRegs: 1607 return Val < 2; 1608 } 1609} 1610 1611MipsAsmParser::OperandMatchResultTy 1612MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 1613 int RegKind) { 1614 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1615 SMLoc S = Parser.getTok().getLoc(); 1616 std::string RegName; 1617 1618 if (Parser.getTok().isNot(AsmToken::Dollar)) 1619 return MatchOperand_NoMatch; 1620 1621 switch (RegKind) { 1622 default: 1623 return MatchOperand_ParseFail; 1624 case MipsOperand::Kind_MSA128BRegs: 1625 case MipsOperand::Kind_MSA128HRegs: 1626 case MipsOperand::Kind_MSA128WRegs: 1627 case MipsOperand::Kind_MSA128DRegs: 1628 break; 1629 } 1630 1631 Parser.Lex(); // Eat the '$'. 1632 if (getLexer().getKind() == AsmToken::Identifier) 1633 RegName = Parser.getTok().getString().lower(); 1634 else 1635 return MatchOperand_ParseFail; 1636 1637 int RegNum = matchMSA128RegisterName(RegName); 1638 1639 if (RegNum < 0 || RegNum > 31) 1640 return MatchOperand_ParseFail; 1641 1642 int RegVal = getReg(regKindToRegClass(Kind), RegNum); 1643 if (RegVal == -1) 1644 return MatchOperand_ParseFail; 1645 1646 MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc()); 1647 Op->setRegKind(Kind); 1648 Operands.push_back(Op); 1649 1650 Parser.Lex(); // Eat the register identifier. 1651 1652 // MSA registers may be suffixed with an index in the form of: 1653 // 1) Immediate expression. 1654 // 2) General Purpose Register. 1655 // Examples: 1656 // 1) copy_s.b $29,$w0[0] 1657 // 2) sld.b $w0,$w1[$1] 1658 1659 if (Parser.getTok().isNot(AsmToken::LBrac)) 1660 return MatchOperand_Success; 1661 1662 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]); 1663 1664 Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc())); 1665 Parser.Lex(); // Parse the '[' token. 1666 1667 if (Parser.getTok().is(AsmToken::Dollar)) { 1668 // This must be a GPR. 1669 MipsOperand *RegOp; 1670 SMLoc VIdx = Parser.getTok().getLoc(); 1671 Parser.Lex(); // Parse the '$' token. 1672 1673 // GPR have aliases and we must account for that. Example: $30 == $fp 1674 if (getLexer().getKind() == AsmToken::Integer) { 1675 unsigned RegNum = Parser.getTok().getIntVal(); 1676 int Reg = matchRegisterByNumber( 1677 RegNum, regKindToRegClass(MipsOperand::Kind_GPR32)); 1678 if (Reg == -1) { 1679 Error(VIdx, "invalid general purpose register"); 1680 return MatchOperand_ParseFail; 1681 } 1682 1683 RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc()); 1684 } else if (getLexer().getKind() == AsmToken::Identifier) { 1685 int RegNum = -1; 1686 std::string RegName = Parser.getTok().getString().lower(); 1687 1688 RegNum = matchCPURegisterName(RegName); 1689 if (RegNum == -1) { 1690 Error(VIdx, "general purpose register expected"); 1691 return MatchOperand_ParseFail; 1692 } 1693 RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum); 1694 RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc()); 1695 } else 1696 return MatchOperand_ParseFail; 1697 1698 RegOp->setRegKind(MipsOperand::Kind_GPR32); 1699 Operands.push_back(RegOp); 1700 Parser.Lex(); // Eat the register identifier. 1701 1702 if (Parser.getTok().isNot(AsmToken::RBrac)) 1703 return MatchOperand_ParseFail; 1704 1705 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc())); 1706 Parser.Lex(); // Parse the ']' token. 1707 1708 return MatchOperand_Success; 1709 } 1710 1711 // The index must be a constant expression then. 1712 SMLoc VIdx = Parser.getTok().getLoc(); 1713 const MCExpr *ImmVal; 1714 1715 if (getParser().parseExpression(ImmVal)) 1716 return MatchOperand_ParseFail; 1717 1718 const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal); 1719 if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) { 1720 Error(VIdx, "invalid immediate value"); 1721 return MatchOperand_ParseFail; 1722 } 1723 1724 SMLoc E = Parser.getTok().getEndLoc(); 1725 1726 if (Parser.getTok().isNot(AsmToken::RBrac)) 1727 return MatchOperand_ParseFail; 1728 1729 bool insve = 1730 Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" || 1731 Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d"; 1732 1733 // The second vector index of insve instructions is always 0. 1734 if (insve && Operands.size() > 6) { 1735 if (expr->getValue() != 0) { 1736 Error(VIdx, "immediate value must be 0"); 1737 return MatchOperand_ParseFail; 1738 } 1739 Operands.push_back(MipsOperand::CreateToken("0", VIdx)); 1740 } else 1741 Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E)); 1742 1743 Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc())); 1744 1745 Parser.Lex(); // Parse the ']' token. 1746 1747 return MatchOperand_Success; 1748} 1749 1750MipsAsmParser::OperandMatchResultTy 1751MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, 1752 int RegKind) { 1753 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1754 1755 if (Kind != MipsOperand::Kind_MSA128CtrlRegs) 1756 return MatchOperand_NoMatch; 1757 1758 if (Parser.getTok().isNot(AsmToken::Dollar)) 1759 return MatchOperand_ParseFail; 1760 1761 SMLoc S = Parser.getTok().getLoc(); 1762 1763 Parser.Lex(); // Eat the '$' symbol. 1764 1765 int RegNum = -1; 1766 if (getLexer().getKind() == AsmToken::Identifier) 1767 RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower()); 1768 else if (getLexer().getKind() == AsmToken::Integer) 1769 RegNum = Parser.getTok().getIntVal(); 1770 else 1771 return MatchOperand_ParseFail; 1772 1773 if (RegNum < 0 || RegNum > 7) 1774 return MatchOperand_ParseFail; 1775 1776 int RegVal = getReg(regKindToRegClass(Kind), RegNum); 1777 if (RegVal == -1) 1778 return MatchOperand_ParseFail; 1779 1780 MipsOperand *RegOp = 1781 MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc()); 1782 RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs); 1783 Operands.push_back(RegOp); 1784 Parser.Lex(); // Eat the register identifier. 1785 1786 return MatchOperand_Success; 1787} 1788 1789MipsAsmParser::OperandMatchResultTy 1790MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1791 1792 if (!isMips64()) 1793 return MatchOperand_NoMatch; 1794 return parseRegs(Operands, (int)MipsOperand::Kind_GPR64); 1795} 1796 1797MipsAsmParser::OperandMatchResultTy 1798MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1799 return parseRegs(Operands, (int)MipsOperand::Kind_GPR32); 1800} 1801 1802MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs( 1803 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1804 1805 if (isFP64()) 1806 return MatchOperand_NoMatch; 1807 return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs); 1808} 1809 1810MipsAsmParser::OperandMatchResultTy 1811MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1812 if (!isFP64()) 1813 return MatchOperand_NoMatch; 1814 return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs); 1815} 1816 1817MipsAsmParser::OperandMatchResultTy 1818MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1819 return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs); 1820} 1821 1822MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs( 1823 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1824 return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs); 1825} 1826 1827MipsAsmParser::OperandMatchResultTy 1828MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1829 return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs); 1830} 1831 1832MipsAsmParser::OperandMatchResultTy 1833MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1834 return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP); 1835} 1836 1837MipsAsmParser::OperandMatchResultTy 1838MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1839 // If the first token is not '$' we have an error. 1840 if (Parser.getTok().isNot(AsmToken::Dollar)) 1841 return MatchOperand_NoMatch; 1842 1843 SMLoc S = Parser.getTok().getLoc(); 1844 Parser.Lex(); // Eat the '$' 1845 1846 const AsmToken &Tok = Parser.getTok(); // Get next token. 1847 1848 if (Tok.isNot(AsmToken::Identifier)) 1849 return MatchOperand_NoMatch; 1850 1851 if (!Tok.getIdentifier().startswith("ac")) 1852 return MatchOperand_NoMatch; 1853 1854 StringRef NumString = Tok.getIdentifier().substr(2); 1855 1856 unsigned IntVal; 1857 if (NumString.getAsInteger(10, IntVal)) 1858 return MatchOperand_NoMatch; 1859 1860 unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID); 1861 1862 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1863 Op->setRegKind(MipsOperand::Kind_LO32DSP); 1864 Operands.push_back(Op); 1865 1866 Parser.Lex(); // Eat the register number. 1867 return MatchOperand_Success; 1868} 1869 1870MipsAsmParser::OperandMatchResultTy 1871MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1872 // If the first token is not '$' we have an error. 1873 if (Parser.getTok().isNot(AsmToken::Dollar)) 1874 return MatchOperand_NoMatch; 1875 1876 SMLoc S = Parser.getTok().getLoc(); 1877 Parser.Lex(); // Eat the '$' 1878 1879 const AsmToken &Tok = Parser.getTok(); // Get next token. 1880 1881 if (Tok.isNot(AsmToken::Identifier)) 1882 return MatchOperand_NoMatch; 1883 1884 if (!Tok.getIdentifier().startswith("ac")) 1885 return MatchOperand_NoMatch; 1886 1887 StringRef NumString = Tok.getIdentifier().substr(2); 1888 1889 unsigned IntVal; 1890 if (NumString.getAsInteger(10, IntVal)) 1891 return MatchOperand_NoMatch; 1892 1893 unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID); 1894 1895 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1896 Op->setRegKind(MipsOperand::Kind_HI32DSP); 1897 Operands.push_back(Op); 1898 1899 Parser.Lex(); // Eat the register number. 1900 return MatchOperand_Success; 1901} 1902 1903MipsAsmParser::OperandMatchResultTy 1904MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1905 // If the first token is not '$' we have an error. 1906 if (Parser.getTok().isNot(AsmToken::Dollar)) 1907 return MatchOperand_NoMatch; 1908 1909 SMLoc S = Parser.getTok().getLoc(); 1910 Parser.Lex(); // Eat the '$' 1911 1912 const AsmToken &Tok = Parser.getTok(); // Get next token. 1913 1914 if (Tok.isNot(AsmToken::Integer)) 1915 return MatchOperand_NoMatch; 1916 1917 unsigned IntVal = Tok.getIntVal(); 1918 1919 unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID); 1920 1921 MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc()); 1922 Op->setRegKind(MipsOperand::Kind_COP2); 1923 Operands.push_back(Op); 1924 1925 Parser.Lex(); // Eat the register number. 1926 return MatchOperand_Success; 1927} 1928 1929MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs( 1930 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1931 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs); 1932} 1933 1934MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs( 1935 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1936 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs); 1937} 1938 1939MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs( 1940 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1941 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs); 1942} 1943 1944MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs( 1945 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1946 return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs); 1947} 1948 1949MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs( 1950 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 1951 return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs); 1952} 1953 1954bool MipsAsmParser::searchSymbolAlias( 1955 SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) { 1956 1957 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier()); 1958 if (Sym) { 1959 SMLoc S = Parser.getTok().getLoc(); 1960 const MCExpr *Expr; 1961 if (Sym->isVariable()) 1962 Expr = Sym->getVariableValue(); 1963 else 1964 return false; 1965 if (Expr->getKind() == MCExpr::SymbolRef) { 1966 MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind; 1967 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr); 1968 const StringRef DefSymbol = Ref->getSymbol().getName(); 1969 if (DefSymbol.startswith("$")) { 1970 int RegNum = -1; 1971 APInt IntVal(32, -1); 1972 if (!DefSymbol.substr(1).getAsInteger(10, IntVal)) 1973 RegNum = matchRegisterByNumber(IntVal.getZExtValue(), 1974 isMips64() ? Mips::GPR64RegClassID 1975 : Mips::GPR32RegClassID); 1976 else { 1977 // Lookup for the register with the corresponding name. 1978 switch (Kind) { 1979 case MipsOperand::Kind_AFGR64Regs: 1980 case MipsOperand::Kind_FGR64Regs: 1981 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1982 break; 1983 case MipsOperand::Kind_FGR32Regs: 1984 RegNum = matchFPURegisterName(DefSymbol.substr(1)); 1985 break; 1986 case MipsOperand::Kind_GPR64: 1987 case MipsOperand::Kind_GPR32: 1988 default: 1989 RegNum = matchCPURegisterName(DefSymbol.substr(1)); 1990 break; 1991 } 1992 if (RegNum > -1) 1993 RegNum = getReg(regKindToRegClass(Kind), RegNum); 1994 } 1995 if (RegNum > -1) { 1996 Parser.Lex(); 1997 MipsOperand *op = 1998 MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc()); 1999 op->setRegKind(Kind); 2000 Operands.push_back(op); 2001 return true; 2002 } 2003 } 2004 } else if (Expr->getKind() == MCExpr::Constant) { 2005 Parser.Lex(); 2006 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr); 2007 MipsOperand *op = 2008 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc()); 2009 Operands.push_back(op); 2010 return true; 2011 } 2012 } 2013 return false; 2014} 2015 2016MipsAsmParser::OperandMatchResultTy 2017MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2018 return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs); 2019} 2020 2021MipsAsmParser::OperandMatchResultTy 2022MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2023 return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs); 2024} 2025 2026MipsAsmParser::OperandMatchResultTy 2027MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2028 const MCExpr *IdVal; 2029 // If the first token is '$' we may have register operand. 2030 if (Parser.getTok().is(AsmToken::Dollar)) 2031 return MatchOperand_NoMatch; 2032 SMLoc S = Parser.getTok().getLoc(); 2033 if (getParser().parseExpression(IdVal)) 2034 return MatchOperand_ParseFail; 2035 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal); 2036 assert(MCE && "Unexpected MCExpr type."); 2037 int64_t Val = MCE->getValue(); 2038 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1); 2039 Operands.push_back(MipsOperand::CreateImm( 2040 MCConstantExpr::Create(0 - Val, getContext()), S, E)); 2041 return MatchOperand_Success; 2042} 2043 2044MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) { 2045 2046 MCSymbolRefExpr::VariantKind VK = 2047 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol) 2048 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI) 2049 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO) 2050 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL) 2051 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL) 2052 .Case("got", MCSymbolRefExpr::VK_Mips_GOT) 2053 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD) 2054 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM) 2055 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI) 2056 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO) 2057 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL) 2058 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI) 2059 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO) 2060 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP) 2061 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE) 2062 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST) 2063 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI) 2064 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO) 2065 .Default(MCSymbolRefExpr::VK_None); 2066 2067 return VK; 2068} 2069 2070bool MipsAsmParser::ParseInstruction( 2071 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc, 2072 SmallVectorImpl<MCParsedAsmOperand *> &Operands) { 2073 // Check if we have valid mnemonic 2074 if (!mnemonicIsValid(Name, 0)) { 2075 Parser.eatToEndOfStatement(); 2076 return Error(NameLoc, "Unknown instruction"); 2077 } 2078 // First operand in MCInst is instruction mnemonic. 2079 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc)); 2080 2081 // Read the remaining operands. 2082 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2083 // Read the first operand. 2084 if (ParseOperand(Operands, Name)) { 2085 SMLoc Loc = getLexer().getLoc(); 2086 Parser.eatToEndOfStatement(); 2087 return Error(Loc, "unexpected token in argument list"); 2088 } 2089 2090 while (getLexer().is(AsmToken::Comma)) { 2091 Parser.Lex(); // Eat the comma. 2092 // Parse and remember the operand. 2093 if (ParseOperand(Operands, Name)) { 2094 SMLoc Loc = getLexer().getLoc(); 2095 Parser.eatToEndOfStatement(); 2096 return Error(Loc, "unexpected token in argument list"); 2097 } 2098 } 2099 } 2100 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2101 SMLoc Loc = getLexer().getLoc(); 2102 Parser.eatToEndOfStatement(); 2103 return Error(Loc, "unexpected token in argument list"); 2104 } 2105 Parser.Lex(); // Consume the EndOfStatement. 2106 return false; 2107} 2108 2109bool MipsAsmParser::reportParseError(StringRef ErrorMsg) { 2110 SMLoc Loc = getLexer().getLoc(); 2111 Parser.eatToEndOfStatement(); 2112 return Error(Loc, ErrorMsg); 2113} 2114 2115bool MipsAsmParser::parseSetNoAtDirective() { 2116 // Line should look like: ".set noat". 2117 // set at reg to 0. 2118 Options.setATReg(0); 2119 // eat noat 2120 Parser.Lex(); 2121 // If this is not the end of the statement, report an error. 2122 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2123 reportParseError("unexpected token in statement"); 2124 return false; 2125 } 2126 Parser.Lex(); // Consume the EndOfStatement. 2127 return false; 2128} 2129 2130bool MipsAsmParser::parseSetAtDirective() { 2131 // Line can be .set at - defaults to $1 2132 // or .set at=$reg 2133 int AtRegNo; 2134 getParser().Lex(); 2135 if (getLexer().is(AsmToken::EndOfStatement)) { 2136 Options.setATReg(1); 2137 Parser.Lex(); // Consume the EndOfStatement. 2138 return false; 2139 } else if (getLexer().is(AsmToken::Equal)) { 2140 getParser().Lex(); // Eat the '='. 2141 if (getLexer().isNot(AsmToken::Dollar)) { 2142 reportParseError("unexpected token in statement"); 2143 return false; 2144 } 2145 Parser.Lex(); // Eat the '$'. 2146 const AsmToken &Reg = Parser.getTok(); 2147 if (Reg.is(AsmToken::Identifier)) { 2148 AtRegNo = matchCPURegisterName(Reg.getIdentifier()); 2149 } else if (Reg.is(AsmToken::Integer)) { 2150 AtRegNo = Reg.getIntVal(); 2151 } else { 2152 reportParseError("unexpected token in statement"); 2153 return false; 2154 } 2155 2156 if (AtRegNo < 1 || AtRegNo > 31) { 2157 reportParseError("unexpected token in statement"); 2158 return false; 2159 } 2160 2161 if (!Options.setATReg(AtRegNo)) { 2162 reportParseError("unexpected token in statement"); 2163 return false; 2164 } 2165 getParser().Lex(); // Eat the register. 2166 2167 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2168 reportParseError("unexpected token in statement"); 2169 return false; 2170 } 2171 Parser.Lex(); // Consume the EndOfStatement. 2172 return false; 2173 } else { 2174 reportParseError("unexpected token in statement"); 2175 return false; 2176 } 2177} 2178 2179bool MipsAsmParser::parseSetReorderDirective() { 2180 Parser.Lex(); 2181 // If this is not the end of the statement, report an error. 2182 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2183 reportParseError("unexpected token in statement"); 2184 return false; 2185 } 2186 Options.setReorder(); 2187 Parser.Lex(); // Consume the EndOfStatement. 2188 return false; 2189} 2190 2191bool MipsAsmParser::parseSetNoReorderDirective() { 2192 Parser.Lex(); 2193 // If this is not the end of the statement, report an error. 2194 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2195 reportParseError("unexpected token in statement"); 2196 return false; 2197 } 2198 Options.setNoreorder(); 2199 Parser.Lex(); // Consume the EndOfStatement. 2200 return false; 2201} 2202 2203bool MipsAsmParser::parseSetMacroDirective() { 2204 Parser.Lex(); 2205 // If this is not the end of the statement, report an error. 2206 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2207 reportParseError("unexpected token in statement"); 2208 return false; 2209 } 2210 Options.setMacro(); 2211 Parser.Lex(); // Consume the EndOfStatement. 2212 return false; 2213} 2214 2215bool MipsAsmParser::parseSetNoMacroDirective() { 2216 Parser.Lex(); 2217 // If this is not the end of the statement, report an error. 2218 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2219 reportParseError("`noreorder' must be set before `nomacro'"); 2220 return false; 2221 } 2222 if (Options.isReorder()) { 2223 reportParseError("`noreorder' must be set before `nomacro'"); 2224 return false; 2225 } 2226 Options.setNomacro(); 2227 Parser.Lex(); // Consume the EndOfStatement. 2228 return false; 2229} 2230 2231bool MipsAsmParser::parseSetAssignment() { 2232 StringRef Name; 2233 const MCExpr *Value; 2234 2235 if (Parser.parseIdentifier(Name)) 2236 reportParseError("expected identifier after .set"); 2237 2238 if (getLexer().isNot(AsmToken::Comma)) 2239 return reportParseError("unexpected token in .set directive"); 2240 Lex(); // Eat comma 2241 2242 if (getLexer().is(AsmToken::Dollar)) { 2243 MCSymbol *Symbol; 2244 SMLoc DollarLoc = getLexer().getLoc(); 2245 // Consume the dollar sign, and check for a following identifier. 2246 Parser.Lex(); 2247 // We have a '$' followed by something, make sure they are adjacent. 2248 if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer()) 2249 return true; 2250 StringRef Res = 2251 StringRef(DollarLoc.getPointer(), 2252 getTok().getEndLoc().getPointer() - DollarLoc.getPointer()); 2253 Symbol = getContext().GetOrCreateSymbol(Res); 2254 Parser.Lex(); 2255 Value = 2256 MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, getContext()); 2257 } else if (Parser.parseExpression(Value)) 2258 return reportParseError("expected valid expression after comma"); 2259 2260 // Check if the Name already exists as a symbol. 2261 MCSymbol *Sym = getContext().LookupSymbol(Name); 2262 if (Sym) 2263 return reportParseError("symbol already defined"); 2264 Sym = getContext().GetOrCreateSymbol(Name); 2265 Sym->setVariableValue(Value); 2266 2267 return false; 2268} 2269 2270bool MipsAsmParser::parseDirectiveSet() { 2271 2272 // Get the next token. 2273 const AsmToken &Tok = Parser.getTok(); 2274 2275 if (Tok.getString() == "noat") { 2276 return parseSetNoAtDirective(); 2277 } else if (Tok.getString() == "at") { 2278 return parseSetAtDirective(); 2279 } else if (Tok.getString() == "reorder") { 2280 return parseSetReorderDirective(); 2281 } else if (Tok.getString() == "noreorder") { 2282 return parseSetNoReorderDirective(); 2283 } else if (Tok.getString() == "macro") { 2284 return parseSetMacroDirective(); 2285 } else if (Tok.getString() == "nomacro") { 2286 return parseSetNoMacroDirective(); 2287 } else if (Tok.getString() == "nomips16") { 2288 // Ignore this directive for now. 2289 Parser.eatToEndOfStatement(); 2290 return false; 2291 } else if (Tok.getString() == "nomicromips") { 2292 // Ignore this directive for now. 2293 Parser.eatToEndOfStatement(); 2294 return false; 2295 } else { 2296 // It is just an identifier, look for an assignment. 2297 parseSetAssignment(); 2298 return false; 2299 } 2300 2301 return true; 2302} 2303 2304bool MipsAsmParser::parseDirectiveMipsHackStocg() { 2305 MCAsmParser &Parser = getParser(); 2306 StringRef Name; 2307 if (Parser.parseIdentifier(Name)) 2308 reportParseError("expected identifier"); 2309 2310 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name); 2311 if (getLexer().isNot(AsmToken::Comma)) 2312 return TokError("unexpected token"); 2313 Lex(); 2314 2315 int64_t Flags = 0; 2316 if (Parser.parseAbsoluteExpression(Flags)) 2317 return TokError("unexpected token"); 2318 2319 getTargetStreamer().emitMipsHackSTOCG(Sym, Flags); 2320 return false; 2321} 2322 2323bool MipsAsmParser::parseDirectiveMipsHackELFFlags() { 2324 int64_t Flags = 0; 2325 if (Parser.parseAbsoluteExpression(Flags)) 2326 return TokError("unexpected token"); 2327 2328 getTargetStreamer().emitMipsHackELFFlags(Flags); 2329 return false; 2330} 2331 2332/// parseDirectiveWord 2333/// ::= .word [ expression (, expression)* ] 2334bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) { 2335 if (getLexer().isNot(AsmToken::EndOfStatement)) { 2336 for (;;) { 2337 const MCExpr *Value; 2338 if (getParser().parseExpression(Value)) 2339 return true; 2340 2341 getParser().getStreamer().EmitValue(Value, Size); 2342 2343 if (getLexer().is(AsmToken::EndOfStatement)) 2344 break; 2345 2346 // FIXME: Improve diagnostic. 2347 if (getLexer().isNot(AsmToken::Comma)) 2348 return Error(L, "unexpected token in directive"); 2349 Parser.Lex(); 2350 } 2351 } 2352 2353 Parser.Lex(); 2354 return false; 2355} 2356 2357/// parseDirectiveGpWord 2358/// ::= .gpword local_sym 2359bool MipsAsmParser::parseDirectiveGpWord() { 2360 const MCExpr *Value; 2361 // EmitGPRel32Value requires an expression, so we are using base class 2362 // method to evaluate the expression. 2363 if (getParser().parseExpression(Value)) 2364 return true; 2365 2366 getParser().getStreamer().EmitGPRel32Value(Value); 2367 Parser.Lex(); // Eat last token. 2368 2369 if (getLexer().is(AsmToken::EndOfStatement)) 2370 return Error(getLexer().getLoc(), "unexpected token in directive"); 2371 2372 return false; 2373} 2374 2375bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) { 2376 2377 StringRef IDVal = DirectiveID.getString(); 2378 2379 if (IDVal == ".ent") { 2380 // Ignore this directive for now. 2381 Parser.Lex(); 2382 return false; 2383 } 2384 2385 if (IDVal == ".end") { 2386 // Ignore this directive for now. 2387 Parser.Lex(); 2388 return false; 2389 } 2390 2391 if (IDVal == ".frame") { 2392 // Ignore this directive for now. 2393 Parser.eatToEndOfStatement(); 2394 return false; 2395 } 2396 2397 if (IDVal == ".set") { 2398 return parseDirectiveSet(); 2399 } 2400 2401 if (IDVal == ".fmask") { 2402 // Ignore this directive for now. 2403 Parser.eatToEndOfStatement(); 2404 return false; 2405 } 2406 2407 if (IDVal == ".mask") { 2408 // Ignore this directive for now. 2409 Parser.eatToEndOfStatement(); 2410 return false; 2411 } 2412 2413 if (IDVal == ".gpword") { 2414 // Ignore this directive for now. 2415 parseDirectiveGpWord(); 2416 return false; 2417 } 2418 2419 if (IDVal == ".word") { 2420 parseDirectiveWord(4, DirectiveID.getLoc()); 2421 return false; 2422 } 2423 2424 if (IDVal == ".mips_hack_stocg") 2425 return parseDirectiveMipsHackStocg(); 2426 2427 if (IDVal == ".mips_hack_elf_flags") 2428 return parseDirectiveMipsHackELFFlags(); 2429 2430 return true; 2431} 2432 2433extern "C" void LLVMInitializeMipsAsmParser() { 2434 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget); 2435 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget); 2436 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target); 2437 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget); 2438} 2439 2440#define GET_REGISTER_MATCHER 2441#define GET_MATCHER_IMPLEMENTATION 2442#include "MipsGenAsmMatcher.inc" 2443