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