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