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