1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(const FeatureBitset &Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 const FeatureBitset &getFeatures() const { return Features; }
74 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const FeatureBitset AllArchRelatedMask;
87 FeatureBitset Features;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
118 // Print a warning along with its fix-it message at the given range.
119 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
120 SMRange Range, bool ShowColors = true);
122 #define GET_ASSEMBLER_HEADER
123 #include "MipsGenAsmMatcher.inc"
125 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
127 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
128 OperandVector &Operands, MCStreamer &Out,
130 FeatureBitset &ErrorMissingFeature,
131 bool MatchingInlineAsm) override;
133 /// Parse a register as used in CFI directives
134 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
136 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
138 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
140 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
141 SMLoc NameLoc, OperandVector &Operands) override;
143 bool ParseDirective(AsmToken DirectiveID) override;
145 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy
148 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
149 StringRef Identifier, SMLoc S);
151 MipsAsmParser::OperandMatchResultTy
152 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
154 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
164 MipsAsmParser::OperandMatchResultTy
165 parseRegisterPair (OperandVector &Operands);
167 MipsAsmParser::OperandMatchResultTy
168 parseMovePRegPair(OperandVector &Operands);
170 MipsAsmParser::OperandMatchResultTy
171 parseRegisterList (OperandVector &Operands);
173 bool searchSymbolAlias(OperandVector &Operands);
175 bool parseOperand(OperandVector &, StringRef Mnemonic);
177 bool needsExpansion(MCInst &Inst);
179 // Expands assembly pseudo instructions.
180 // Returns false on success, true otherwise.
181 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
182 SmallVectorImpl<MCInst> &Instructions);
184 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
185 SmallVectorImpl<MCInst> &Instructions);
187 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
188 bool Is32BitImm, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
191 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
192 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
193 SmallVectorImpl<MCInst> &Instructions);
195 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
198 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
199 SmallVectorImpl<MCInst> &Instructions);
201 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
203 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
210 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
211 SmallVectorImpl<MCInst> &Instructions);
213 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
214 SmallVectorImpl<MCInst> &Instructions);
216 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
217 SmallVectorImpl<MCInst> &Instructions);
219 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
220 SmallVectorImpl<MCInst> &Instructions);
222 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
223 SmallVectorImpl<MCInst> &Instructions);
225 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
226 SmallVectorImpl<MCInst> &Instructions);
228 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
229 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
231 bool reportParseError(Twine ErrorMsg);
232 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
234 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
235 bool parseRelocOperand(const MCExpr *&Res);
237 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
239 bool isEvaluated(const MCExpr *Expr);
240 bool parseSetMips0Directive();
241 bool parseSetArchDirective();
242 bool parseSetFeature(uint64_t Feature);
243 bool parseDirectiveCpLoad(SMLoc Loc);
244 bool parseDirectiveCPSetup();
245 bool parseDirectiveNaN();
246 bool parseDirectiveSet();
247 bool parseDirectiveOption();
248 bool parseInsnDirective();
250 bool parseSetAtDirective();
251 bool parseSetNoAtDirective();
252 bool parseSetMacroDirective();
253 bool parseSetNoMacroDirective();
254 bool parseSetMsaDirective();
255 bool parseSetNoMsaDirective();
256 bool parseSetNoDspDirective();
257 bool parseSetReorderDirective();
258 bool parseSetNoReorderDirective();
259 bool parseSetMips16Directive();
260 bool parseSetNoMips16Directive();
261 bool parseSetFpDirective();
262 bool parseSetOddSPRegDirective();
263 bool parseSetNoOddSPRegDirective();
264 bool parseSetPopDirective();
265 bool parseSetPushDirective();
266 bool parseSetSoftFloatDirective();
267 bool parseSetHardFloatDirective();
269 bool parseSetAssignment();
271 bool parseDataDirective(unsigned Size, SMLoc L);
272 bool parseDirectiveGpWord();
273 bool parseDirectiveGpDWord();
274 bool parseDirectiveModule();
275 bool parseDirectiveModuleFP();
276 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
277 StringRef Directive);
279 bool parseInternalDirectiveReallowModule();
281 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
283 bool eatComma(StringRef ErrorStr);
285 int matchCPURegisterName(StringRef Symbol);
287 int matchHWRegsRegisterName(StringRef Symbol);
289 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
291 int matchFPURegisterName(StringRef Name);
293 int matchFCCRegisterName(StringRef Name);
295 int matchACRegisterName(StringRef Name);
297 int matchMSA128RegisterName(StringRef Name);
299 int matchMSA128CtrlRegisterName(StringRef Name);
301 unsigned getReg(int RC, int RegNo);
303 unsigned getGPR(int RegNo);
305 /// Returns the internal register number for the current AT. Also checks if
306 /// the current AT is unavailable (set to $0) and gives an error if it is.
307 /// This should be used in pseudo-instruction expansions which need AT.
308 unsigned getATReg(SMLoc Loc);
310 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
311 SmallVectorImpl<MCInst> &Instructions);
313 // Helper function that checks if the value of a vector index is within the
314 // boundaries of accepted values for each RegisterKind
315 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
316 bool validateMSAIndex(int Val, int RegKind);
318 // Selects a new architecture by updating the FeatureBits with the necessary
319 // info including implied dependencies.
320 // Internally, it clears all the feature bits related to *any* architecture
321 // and selects the new one using the ToggleFeature functionality of the
322 // MCSubtargetInfo object that handles implied dependencies. The reason we
323 // clear all the arch related bits manually is because ToggleFeature only
324 // clears the features that imply the feature being cleared and not the
325 // features implied by the feature being cleared. This is easier to see
327 // --------------------------------------------------
328 // | Feature | Implies |
329 // | -------------------------------------------------|
330 // | FeatureMips1 | None |
331 // | FeatureMips2 | FeatureMips1 |
332 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
333 // | FeatureMips4 | FeatureMips3 |
335 // --------------------------------------------------
337 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
338 // FeatureMipsGP64 | FeatureMips1)
339 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
340 void selectArch(StringRef ArchFeature) {
341 FeatureBitset FeatureBits = STI.getFeatureBits();
342 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
343 STI.setFeatureBits(FeatureBits);
344 setAvailableFeatures(
345 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
346 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
349 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
350 if (!(STI.getFeatureBits()[Feature])) {
351 setAvailableFeatures(
352 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
353 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
357 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
358 if (STI.getFeatureBits()[Feature]) {
359 setAvailableFeatures(
360 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
361 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
366 enum MipsMatchResultTy {
367 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
368 #define GET_OPERAND_DIAGNOSTIC_TYPES
369 #include "MipsGenAsmMatcher.inc"
370 #undef GET_OPERAND_DIAGNOSTIC_TYPES
374 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
375 const MCInstrInfo &MII, const MCTargetOptions &Options)
376 : MCTargetAsmParser(), STI(sti),
377 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
378 sti.getCPU(), Options)) {
379 MCAsmParserExtension::Initialize(parser);
381 parser.addAliasForDirective(".asciiz", ".asciz");
383 // Initialize the set of available features.
384 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
386 // Remember the initial assembler options. The user can not modify these.
387 AssemblerOptions.push_back(
388 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
390 // Create an assembler options environment for the user to modify.
391 AssemblerOptions.push_back(
392 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
394 getTargetStreamer().updateABIInfo(*this);
396 if (!isABI_O32() && !useOddSPReg() != 0)
397 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
401 Triple TheTriple(sti.getTargetTriple());
402 if ((TheTriple.getArch() == Triple::mips) ||
403 (TheTriple.getArch() == Triple::mips64))
404 IsLittleEndian = false;
406 IsLittleEndian = true;
409 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
410 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
412 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
413 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
414 const MipsABIInfo &getABI() const { return ABI; }
415 bool isABI_N32() const { return ABI.IsN32(); }
416 bool isABI_N64() const { return ABI.IsN64(); }
417 bool isABI_O32() const { return ABI.IsO32(); }
418 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
420 bool useOddSPReg() const {
421 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
424 bool inMicroMipsMode() const {
425 return STI.getFeatureBits()[Mips::FeatureMicroMips];
427 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
428 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
429 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
430 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
431 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
432 bool hasMips32() const {
433 return STI.getFeatureBits()[Mips::FeatureMips32];
435 bool hasMips64() const {
436 return STI.getFeatureBits()[Mips::FeatureMips64];
438 bool hasMips32r2() const {
439 return STI.getFeatureBits()[Mips::FeatureMips32r2];
441 bool hasMips64r2() const {
442 return STI.getFeatureBits()[Mips::FeatureMips64r2];
444 bool hasMips32r3() const {
445 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
447 bool hasMips64r3() const {
448 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
450 bool hasMips32r5() const {
451 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
453 bool hasMips64r5() const {
454 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
456 bool hasMips32r6() const {
457 return STI.getFeatureBits()[Mips::FeatureMips32r6];
459 bool hasMips64r6() const {
460 return STI.getFeatureBits()[Mips::FeatureMips64r6];
463 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
464 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
465 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
466 bool hasCnMips() const {
467 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
470 bool inMips16Mode() const {
471 return STI.getFeatureBits()[Mips::FeatureMips16];
474 bool useSoftFloat() const {
475 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
478 /// Warn if RegIndex is the same as the current AT.
479 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
481 void warnIfNoMacro(SMLoc Loc);
483 bool isLittle() const { return IsLittleEndian; }
489 /// MipsOperand - Instances of this class represent a parsed Mips machine
491 class MipsOperand : public MCParsedAsmOperand {
493 /// Broad categories of register classes
494 /// The exact class is finalized by the render method.
496 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
497 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
499 RegKind_FCC = 4, /// FCC
500 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
501 RegKind_MSACtrl = 16, /// MSA control registers
502 RegKind_COP2 = 32, /// COP2
503 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
505 RegKind_CCR = 128, /// CCR
506 RegKind_HWRegs = 256, /// HWRegs
507 RegKind_COP3 = 512, /// COP3
508 RegKind_COP0 = 1024, /// COP0
509 /// Potentially any (e.g. $1)
510 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
511 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
512 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
517 k_Immediate, /// An immediate (possibly involving symbol references)
518 k_Memory, /// Base + Offset Memory Address
519 k_PhysRegister, /// A physical register from the Mips namespace
520 k_RegisterIndex, /// A register index in one or more RegKind.
521 k_Token, /// A simple token
522 k_RegList, /// A physical register list
523 k_RegPair /// A pair of physical register
527 MipsOperand(KindTy K, MipsAsmParser &Parser)
528 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
531 /// For diagnostics, and checking the assembler temporary
532 MipsAsmParser &AsmParser;
540 unsigned Num; /// Register Number
544 unsigned Index; /// Index into the register class
545 RegKind Kind; /// Bitfield of the kinds it could possibly be
546 const MCRegisterInfo *RegInfo;
559 SmallVector<unsigned, 10> *List;
564 struct PhysRegOp PhysReg;
565 struct RegIdxOp RegIdx;
568 struct RegListOp RegList;
571 SMLoc StartLoc, EndLoc;
573 /// Internal constructor for register kinds
574 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
575 const MCRegisterInfo *RegInfo,
577 MipsAsmParser &Parser) {
578 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
579 Op->RegIdx.Index = Index;
580 Op->RegIdx.RegInfo = RegInfo;
581 Op->RegIdx.Kind = RegKind;
588 /// Coerce the register to GPR32 and return the real register for the current
590 unsigned getGPR32Reg() const {
591 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
592 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
593 unsigned ClassID = Mips::GPR32RegClassID;
594 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
597 /// Coerce the register to GPR32 and return the real register for the current
599 unsigned getGPRMM16Reg() const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
601 unsigned ClassID = Mips::GPR32RegClassID;
602 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
605 /// Coerce the register to GPR64 and return the real register for the current
607 unsigned getGPR64Reg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
609 unsigned ClassID = Mips::GPR64RegClassID;
610 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
614 /// Coerce the register to AFGR64 and return the real register for the current
616 unsigned getAFGR64Reg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
618 if (RegIdx.Index % 2 != 0)
619 AsmParser.Warning(StartLoc, "Float register should be even.");
620 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
621 .getRegister(RegIdx.Index / 2);
624 /// Coerce the register to FGR64 and return the real register for the current
626 unsigned getFGR64Reg() const {
627 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
628 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
629 .getRegister(RegIdx.Index);
632 /// Coerce the register to FGR32 and return the real register for the current
634 unsigned getFGR32Reg() const {
635 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
636 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
637 .getRegister(RegIdx.Index);
640 /// Coerce the register to FGRH32 and return the real register for the current
642 unsigned getFGRH32Reg() const {
643 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
644 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
645 .getRegister(RegIdx.Index);
648 /// Coerce the register to FCC and return the real register for the current
650 unsigned getFCCReg() const {
651 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
652 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
653 .getRegister(RegIdx.Index);
656 /// Coerce the register to MSA128 and return the real register for the current
658 unsigned getMSA128Reg() const {
659 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
660 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
662 unsigned ClassID = Mips::MSA128BRegClassID;
663 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
666 /// Coerce the register to MSACtrl and return the real register for the
668 unsigned getMSACtrlReg() const {
669 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
670 unsigned ClassID = Mips::MSACtrlRegClassID;
671 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
674 /// Coerce the register to COP0 and return the real register for the
676 unsigned getCOP0Reg() const {
677 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
678 unsigned ClassID = Mips::COP0RegClassID;
679 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
682 /// Coerce the register to COP2 and return the real register for the
684 unsigned getCOP2Reg() const {
685 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
686 unsigned ClassID = Mips::COP2RegClassID;
687 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
690 /// Coerce the register to COP3 and return the real register for the
692 unsigned getCOP3Reg() const {
693 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
694 unsigned ClassID = Mips::COP3RegClassID;
695 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
698 /// Coerce the register to ACC64DSP and return the real register for the
700 unsigned getACC64DSPReg() const {
701 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
702 unsigned ClassID = Mips::ACC64DSPRegClassID;
703 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
706 /// Coerce the register to HI32DSP and return the real register for the
708 unsigned getHI32DSPReg() const {
709 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
710 unsigned ClassID = Mips::HI32DSPRegClassID;
711 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
714 /// Coerce the register to LO32DSP and return the real register for the
716 unsigned getLO32DSPReg() const {
717 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
718 unsigned ClassID = Mips::LO32DSPRegClassID;
719 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
722 /// Coerce the register to CCR and return the real register for the
724 unsigned getCCRReg() const {
725 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
726 unsigned ClassID = Mips::CCRRegClassID;
727 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
730 /// Coerce the register to HWRegs and return the real register for the
732 unsigned getHWRegsReg() const {
733 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
734 unsigned ClassID = Mips::HWRegsRegClassID;
735 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
740 // Add as immediate when possible. Null MCExpr = 0.
742 Inst.addOperand(MCOperand::createImm(0));
743 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
744 Inst.addOperand(MCOperand::createImm(CE->getValue()));
746 Inst.addOperand(MCOperand::createExpr(Expr));
749 void addRegOperands(MCInst &Inst, unsigned N) const {
750 llvm_unreachable("Use a custom parser instead");
753 /// Render the operand to an MCInst as a GPR32
754 /// Asserts if the wrong number of operands are requested, or the operand
755 /// is not a k_RegisterIndex compatible with RegKind_GPR
756 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
757 assert(N == 1 && "Invalid number of operands!");
758 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
761 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
762 assert(N == 1 && "Invalid number of operands!");
763 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
766 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
767 assert(N == 1 && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
771 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
772 assert(N == 1 && "Invalid number of operands!");
773 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
776 /// Render the operand to an MCInst as a GPR64
777 /// Asserts if the wrong number of operands are requested, or the operand
778 /// is not a k_RegisterIndex compatible with RegKind_GPR
779 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
784 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
785 assert(N == 1 && "Invalid number of operands!");
786 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
789 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
794 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
797 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
798 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
799 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
803 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
804 assert(N == 1 && "Invalid number of operands!");
805 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
808 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::createReg(getFCCReg()));
813 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
818 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
819 assert(N == 1 && "Invalid number of operands!");
820 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
823 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
825 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
828 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
830 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
833 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
834 assert(N == 1 && "Invalid number of operands!");
835 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
838 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 1 && "Invalid number of operands!");
840 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
843 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 1 && "Invalid number of operands!");
845 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
848 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
849 assert(N == 1 && "Invalid number of operands!");
850 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
853 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
854 assert(N == 1 && "Invalid number of operands!");
855 Inst.addOperand(MCOperand::createReg(getCCRReg()));
858 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
859 assert(N == 1 && "Invalid number of operands!");
860 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
863 void addImmOperands(MCInst &Inst, unsigned N) const {
864 assert(N == 1 && "Invalid number of operands!");
865 const MCExpr *Expr = getImm();
869 void addMemOperands(MCInst &Inst, unsigned N) const {
870 assert(N == 2 && "Invalid number of operands!");
872 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
874 const MCExpr *Expr = getMemOff();
878 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
879 assert(N == 2 && "Invalid number of operands!");
881 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
883 const MCExpr *Expr = getMemOff();
887 void addRegListOperands(MCInst &Inst, unsigned N) const {
888 assert(N == 1 && "Invalid number of operands!");
890 for (auto RegNo : getRegList())
891 Inst.addOperand(MCOperand::createReg(RegNo));
894 void addRegPairOperands(MCInst &Inst, unsigned N) const {
895 assert(N == 2 && "Invalid number of operands!");
896 unsigned RegNo = getRegPair();
897 Inst.addOperand(MCOperand::createReg(RegNo++));
898 Inst.addOperand(MCOperand::createReg(RegNo));
901 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
902 assert(N == 2 && "Invalid number of operands!");
903 for (auto RegNo : getRegList())
904 Inst.addOperand(MCOperand::createReg(RegNo));
907 bool isReg() const override {
908 // As a special case until we sort out the definition of div/divu, pretend
909 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
910 if (isGPRAsmReg() && RegIdx.Index == 0)
913 return Kind == k_PhysRegister;
915 bool isRegIdx() const { return Kind == k_RegisterIndex; }
916 bool isImm() const override { return Kind == k_Immediate; }
917 bool isConstantImm() const {
918 return isImm() && dyn_cast<MCConstantExpr>(getImm());
920 template <unsigned Bits> bool isUImm() const {
921 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
923 bool isToken() const override {
924 // Note: It's not possible to pretend that other operand kinds are tokens.
925 // The matcher emitter checks tokens first.
926 return Kind == k_Token;
928 bool isMem() const override { return Kind == k_Memory; }
929 bool isConstantMemOff() const {
930 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
932 template <unsigned Bits> bool isMemWithSimmOffset() const {
933 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
935 bool isMemWithGRPMM16Base() const {
936 return isMem() && getMemBase()->isMM16AsmReg();
938 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
939 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
940 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
942 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
943 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
944 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
945 && (getMemBase()->getGPR32Reg() == Mips::SP);
947 bool isRegList16() const {
951 int Size = RegList.List->size();
952 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
953 RegList.List->back() != Mips::RA)
956 int PrevReg = *RegList.List->begin();
957 for (int i = 1; i < Size - 1; i++) {
958 int Reg = (*(RegList.List))[i];
959 if ( Reg != PrevReg + 1)
966 bool isInvNum() const { return Kind == k_Immediate; }
967 bool isLSAImm() const {
968 if (!isConstantImm())
970 int64_t Val = getConstantImm();
971 return 1 <= Val && Val <= 4;
973 bool isRegList() const { return Kind == k_RegList; }
974 bool isMovePRegPair() const {
975 if (Kind != k_RegList || RegList.List->size() != 2)
978 unsigned R0 = RegList.List->front();
979 unsigned R1 = RegList.List->back();
981 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
982 (R0 == Mips::A1 && R1 == Mips::A3) ||
983 (R0 == Mips::A2 && R1 == Mips::A3) ||
984 (R0 == Mips::A0 && R1 == Mips::S5) ||
985 (R0 == Mips::A0 && R1 == Mips::S6) ||
986 (R0 == Mips::A0 && R1 == Mips::A1) ||
987 (R0 == Mips::A0 && R1 == Mips::A2) ||
988 (R0 == Mips::A0 && R1 == Mips::A3))
994 StringRef getToken() const {
995 assert(Kind == k_Token && "Invalid access!");
996 return StringRef(Tok.Data, Tok.Length);
998 bool isRegPair() const { return Kind == k_RegPair; }
1000 unsigned getReg() const override {
1001 // As a special case until we sort out the definition of div/divu, pretend
1002 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1003 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1004 RegIdx.Kind & RegKind_GPR)
1005 return getGPR32Reg(); // FIXME: GPR64 too
1007 assert(Kind == k_PhysRegister && "Invalid access!");
1011 const MCExpr *getImm() const {
1012 assert((Kind == k_Immediate) && "Invalid access!");
1016 int64_t getConstantImm() const {
1017 const MCExpr *Val = getImm();
1018 return static_cast<const MCConstantExpr *>(Val)->getValue();
1021 MipsOperand *getMemBase() const {
1022 assert((Kind == k_Memory) && "Invalid access!");
1026 const MCExpr *getMemOff() const {
1027 assert((Kind == k_Memory) && "Invalid access!");
1031 int64_t getConstantMemOff() const {
1032 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1035 const SmallVectorImpl<unsigned> &getRegList() const {
1036 assert((Kind == k_RegList) && "Invalid access!");
1037 return *(RegList.List);
1040 unsigned getRegPair() const {
1041 assert((Kind == k_RegPair) && "Invalid access!");
1042 return RegIdx.Index;
1045 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1046 MipsAsmParser &Parser) {
1047 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1048 Op->Tok.Data = Str.data();
1049 Op->Tok.Length = Str.size();
1055 /// Create a numeric register (e.g. $1). The exact register remains
1056 /// unresolved until an instruction successfully matches
1057 static std::unique_ptr<MipsOperand>
1058 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1059 SMLoc E, MipsAsmParser &Parser) {
1060 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1061 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1064 /// Create a register that is definitely a GPR.
1065 /// This is typically only used for named registers such as $gp.
1066 static std::unique_ptr<MipsOperand>
1067 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1068 MipsAsmParser &Parser) {
1069 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1072 /// Create a register that is definitely a FGR.
1073 /// This is typically only used for named registers such as $f0.
1074 static std::unique_ptr<MipsOperand>
1075 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1076 MipsAsmParser &Parser) {
1077 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1080 /// Create a register that is definitely a HWReg.
1081 /// This is typically only used for named registers such as $hwr_cpunum.
1082 static std::unique_ptr<MipsOperand>
1083 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1084 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1085 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1088 /// Create a register that is definitely an FCC.
1089 /// This is typically only used for named registers such as $fcc0.
1090 static std::unique_ptr<MipsOperand>
1091 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1092 MipsAsmParser &Parser) {
1093 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1096 /// Create a register that is definitely an ACC.
1097 /// This is typically only used for named registers such as $ac0.
1098 static std::unique_ptr<MipsOperand>
1099 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1100 MipsAsmParser &Parser) {
1101 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1104 /// Create a register that is definitely an MSA128.
1105 /// This is typically only used for named registers such as $w0.
1106 static std::unique_ptr<MipsOperand>
1107 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1108 SMLoc E, MipsAsmParser &Parser) {
1109 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1112 /// Create a register that is definitely an MSACtrl.
1113 /// This is typically only used for named registers such as $msaaccess.
1114 static std::unique_ptr<MipsOperand>
1115 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1116 SMLoc E, MipsAsmParser &Parser) {
1117 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1120 static std::unique_ptr<MipsOperand>
1121 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1122 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1129 static std::unique_ptr<MipsOperand>
1130 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1131 SMLoc E, MipsAsmParser &Parser) {
1132 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1133 Op->Mem.Base = Base.release();
1140 static std::unique_ptr<MipsOperand>
1141 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1142 MipsAsmParser &Parser) {
1143 assert (Regs.size() > 0 && "Empty list not allowed");
1145 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1146 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1147 Op->StartLoc = StartLoc;
1148 Op->EndLoc = EndLoc;
1152 static std::unique_ptr<MipsOperand>
1153 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1154 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1155 Op->RegIdx.Index = RegNo;
1161 bool isGPRAsmReg() const {
1162 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1164 bool isMM16AsmReg() const {
1165 if (!(isRegIdx() && RegIdx.Kind))
1167 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1168 || RegIdx.Index == 16 || RegIdx.Index == 17);
1170 bool isMM16AsmRegZero() const {
1171 if (!(isRegIdx() && RegIdx.Kind))
1173 return (RegIdx.Index == 0 ||
1174 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1175 RegIdx.Index == 17);
1177 bool isMM16AsmRegMoveP() const {
1178 if (!(isRegIdx() && RegIdx.Kind))
1180 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1181 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1183 bool isFGRAsmReg() const {
1184 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1185 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1187 bool isHWRegsAsmReg() const {
1188 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1190 bool isCCRAsmReg() const {
1191 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1193 bool isFCCAsmReg() const {
1194 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1196 if (!AsmParser.hasEightFccRegisters())
1197 return RegIdx.Index == 0;
1198 return RegIdx.Index <= 7;
1200 bool isACCAsmReg() const {
1201 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1203 bool isCOP0AsmReg() const {
1204 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1206 bool isCOP2AsmReg() const {
1207 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1209 bool isCOP3AsmReg() const {
1210 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1212 bool isMSA128AsmReg() const {
1213 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1215 bool isMSACtrlAsmReg() const {
1216 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1219 /// getStartLoc - Get the location of the first token of this operand.
1220 SMLoc getStartLoc() const override { return StartLoc; }
1221 /// getEndLoc - Get the location of the last token of this operand.
1222 SMLoc getEndLoc() const override { return EndLoc; }
1224 virtual ~MipsOperand() {
1232 delete RegList.List;
1233 case k_PhysRegister:
1234 case k_RegisterIndex:
1241 void print(raw_ostream &OS) const override {
1250 Mem.Base->print(OS);
1255 case k_PhysRegister:
1256 OS << "PhysReg<" << PhysReg.Num << ">";
1258 case k_RegisterIndex:
1259 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1266 for (auto Reg : (*RegList.List))
1271 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1275 }; // class MipsOperand
1279 extern const MCInstrDesc MipsInsts[];
1281 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1282 return MipsInsts[Opcode];
1285 static bool hasShortDelaySlot(unsigned Opcode) {
1288 case Mips::JALRS_MM:
1289 case Mips::JALRS16_MM:
1290 case Mips::BGEZALS_MM:
1291 case Mips::BLTZALS_MM:
1298 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1299 SmallVectorImpl<MCInst> &Instructions) {
1300 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1304 if (MCID.isBranch() || MCID.isCall()) {
1305 const unsigned Opcode = Inst.getOpcode();
1315 assert(hasCnMips() && "instruction only valid for octeon cpus");
1322 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1323 Offset = Inst.getOperand(2);
1324 if (!Offset.isImm())
1325 break; // We'll deal with this situation later on when applying fixups.
1326 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1327 return Error(IDLoc, "branch target out of range");
1328 if (OffsetToAlignment(Offset.getImm(),
1329 1LL << (inMicroMipsMode() ? 1 : 2)))
1330 return Error(IDLoc, "branch to misaligned address");
1344 case Mips::BGEZAL_MM:
1345 case Mips::BLTZAL_MM:
1348 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1349 Offset = Inst.getOperand(1);
1350 if (!Offset.isImm())
1351 break; // We'll deal with this situation later on when applying fixups.
1352 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1353 return Error(IDLoc, "branch target out of range");
1354 if (OffsetToAlignment(Offset.getImm(),
1355 1LL << (inMicroMipsMode() ? 1 : 2)))
1356 return Error(IDLoc, "branch to misaligned address");
1358 case Mips::BEQZ16_MM:
1359 case Mips::BNEZ16_MM:
1360 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1361 Offset = Inst.getOperand(1);
1362 if (!Offset.isImm())
1363 break; // We'll deal with this situation later on when applying fixups.
1364 if (!isIntN(8, Offset.getImm()))
1365 return Error(IDLoc, "branch target out of range");
1366 if (OffsetToAlignment(Offset.getImm(), 2LL))
1367 return Error(IDLoc, "branch to misaligned address");
1372 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1373 // We still accept it but it is a normal nop.
1374 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1375 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1376 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1381 const unsigned Opcode = Inst.getOpcode();
1393 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1394 // The offset is handled above
1395 Opnd = Inst.getOperand(1);
1397 return Error(IDLoc, "expected immediate operand kind");
1398 Imm = Opnd.getImm();
1399 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1400 Opcode == Mips::BBIT1 ? 63 : 31))
1401 return Error(IDLoc, "immediate operand value out of range");
1403 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1405 Inst.getOperand(1).setImm(Imm - 32);
1413 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1415 Opnd = Inst.getOperand(3);
1417 return Error(IDLoc, "expected immediate operand kind");
1418 Imm = Opnd.getImm();
1419 if (Imm < 0 || Imm > 31)
1420 return Error(IDLoc, "immediate operand value out of range");
1422 Opnd = Inst.getOperand(2);
1424 return Error(IDLoc, "expected immediate operand kind");
1425 Imm = Opnd.getImm();
1426 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1427 Opcode == Mips::EXTS ? 63 : 31))
1428 return Error(IDLoc, "immediate operand value out of range");
1430 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1431 Inst.getOperand(2).setImm(Imm - 32);
1437 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1438 Opnd = Inst.getOperand(2);
1440 return Error(IDLoc, "expected immediate operand kind");
1441 Imm = Opnd.getImm();
1442 if (!isInt<10>(Imm))
1443 return Error(IDLoc, "immediate operand value out of range");
1448 if (MCID.mayLoad() || MCID.mayStore()) {
1449 // Check the offset of memory operand, if it is a symbol
1450 // reference or immediate we may have to expand instructions.
1451 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1452 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1453 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1454 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1455 MCOperand &Op = Inst.getOperand(i);
1457 int MemOffset = Op.getImm();
1458 if (MemOffset < -32768 || MemOffset > 32767) {
1459 // Offset can't exceed 16bit value.
1460 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1463 } else if (Op.isExpr()) {
1464 const MCExpr *Expr = Op.getExpr();
1465 if (Expr->getKind() == MCExpr::SymbolRef) {
1466 const MCSymbolRefExpr *SR =
1467 static_cast<const MCSymbolRefExpr *>(Expr);
1468 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1470 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1473 } else if (!isEvaluated(Expr)) {
1474 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1482 if (inMicroMipsMode()) {
1483 if (MCID.mayLoad()) {
1484 // Try to create 16-bit GP relative load instruction.
1485 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1486 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1487 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1488 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1489 MCOperand &Op = Inst.getOperand(i);
1491 int MemOffset = Op.getImm();
1492 MCOperand &DstReg = Inst.getOperand(0);
1493 MCOperand &BaseReg = Inst.getOperand(1);
1494 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1495 getContext().getRegisterInfo()->getRegClass(
1496 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1497 BaseReg.getReg() == Mips::GP) {
1499 TmpInst.setLoc(IDLoc);
1500 TmpInst.setOpcode(Mips::LWGP_MM);
1501 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1502 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1503 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1504 Instructions.push_back(TmpInst);
1512 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1517 switch (Inst.getOpcode()) {
1520 case Mips::ADDIUS5_MM:
1521 Opnd = Inst.getOperand(2);
1523 return Error(IDLoc, "expected immediate operand kind");
1524 Imm = Opnd.getImm();
1525 if (Imm < -8 || Imm > 7)
1526 return Error(IDLoc, "immediate operand value out of range");
1528 case Mips::ADDIUSP_MM:
1529 Opnd = Inst.getOperand(0);
1531 return Error(IDLoc, "expected immediate operand kind");
1532 Imm = Opnd.getImm();
1533 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1535 return Error(IDLoc, "immediate operand value out of range");
1537 case Mips::SLL16_MM:
1538 case Mips::SRL16_MM:
1539 Opnd = Inst.getOperand(2);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (Imm < 1 || Imm > 8)
1544 return Error(IDLoc, "immediate operand value out of range");
1547 Opnd = Inst.getOperand(1);
1549 return Error(IDLoc, "expected immediate operand kind");
1550 Imm = Opnd.getImm();
1551 if (Imm < -1 || Imm > 126)
1552 return Error(IDLoc, "immediate operand value out of range");
1554 case Mips::ADDIUR2_MM:
1555 Opnd = Inst.getOperand(2);
1557 return Error(IDLoc, "expected immediate operand kind");
1558 Imm = Opnd.getImm();
1559 if (!(Imm == 1 || Imm == -1 ||
1560 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1561 return Error(IDLoc, "immediate operand value out of range");
1563 case Mips::ADDIUR1SP_MM:
1564 Opnd = Inst.getOperand(1);
1566 return Error(IDLoc, "expected immediate operand kind");
1567 Imm = Opnd.getImm();
1568 if (OffsetToAlignment(Imm, 4LL))
1569 return Error(IDLoc, "misaligned immediate operand value");
1570 if (Imm < 0 || Imm > 255)
1571 return Error(IDLoc, "immediate operand value out of range");
1573 case Mips::ANDI16_MM:
1574 Opnd = Inst.getOperand(2);
1576 return Error(IDLoc, "expected immediate operand kind");
1577 Imm = Opnd.getImm();
1578 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1579 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1580 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1581 return Error(IDLoc, "immediate operand value out of range");
1583 case Mips::LBU16_MM:
1584 Opnd = Inst.getOperand(2);
1586 return Error(IDLoc, "expected immediate operand kind");
1587 Imm = Opnd.getImm();
1588 if (Imm < -1 || Imm > 14)
1589 return Error(IDLoc, "immediate operand value out of range");
1592 Opnd = Inst.getOperand(2);
1594 return Error(IDLoc, "expected immediate operand kind");
1595 Imm = Opnd.getImm();
1596 if (Imm < 0 || Imm > 15)
1597 return Error(IDLoc, "immediate operand value out of range");
1599 case Mips::LHU16_MM:
1601 Opnd = Inst.getOperand(2);
1603 return Error(IDLoc, "expected immediate operand kind");
1604 Imm = Opnd.getImm();
1605 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1606 return Error(IDLoc, "immediate operand value out of range");
1610 Opnd = Inst.getOperand(2);
1612 return Error(IDLoc, "expected immediate operand kind");
1613 Imm = Opnd.getImm();
1614 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1615 return Error(IDLoc, "immediate operand value out of range");
1619 Opnd = Inst.getOperand(2);
1621 return Error(IDLoc, "expected immediate operand kind");
1622 Imm = Opnd.getImm();
1623 if (!isUInt<5>(Imm))
1624 return Error(IDLoc, "immediate operand value out of range");
1626 case Mips::ADDIUPC_MM:
1627 MCOperand Opnd = Inst.getOperand(1);
1629 return Error(IDLoc, "expected immediate operand kind");
1630 int Imm = Opnd.getImm();
1631 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1632 return Error(IDLoc, "immediate operand value out of range");
1637 if (needsExpansion(Inst)) {
1638 if (expandInstruction(Inst, IDLoc, Instructions))
1641 Instructions.push_back(Inst);
1643 // If this instruction has a delay slot and .set reorder is active,
1644 // emit a NOP after it.
1645 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1646 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1651 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1653 switch (Inst.getOpcode()) {
1654 case Mips::LoadImm32:
1655 case Mips::LoadImm64:
1656 case Mips::LoadAddrImm32:
1657 case Mips::LoadAddrReg32:
1658 case Mips::B_MM_Pseudo:
1661 case Mips::JalOneReg:
1662 case Mips::JalTwoReg:
1681 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1682 SmallVectorImpl<MCInst> &Instructions) {
1683 switch (Inst.getOpcode()) {
1684 default: llvm_unreachable("unimplemented expansion");
1685 case Mips::LoadImm32:
1686 return expandLoadImm(Inst, true, IDLoc, Instructions);
1687 case Mips::LoadImm64:
1688 return expandLoadImm(Inst, false, IDLoc, Instructions);
1689 case Mips::LoadAddrImm32:
1690 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1691 case Mips::LoadAddrReg32:
1692 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1693 case Mips::B_MM_Pseudo:
1694 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1697 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1698 case Mips::JalOneReg:
1699 case Mips::JalTwoReg:
1700 return expandJalWithRegs(Inst, IDLoc, Instructions);
1703 return expandBranchImm(Inst, IDLoc, Instructions);
1712 return expandCondBranches(Inst, IDLoc, Instructions);
1714 return expandUlhu(Inst, IDLoc, Instructions);
1716 return expandUlw(Inst, IDLoc, Instructions);
1721 template <unsigned ShiftAmount>
1722 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1723 SmallVectorImpl<MCInst> &Instructions) {
1725 if (ShiftAmount >= 32) {
1726 tmpInst.setOpcode(Mips::DSLL32);
1727 tmpInst.addOperand(MCOperand::createReg(RegNo));
1728 tmpInst.addOperand(MCOperand::createReg(RegNo));
1729 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1730 tmpInst.setLoc(IDLoc);
1731 Instructions.push_back(tmpInst);
1733 } else if (ShiftAmount > 0) {
1734 tmpInst.setOpcode(Mips::DSLL);
1735 tmpInst.addOperand(MCOperand::createReg(RegNo));
1736 tmpInst.addOperand(MCOperand::createReg(RegNo));
1737 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1738 tmpInst.setLoc(IDLoc);
1739 Instructions.push_back(tmpInst);
1742 // There's no need for an ORi if the immediate is 0.
1743 if (Operand.isImm() && Operand.getImm() == 0)
1746 tmpInst.setOpcode(Mips::ORi);
1747 tmpInst.addOperand(MCOperand::createReg(RegNo));
1748 tmpInst.addOperand(MCOperand::createReg(RegNo));
1749 tmpInst.addOperand(Operand);
1750 tmpInst.setLoc(IDLoc);
1751 Instructions.push_back(tmpInst);
1754 template <unsigned ShiftAmount>
1755 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1756 SmallVectorImpl<MCInst> &Instructions) {
1757 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1762 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1763 SmallVectorImpl<MCInst> &Instructions) {
1764 // Create a JALR instruction which is going to replace the pseudo-JAL.
1766 JalrInst.setLoc(IDLoc);
1767 const MCOperand FirstRegOp = Inst.getOperand(0);
1768 const unsigned Opcode = Inst.getOpcode();
1770 if (Opcode == Mips::JalOneReg) {
1771 // jal $rs => jalr $rs
1772 if (inMicroMipsMode()) {
1773 JalrInst.setOpcode(Mips::JALR16_MM);
1774 JalrInst.addOperand(FirstRegOp);
1776 JalrInst.setOpcode(Mips::JALR);
1777 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1778 JalrInst.addOperand(FirstRegOp);
1780 } else if (Opcode == Mips::JalTwoReg) {
1781 // jal $rd, $rs => jalr $rd, $rs
1782 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1783 JalrInst.addOperand(FirstRegOp);
1784 const MCOperand SecondRegOp = Inst.getOperand(1);
1785 JalrInst.addOperand(SecondRegOp);
1787 Instructions.push_back(JalrInst);
1789 // If .set reorder is active, emit a NOP after it.
1790 if (AssemblerOptions.back()->isReorder()) {
1791 // This is a 32-bit NOP because these 2 pseudo-instructions
1792 // do not have a short delay slot.
1794 NopInst.setOpcode(Mips::SLL);
1795 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1796 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1797 NopInst.addOperand(MCOperand::createImm(0));
1798 Instructions.push_back(NopInst);
1804 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1805 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1806 SmallVectorImpl<MCInst> &Instructions) {
1807 if (!Is32BitImm && !isGP64bit()) {
1808 Error(IDLoc, "instruction requires a 64-bit architecture");
1812 bool UseSrcReg = false;
1813 if (SrcReg != Mips::NoRegister)
1818 unsigned TmpReg = DstReg;
1819 if (UseSrcReg && (DstReg == SrcReg)) {
1820 // At this point we need AT to perform the expansions and we exit if it is
1822 unsigned ATReg = getATReg(IDLoc);
1828 tmpInst.setLoc(IDLoc);
1829 // FIXME: gas has a special case for values that are 000...1111, which
1830 // becomes a li -1 and then a dsrl
1831 if (0 <= ImmValue && ImmValue <= 65535) {
1832 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1833 // li d,j => ori d,$zero,j
1835 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1836 tmpInst.setOpcode(Mips::ORi);
1837 tmpInst.addOperand(MCOperand::createReg(DstReg));
1838 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1839 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1840 Instructions.push_back(tmpInst);
1841 } else if (ImmValue < 0 && ImmValue >= -32768) {
1842 // For negative signed 16-bit values (-32768 <= j < 0):
1843 // li d,j => addiu d,$zero,j
1845 SrcReg = Mips::ZERO;
1846 tmpInst.setOpcode(Mips::ADDiu);
1847 tmpInst.addOperand(MCOperand::createReg(DstReg));
1848 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1849 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1850 Instructions.push_back(tmpInst);
1851 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1852 warnIfNoMacro(IDLoc);
1854 // For all other values which are representable as a 32-bit integer:
1855 // li d,j => lui d,hi16(j)
1857 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1858 uint16_t Bits15To0 = ImmValue & 0xffff;
1860 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1861 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1863 tmpInst.setOpcode(Mips::ORi);
1864 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1865 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1866 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1867 tmpInst.setLoc(IDLoc);
1868 Instructions.push_back(tmpInst);
1869 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1870 createLShiftOri<16>(0, TmpReg, IDLoc, Instructions);
1872 tmpInst.setOpcode(Mips::LUi);
1873 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1874 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1875 Instructions.push_back(tmpInst);
1877 createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1880 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1882 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1884 Error(IDLoc, "instruction requires a 32-bit immediate");
1887 warnIfNoMacro(IDLoc);
1889 // <------- lo32 ------>
1890 // <------- hi32 ------>
1891 // <- hi16 -> <- lo16 ->
1892 // _________________________________
1894 // | 16-bits | 16-bits | 16-bits |
1895 // |__________|__________|__________|
1897 // For any 64-bit value that is representable as a 48-bit integer:
1898 // li d,j => lui d,hi16(j)
1899 // ori d,d,hi16(lo32(j))
1901 // ori d,d,lo16(lo32(j))
1902 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1903 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1904 uint16_t Bits15To0 = ImmValue & 0xffff;
1906 tmpInst.setOpcode(Mips::LUi);
1907 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1908 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1909 Instructions.push_back(tmpInst);
1910 createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1911 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1914 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1918 Error(IDLoc, "instruction requires a 32-bit immediate");
1921 warnIfNoMacro(IDLoc);
1923 // <------- hi32 ------> <------- lo32 ------>
1924 // <- hi16 -> <- lo16 ->
1925 // ___________________________________________
1927 // | 16-bits | 16-bits | 16-bits | 16-bits |
1928 // |__________|__________|__________|__________|
1930 // For all other values which are representable as a 64-bit integer:
1931 // li d,j => lui d,hi16(j)
1932 // ori d,d,lo16(hi32(j))
1934 // ori d,d,hi16(lo32(j))
1936 // ori d,d,lo16(lo32(j))
1937 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1938 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1939 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1940 uint16_t Bits15To0 = ImmValue & 0xffff;
1942 tmpInst.setOpcode(Mips::LUi);
1943 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1944 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1945 Instructions.push_back(tmpInst);
1946 createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1948 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1949 // two left shifts of 16 bits.
1950 if (Bits31To16 == 0) {
1951 createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1953 createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1954 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1958 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1963 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1964 SmallVectorImpl<MCInst> &Instructions) {
1965 const MCOperand &ImmOp = Inst.getOperand(1);
1966 assert(ImmOp.isImm() && "expected immediate operand kind");
1967 const MCOperand &DstRegOp = Inst.getOperand(0);
1968 assert(DstRegOp.isReg() && "expected register operand kind");
1970 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1971 Is32BitImm, IDLoc, Instructions))
1978 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1979 SmallVectorImpl<MCInst> &Instructions) {
1980 const MCOperand &DstRegOp = Inst.getOperand(0);
1981 assert(DstRegOp.isReg() && "expected register operand kind");
1983 const MCOperand &SrcRegOp = Inst.getOperand(1);
1984 assert(SrcRegOp.isReg() && "expected register operand kind");
1986 const MCOperand &ImmOp = Inst.getOperand(2);
1987 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1988 "expected immediate operand kind");
1989 if (!ImmOp.isImm()) {
1990 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1991 SrcRegOp.getReg(), Is32BitImm, IDLoc,
1998 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1999 Is32BitImm, IDLoc, Instructions))
2006 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2007 SmallVectorImpl<MCInst> &Instructions) {
2008 const MCOperand &DstRegOp = Inst.getOperand(0);
2009 assert(DstRegOp.isReg() && "expected register operand kind");
2011 const MCOperand &ImmOp = Inst.getOperand(1);
2012 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2013 "expected immediate operand kind");
2014 if (!ImmOp.isImm()) {
2015 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2016 Mips::NoRegister, Is32BitImm, IDLoc,
2023 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2024 Is32BitImm, IDLoc, Instructions))
2030 bool MipsAsmParser::loadAndAddSymbolAddress(
2031 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2032 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2033 warnIfNoMacro(IDLoc);
2035 if (Is32BitSym && isABI_N64())
2036 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
2039 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2040 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2041 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2042 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2043 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2045 bool UseSrcReg = SrcReg != Mips::NoRegister;
2047 unsigned TmpReg = DstReg;
2048 if (UseSrcReg && (DstReg == SrcReg)) {
2049 // At this point we need AT to perform the expansions and we exit if it is
2051 unsigned ATReg = getATReg(IDLoc);
2058 // If it's a 64-bit architecture, expand to:
2059 // la d,sym => lui d,highest(sym)
2060 // ori d,d,higher(sym)
2062 // ori d,d,hi16(sym)
2064 // ori d,d,lo16(sym)
2065 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2066 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2067 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2068 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2070 tmpInst.setOpcode(Mips::LUi);
2071 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2072 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2073 Instructions.push_back(tmpInst);
2075 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2077 createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2079 createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2082 // Otherwise, expand to:
2083 // la d,sym => lui d,hi16(sym)
2084 // ori d,d,lo16(sym)
2085 tmpInst.setOpcode(Mips::LUi);
2086 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2087 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2088 Instructions.push_back(tmpInst);
2090 createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2095 createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2100 bool MipsAsmParser::expandUncondBranchMMPseudo(
2101 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2102 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2103 "unexpected number of operands");
2105 MCOperand Offset = Inst.getOperand(0);
2106 if (Offset.isExpr()) {
2108 Inst.setOpcode(Mips::BEQ_MM);
2109 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2110 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2111 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2113 assert(Offset.isImm() && "expected immediate operand kind");
2114 if (isIntN(11, Offset.getImm())) {
2115 // If offset fits into 11 bits then this instruction becomes microMIPS
2116 // 16-bit unconditional branch instruction.
2117 Inst.setOpcode(Mips::B16_MM);
2119 if (!isIntN(17, Offset.getImm()))
2120 Error(IDLoc, "branch target out of range");
2121 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2122 Error(IDLoc, "branch to misaligned address");
2124 Inst.setOpcode(Mips::BEQ_MM);
2125 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2126 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2127 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2130 Instructions.push_back(Inst);
2132 // If .set reorder is active, emit a NOP after the branch instruction.
2133 if (AssemblerOptions.back()->isReorder())
2134 createNop(true, IDLoc, Instructions);
2139 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2140 SmallVectorImpl<MCInst> &Instructions) {
2141 const MCOperand &DstRegOp = Inst.getOperand(0);
2142 assert(DstRegOp.isReg() && "expected register operand kind");
2144 const MCOperand &ImmOp = Inst.getOperand(1);
2145 assert(ImmOp.isImm() && "expected immediate operand kind");
2147 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2148 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2150 unsigned OpCode = 0;
2151 switch(Inst.getOpcode()) {
2159 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2163 int64_t ImmValue = ImmOp.getImm();
2164 if (ImmValue == 0) {
2166 BranchInst.setOpcode(OpCode);
2167 BranchInst.addOperand(DstRegOp);
2168 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2169 BranchInst.addOperand(MemOffsetOp);
2170 Instructions.push_back(BranchInst);
2172 warnIfNoMacro(IDLoc);
2174 unsigned ATReg = getATReg(IDLoc);
2178 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2183 BranchInst.setOpcode(OpCode);
2184 BranchInst.addOperand(DstRegOp);
2185 BranchInst.addOperand(MCOperand::createReg(ATReg));
2186 BranchInst.addOperand(MemOffsetOp);
2187 Instructions.push_back(BranchInst);
2192 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2193 SmallVectorImpl<MCInst> &Instructions,
2194 bool isLoad, bool isImmOpnd) {
2196 unsigned ImmOffset, HiOffset, LoOffset;
2197 const MCExpr *ExprOffset;
2199 // 1st operand is either the source or destination register.
2200 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2201 unsigned RegOpNum = Inst.getOperand(0).getReg();
2202 // 2nd operand is the base register.
2203 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2204 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2205 // 3rd operand is either an immediate or expression.
2207 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2208 ImmOffset = Inst.getOperand(2).getImm();
2209 LoOffset = ImmOffset & 0x0000ffff;
2210 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2211 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2212 if (LoOffset & 0x8000)
2215 ExprOffset = Inst.getOperand(2).getExpr();
2216 // All instructions will have the same location.
2217 TempInst.setLoc(IDLoc);
2218 // These are some of the types of expansions we perform here:
2219 // 1) lw $8, sym => lui $8, %hi(sym)
2220 // lw $8, %lo(sym)($8)
2221 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2223 // lw $8, %lo(offset)($9)
2224 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2226 // lw $8, %lo(offset)($at)
2227 // 4) sw $8, sym => lui $at, %hi(sym)
2228 // sw $8, %lo(sym)($at)
2229 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2231 // sw $8, %lo(offset)($at)
2232 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2233 // ldc1 $f0, %lo(sym)($at)
2235 // For load instructions we can use the destination register as a temporary
2236 // if base and dst are different (examples 1 and 2) and if the base register
2237 // is general purpose otherwise we must use $at (example 6) and error if it's
2238 // not available. For stores we must use $at (examples 4 and 5) because we
2239 // must not clobber the source register setting up the offset.
2240 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2241 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2242 unsigned RegClassIDOp0 =
2243 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2244 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2245 (RegClassIDOp0 == Mips::GPR64RegClassID);
2246 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2247 TmpRegNum = RegOpNum;
2249 // At this point we need AT to perform the expansions and we exit if it is
2251 TmpRegNum = getATReg(IDLoc);
2256 TempInst.setOpcode(Mips::LUi);
2257 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2259 TempInst.addOperand(MCOperand::createImm(HiOffset));
2261 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2262 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2264 // Add the instruction to the list.
2265 Instructions.push_back(TempInst);
2266 // Prepare TempInst for next instruction.
2268 // Add temp register to base.
2269 if (BaseRegNum != Mips::ZERO) {
2270 TempInst.setOpcode(Mips::ADDu);
2271 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2272 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2273 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2274 Instructions.push_back(TempInst);
2277 // And finally, create original instruction with low part
2278 // of offset and new base.
2279 TempInst.setOpcode(Inst.getOpcode());
2280 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2281 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2283 TempInst.addOperand(MCOperand::createImm(LoOffset));
2285 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2286 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2288 Instructions.push_back(TempInst);
2293 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2294 SmallVectorImpl<MCInst> &Instructions) {
2295 unsigned OpNum = Inst.getNumOperands();
2296 unsigned Opcode = Inst.getOpcode();
2297 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2299 assert (Inst.getOperand(OpNum - 1).isImm() &&
2300 Inst.getOperand(OpNum - 2).isReg() &&
2301 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2303 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2304 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2305 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2306 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2307 // It can be implemented as SWM16 or LWM16 instruction.
2308 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2310 Inst.setOpcode(NewOpcode);
2311 Instructions.push_back(Inst);
2315 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2316 SmallVectorImpl<MCInst> &Instructions) {
2317 unsigned PseudoOpcode = Inst.getOpcode();
2318 unsigned SrcReg = Inst.getOperand(0).getReg();
2319 unsigned TrgReg = Inst.getOperand(1).getReg();
2320 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2322 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2323 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2325 switch (PseudoOpcode) {
2328 AcceptsEquality = false;
2329 ReverseOrderSLT = false;
2330 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2331 ZeroSrcOpcode = Mips::BGTZ;
2332 ZeroTrgOpcode = Mips::BLTZ;
2336 AcceptsEquality = true;
2337 ReverseOrderSLT = true;
2338 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2339 ZeroSrcOpcode = Mips::BGEZ;
2340 ZeroTrgOpcode = Mips::BLEZ;
2344 AcceptsEquality = true;
2345 ReverseOrderSLT = false;
2346 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2347 ZeroSrcOpcode = Mips::BLEZ;
2348 ZeroTrgOpcode = Mips::BGEZ;
2352 AcceptsEquality = false;
2353 ReverseOrderSLT = true;
2354 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2355 ZeroSrcOpcode = Mips::BLTZ;
2356 ZeroTrgOpcode = Mips::BGTZ;
2359 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2363 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2364 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2365 if (IsSrcRegZero && IsTrgRegZero) {
2366 // FIXME: All of these Opcode-specific if's are needed for compatibility
2367 // with GAS' behaviour. However, they may not generate the most efficient
2368 // code in some circumstances.
2369 if (PseudoOpcode == Mips::BLT) {
2370 BranchInst.setOpcode(Mips::BLTZ);
2371 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2372 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2373 Instructions.push_back(BranchInst);
2376 if (PseudoOpcode == Mips::BLE) {
2377 BranchInst.setOpcode(Mips::BLEZ);
2378 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2379 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2380 Instructions.push_back(BranchInst);
2381 Warning(IDLoc, "branch is always taken");
2384 if (PseudoOpcode == Mips::BGE) {
2385 BranchInst.setOpcode(Mips::BGEZ);
2386 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2387 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2388 Instructions.push_back(BranchInst);
2389 Warning(IDLoc, "branch is always taken");
2392 if (PseudoOpcode == Mips::BGT) {
2393 BranchInst.setOpcode(Mips::BGTZ);
2394 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2395 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2396 Instructions.push_back(BranchInst);
2399 if (PseudoOpcode == Mips::BGTU) {
2400 BranchInst.setOpcode(Mips::BNE);
2401 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2402 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2403 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2404 Instructions.push_back(BranchInst);
2407 if (AcceptsEquality) {
2408 // If both registers are $0 and the pseudo-branch accepts equality, it
2409 // will always be taken, so we emit an unconditional branch.
2410 BranchInst.setOpcode(Mips::BEQ);
2411 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2412 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2413 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2414 Instructions.push_back(BranchInst);
2415 Warning(IDLoc, "branch is always taken");
2418 // If both registers are $0 and the pseudo-branch does not accept
2419 // equality, it will never be taken, so we don't have to emit anything.
2422 if (IsSrcRegZero || IsTrgRegZero) {
2423 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2424 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2425 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2426 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2427 // the pseudo-branch will never be taken, so we don't emit anything.
2428 // This only applies to unsigned pseudo-branches.
2431 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2432 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2433 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2434 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2435 // the pseudo-branch will always be taken, so we emit an unconditional
2437 // This only applies to unsigned pseudo-branches.
2438 BranchInst.setOpcode(Mips::BEQ);
2439 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2440 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2441 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2442 Instructions.push_back(BranchInst);
2443 Warning(IDLoc, "branch is always taken");
2447 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2448 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2449 // the pseudo-branch will be taken only when the non-zero register is
2450 // different from 0, so we emit a BNEZ.
2452 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2453 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2454 // the pseudo-branch will be taken only when the non-zero register is
2455 // equal to 0, so we emit a BEQZ.
2457 // Because only BLEU and BGEU branch on equality, we can use the
2458 // AcceptsEquality variable to decide when to emit the BEQZ.
2459 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2460 BranchInst.addOperand(
2461 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2462 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2463 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2464 Instructions.push_back(BranchInst);
2467 // If we have a signed pseudo-branch and one of the registers is $0,
2468 // we can use an appropriate compare-to-zero branch. We select which one
2469 // to use in the switch statement above.
2470 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2471 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2472 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2473 Instructions.push_back(BranchInst);
2477 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2478 // expansions. If it is not available, we return.
2479 unsigned ATRegNum = getATReg(IDLoc);
2483 warnIfNoMacro(IDLoc);
2485 // SLT fits well with 2 of our 4 pseudo-branches:
2486 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2487 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2488 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2489 // This is accomplished by using a BNEZ with the result of the SLT.
2491 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2492 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2493 // Because only BGE and BLE branch on equality, we can use the
2494 // AcceptsEquality variable to decide when to emit the BEQZ.
2495 // Note that the order of the SLT arguments doesn't change between
2498 // The same applies to the unsigned variants, except that SLTu is used
2501 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2502 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2503 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2504 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2505 Instructions.push_back(SetInst);
2507 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2508 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2509 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2510 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2511 Instructions.push_back(BranchInst);
2515 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2516 SmallVectorImpl<MCInst> &Instructions) {
2517 if (hasMips32r6() || hasMips64r6()) {
2518 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2522 warnIfNoMacro(IDLoc);
2524 const MCOperand &DstRegOp = Inst.getOperand(0);
2525 assert(DstRegOp.isReg() && "expected register operand kind");
2527 const MCOperand &SrcRegOp = Inst.getOperand(1);
2528 assert(SrcRegOp.isReg() && "expected register operand kind");
2530 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2531 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2533 unsigned DstReg = DstRegOp.getReg();
2534 unsigned SrcReg = SrcRegOp.getReg();
2535 int64_t OffsetValue = OffsetImmOp.getImm();
2537 // NOTE: We always need AT for ULHU, as it is always used as the source
2538 // register for one of the LBu's.
2539 unsigned ATReg = getATReg(IDLoc);
2543 // When the value of offset+1 does not fit in 16 bits, we have to load the
2544 // offset in AT, (D)ADDu the original source register (if there was one), and
2545 // then use AT as the source register for the 2 generated LBu's.
2546 bool LoadedOffsetInAT = false;
2547 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2548 LoadedOffsetInAT = true;
2550 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2551 IDLoc, Instructions))
2554 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2555 // because it will make our output more similar to GAS'. For example,
2556 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2557 // instead of just an "ori $1, $9, 32768".
2558 // NOTE: If there is no source register specified in the ULHU, the parser
2559 // will interpret it as $0.
2560 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2561 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2564 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2565 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2566 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2568 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2570 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2571 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2573 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2574 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2577 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2580 TmpInst.setOpcode(Mips::LBu);
2581 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2582 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2583 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2584 Instructions.push_back(TmpInst);
2587 TmpInst.setOpcode(Mips::LBu);
2588 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2589 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2590 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2591 Instructions.push_back(TmpInst);
2594 TmpInst.setOpcode(Mips::SLL);
2595 TmpInst.addOperand(MCOperand::createReg(SllReg));
2596 TmpInst.addOperand(MCOperand::createReg(SllReg));
2597 TmpInst.addOperand(MCOperand::createImm(8));
2598 Instructions.push_back(TmpInst);
2601 TmpInst.setOpcode(Mips::OR);
2602 TmpInst.addOperand(MCOperand::createReg(DstReg));
2603 TmpInst.addOperand(MCOperand::createReg(DstReg));
2604 TmpInst.addOperand(MCOperand::createReg(ATReg));
2605 Instructions.push_back(TmpInst);
2610 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2611 SmallVectorImpl<MCInst> &Instructions) {
2612 if (hasMips32r6() || hasMips64r6()) {
2613 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2617 const MCOperand &DstRegOp = Inst.getOperand(0);
2618 assert(DstRegOp.isReg() && "expected register operand kind");
2620 const MCOperand &SrcRegOp = Inst.getOperand(1);
2621 assert(SrcRegOp.isReg() && "expected register operand kind");
2623 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2624 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2626 unsigned SrcReg = SrcRegOp.getReg();
2627 int64_t OffsetValue = OffsetImmOp.getImm();
2630 // When the value of offset+3 does not fit in 16 bits, we have to load the
2631 // offset in AT, (D)ADDu the original source register (if there was one), and
2632 // then use AT as the source register for the generated LWL and LWR.
2633 bool LoadedOffsetInAT = false;
2634 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2635 ATReg = getATReg(IDLoc);
2638 LoadedOffsetInAT = true;
2640 warnIfNoMacro(IDLoc);
2642 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2643 IDLoc, Instructions))
2646 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2647 // because it will make our output more similar to GAS'. For example,
2648 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2649 // instead of just an "ori $1, $9, 32768".
2650 // NOTE: If there is no source register specified in the ULW, the parser
2651 // will interpret it as $0.
2652 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2653 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2656 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2657 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2659 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2660 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2662 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2663 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2666 MCInst LeftLoadInst;
2667 LeftLoadInst.setOpcode(Mips::LWL);
2668 LeftLoadInst.addOperand(DstRegOp);
2669 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2670 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2671 Instructions.push_back(LeftLoadInst);
2673 MCInst RightLoadInst;
2674 RightLoadInst.setOpcode(Mips::LWR);
2675 RightLoadInst.addOperand(DstRegOp);
2676 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2677 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2678 Instructions.push_back(RightLoadInst);
2683 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2684 SmallVectorImpl<MCInst> &Instructions) {
2686 if (hasShortDelaySlot) {
2687 NopInst.setOpcode(Mips::MOVE16_MM);
2688 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2689 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2691 NopInst.setOpcode(Mips::SLL);
2692 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2693 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2694 NopInst.addOperand(MCOperand::createImm(0));
2696 Instructions.push_back(NopInst);
2699 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2700 unsigned TrgReg, bool Is64Bit,
2701 SmallVectorImpl<MCInst> &Instructions) {
2703 AdduInst.setOpcode(Is64Bit ? Mips::DADDu : Mips::ADDu);
2704 AdduInst.addOperand(MCOperand::createReg(DstReg));
2705 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2706 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2707 Instructions.push_back(AdduInst);
2710 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2711 // As described by the Mips32r2 spec, the registers Rd and Rs for
2712 // jalr.hb must be different.
2713 unsigned Opcode = Inst.getOpcode();
2715 if (Opcode == Mips::JALR_HB &&
2716 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2717 return Match_RequiresDifferentSrcAndDst;
2719 return Match_Success;
2722 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2723 OperandVector &Operands,
2725 uint64_t &ErrorInfo,
2726 FeatureBitset &ErrorMissingFeature,
2727 bool MatchingInlineAsm) {
2730 SmallVector<MCInst, 8> Instructions;
2731 unsigned MatchResult =
2732 MatchInstructionImpl(Operands, Inst, ErrorInfo, ErrorMissingFeature, MatchingInlineAsm);
2734 switch (MatchResult) {
2735 case Match_Success: {
2736 if (processInstruction(Inst, IDLoc, Instructions))
2738 for (unsigned i = 0; i < Instructions.size(); i++)
2739 Out.EmitInstruction(Instructions[i], STI);
2742 case Match_MissingFeature:
2743 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2745 case Match_InvalidOperand: {
2746 SMLoc ErrorLoc = IDLoc;
2747 if (ErrorInfo != ~0ULL) {
2748 if (ErrorInfo >= Operands.size())
2749 return Error(IDLoc, "too few operands for instruction");
2751 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2752 if (ErrorLoc == SMLoc())
2756 return Error(ErrorLoc, "invalid operand for instruction");
2758 case Match_MnemonicFail:
2759 return Error(IDLoc, "invalid instruction");
2760 case Match_RequiresDifferentSrcAndDst:
2761 return Error(IDLoc, "source and destination must be different");
2764 llvm_unreachable("Implement any new match types added!");
2767 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2768 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2769 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2770 ") without \".set noat\"");
2773 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2774 if (!AssemblerOptions.back()->isMacro())
2775 Warning(Loc, "macro instruction expanded into multiple instructions");
2779 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2780 SMRange Range, bool ShowColors) {
2781 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2782 Range, SMFixIt(Range, FixMsg),
2786 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2789 CC = StringSwitch<unsigned>(Name)
2825 if (!(isABI_N32() || isABI_N64()))
2828 if (12 <= CC && CC <= 15) {
2829 // Name is one of t4-t7
2830 AsmToken RegTok = getLexer().peekTok();
2831 SMRange RegRange = RegTok.getLocRange();
2833 StringRef FixedName = StringSwitch<StringRef>(Name)
2839 assert(FixedName != "" && "Register name is not one of t4-t7.");
2841 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2842 "Did you mean $" + FixedName + "?", RegRange);
2845 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2846 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2847 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2848 if (8 <= CC && CC <= 11)
2852 CC = StringSwitch<unsigned>(Name)
2864 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2867 CC = StringSwitch<unsigned>(Name)
2868 .Case("hwr_cpunum", 0)
2869 .Case("hwr_synci_step", 1)
2871 .Case("hwr_ccres", 3)
2872 .Case("hwr_ulr", 29)
2878 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2880 if (Name[0] == 'f') {
2881 StringRef NumString = Name.substr(1);
2883 if (NumString.getAsInteger(10, IntVal))
2884 return -1; // This is not an integer.
2885 if (IntVal > 31) // Maximum index for fpu register.
2892 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2894 if (Name.startswith("fcc")) {
2895 StringRef NumString = Name.substr(3);
2897 if (NumString.getAsInteger(10, IntVal))
2898 return -1; // This is not an integer.
2899 if (IntVal > 7) // There are only 8 fcc registers.
2906 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2908 if (Name.startswith("ac")) {
2909 StringRef NumString = Name.substr(2);
2911 if (NumString.getAsInteger(10, IntVal))
2912 return -1; // This is not an integer.
2913 if (IntVal > 3) // There are only 3 acc registers.
2920 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2923 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2932 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2935 CC = StringSwitch<unsigned>(Name)
2938 .Case("msaaccess", 2)
2940 .Case("msamodify", 4)
2941 .Case("msarequest", 5)
2943 .Case("msaunmap", 7)
2949 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2950 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2952 reportParseError(Loc,
2953 "pseudo-instruction requires $at, which is not available");
2956 unsigned AT = getReg(
2957 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2961 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2962 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2965 unsigned MipsAsmParser::getGPR(int RegNo) {
2966 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2970 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2972 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2975 return getReg(RegClass, RegNum);
2978 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2979 MCAsmParser &Parser = getParser();
2980 DEBUG(dbgs() << "parseOperand\n");
2982 // Check if the current operand has a custom associated parser, if so, try to
2983 // custom parse the operand, or fallback to the general approach.
2984 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2985 if (ResTy == MatchOperand_Success)
2987 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2988 // there was a match, but an error occurred, in which case, just return that
2989 // the operand parsing failed.
2990 if (ResTy == MatchOperand_ParseFail)
2993 DEBUG(dbgs() << ".. Generic Parser\n");
2995 switch (getLexer().getKind()) {
2997 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2999 case AsmToken::Dollar: {
3000 // Parse the register.
3001 SMLoc S = Parser.getTok().getLoc();
3003 // Almost all registers have been parsed by custom parsers. There is only
3004 // one exception to this. $zero (and it's alias $0) will reach this point
3005 // for div, divu, and similar instructions because it is not an operand
3006 // to the instruction definition but an explicit register. Special case
3007 // this situation for now.
3008 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3011 // Maybe it is a symbol reference.
3012 StringRef Identifier;
3013 if (Parser.parseIdentifier(Identifier))
3016 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3017 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3018 // Otherwise create a symbol reference.
3020 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3022 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3025 // Else drop to expression parsing.
3026 case AsmToken::LParen:
3027 case AsmToken::Minus:
3028 case AsmToken::Plus:
3029 case AsmToken::Integer:
3030 case AsmToken::Tilde:
3031 case AsmToken::String: {
3032 DEBUG(dbgs() << ".. generic integer\n");
3033 OperandMatchResultTy ResTy = parseImm(Operands);
3034 return ResTy != MatchOperand_Success;
3036 case AsmToken::Percent: {
3037 // It is a symbol reference or constant expression.
3038 const MCExpr *IdVal;
3039 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3040 if (parseRelocOperand(IdVal))
3043 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3045 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3047 } // case AsmToken::Percent
3048 } // switch(getLexer().getKind())
3052 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3053 StringRef RelocStr) {
3055 // Check the type of the expression.
3056 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3057 // It's a constant, evaluate reloc value.
3059 switch (getVariantKind(RelocStr)) {
3060 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3061 // Get the 1st 16-bits.
3062 Val = MCE->getValue() & 0xffff;
3064 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3065 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3066 // 16 bits being negative.
3067 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3069 case MCSymbolRefExpr::VK_Mips_HIGHER:
3070 // Get the 3rd 16-bits.
3071 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3073 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3074 // Get the 4th 16-bits.
3075 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3078 report_fatal_error("unsupported reloc value");
3080 return MCConstantExpr::create(Val, getContext());
3083 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3084 // It's a symbol, create a symbolic expression from the symbol.
3085 const MCSymbol *Symbol = &MSRE->getSymbol();
3086 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3087 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3091 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3092 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3094 // Try to create target expression.
3095 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3096 return MipsMCExpr::create(VK, Expr, getContext());
3098 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3099 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3100 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3104 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3105 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3106 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3109 // Just return the original expression.
3113 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3115 switch (Expr->getKind()) {
3116 case MCExpr::Constant:
3118 case MCExpr::SymbolRef:
3119 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3120 case MCExpr::Binary:
3121 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3122 if (!isEvaluated(BE->getLHS()))
3124 return isEvaluated(BE->getRHS());
3127 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3128 case MCExpr::Target:
3134 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3135 MCAsmParser &Parser = getParser();
3136 Parser.Lex(); // Eat the % token.
3137 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3138 if (Tok.isNot(AsmToken::Identifier))
3141 std::string Str = Tok.getIdentifier();
3143 Parser.Lex(); // Eat the identifier.
3144 // Now make an expression from the rest of the operand.
3145 const MCExpr *IdVal;
3148 if (getLexer().getKind() == AsmToken::LParen) {
3150 Parser.Lex(); // Eat the '(' token.
3151 if (getLexer().getKind() == AsmToken::Percent) {
3152 Parser.Lex(); // Eat the % token.
3153 const AsmToken &nextTok = Parser.getTok();
3154 if (nextTok.isNot(AsmToken::Identifier))
3157 Str += nextTok.getIdentifier();
3158 Parser.Lex(); // Eat the identifier.
3159 if (getLexer().getKind() != AsmToken::LParen)
3164 if (getParser().parseParenExpression(IdVal, EndLoc))
3167 while (getLexer().getKind() == AsmToken::RParen)
3168 Parser.Lex(); // Eat the ')' token.
3171 return true; // Parenthesis must follow the relocation operand.
3173 Res = evaluateRelocExpr(IdVal, Str);
3177 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3179 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3180 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3181 if (ResTy == MatchOperand_Success) {
3182 assert(Operands.size() == 1);
3183 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3184 StartLoc = Operand.getStartLoc();
3185 EndLoc = Operand.getEndLoc();
3187 // AFAIK, we only support numeric registers and named GPR's in CFI
3189 // Don't worry about eating tokens before failing. Using an unrecognised
3190 // register is a parse error.
3191 if (Operand.isGPRAsmReg()) {
3192 // Resolve to GPR32 or GPR64 appropriately.
3193 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3196 return (RegNo == (unsigned)-1);
3199 assert(Operands.size() == 0);
3200 return (RegNo == (unsigned)-1);
3203 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3204 MCAsmParser &Parser = getParser();
3207 unsigned NumOfLParen = 0;
3209 while (getLexer().getKind() == AsmToken::LParen) {
3214 switch (getLexer().getKind()) {
3217 case AsmToken::Identifier:
3218 case AsmToken::LParen:
3219 case AsmToken::Integer:
3220 case AsmToken::Minus:
3221 case AsmToken::Plus:
3223 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3225 Result = (getParser().parseExpression(Res));
3226 while (getLexer().getKind() == AsmToken::RParen)
3229 case AsmToken::Percent:
3230 Result = parseRelocOperand(Res);
3235 MipsAsmParser::OperandMatchResultTy
3236 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3237 MCAsmParser &Parser = getParser();
3238 DEBUG(dbgs() << "parseMemOperand\n");
3239 const MCExpr *IdVal = nullptr;
3241 bool isParenExpr = false;
3242 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3243 // First operand is the offset.
3244 S = Parser.getTok().getLoc();
3246 if (getLexer().getKind() == AsmToken::LParen) {
3251 if (getLexer().getKind() != AsmToken::Dollar) {
3252 if (parseMemOffset(IdVal, isParenExpr))
3253 return MatchOperand_ParseFail;
3255 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3256 if (Tok.isNot(AsmToken::LParen)) {
3257 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3258 if (Mnemonic.getToken() == "la") {
3260 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3261 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3262 return MatchOperand_Success;
3264 if (Tok.is(AsmToken::EndOfStatement)) {
3266 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3268 // Zero register assumed, add a memory operand with ZERO as its base.
3269 // "Base" will be managed by k_Memory.
3270 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3273 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3274 return MatchOperand_Success;
3276 Error(Parser.getTok().getLoc(), "'(' expected");
3277 return MatchOperand_ParseFail;
3280 Parser.Lex(); // Eat the '(' token.
3283 Res = parseAnyRegister(Operands);
3284 if (Res != MatchOperand_Success)
3287 if (Parser.getTok().isNot(AsmToken::RParen)) {
3288 Error(Parser.getTok().getLoc(), "')' expected");
3289 return MatchOperand_ParseFail;
3292 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3294 Parser.Lex(); // Eat the ')' token.
3297 IdVal = MCConstantExpr::create(0, getContext());
3299 // Replace the register operand with the memory operand.
3300 std::unique_ptr<MipsOperand> op(
3301 static_cast<MipsOperand *>(Operands.back().release()));
3302 // Remove the register from the operands.
3303 // "op" will be managed by k_Memory.
3304 Operands.pop_back();
3305 // Add the memory operand.
3306 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3308 if (IdVal->evaluateAsAbsolute(Imm))
3309 IdVal = MCConstantExpr::create(Imm, getContext());
3310 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3311 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3315 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3316 return MatchOperand_Success;
3319 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3320 MCAsmParser &Parser = getParser();
3321 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3323 SMLoc S = Parser.getTok().getLoc();
3325 if (Sym->isVariable())
3326 Expr = Sym->getVariableValue();
3329 if (Expr->getKind() == MCExpr::SymbolRef) {
3330 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3331 StringRef DefSymbol = Ref->getSymbol().getName();
3332 if (DefSymbol.startswith("$")) {
3333 OperandMatchResultTy ResTy =
3334 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3335 if (ResTy == MatchOperand_Success) {
3338 } else if (ResTy == MatchOperand_ParseFail)
3339 llvm_unreachable("Should never ParseFail");
3342 } else if (Expr->getKind() == MCExpr::Constant) {
3344 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3346 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3353 MipsAsmParser::OperandMatchResultTy
3354 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3355 StringRef Identifier,
3357 int Index = matchCPURegisterName(Identifier);
3359 Operands.push_back(MipsOperand::createGPRReg(
3360 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3361 return MatchOperand_Success;
3364 Index = matchHWRegsRegisterName(Identifier);
3366 Operands.push_back(MipsOperand::createHWRegsReg(
3367 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3368 return MatchOperand_Success;
3371 Index = matchFPURegisterName(Identifier);
3373 Operands.push_back(MipsOperand::createFGRReg(
3374 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3375 return MatchOperand_Success;
3378 Index = matchFCCRegisterName(Identifier);
3380 Operands.push_back(MipsOperand::createFCCReg(
3381 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3382 return MatchOperand_Success;
3385 Index = matchACRegisterName(Identifier);
3387 Operands.push_back(MipsOperand::createACCReg(
3388 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3389 return MatchOperand_Success;
3392 Index = matchMSA128RegisterName(Identifier);
3394 Operands.push_back(MipsOperand::createMSA128Reg(
3395 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3396 return MatchOperand_Success;
3399 Index = matchMSA128CtrlRegisterName(Identifier);
3401 Operands.push_back(MipsOperand::createMSACtrlReg(
3402 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3403 return MatchOperand_Success;
3406 return MatchOperand_NoMatch;
3409 MipsAsmParser::OperandMatchResultTy
3410 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3411 MCAsmParser &Parser = getParser();
3412 auto Token = Parser.getLexer().peekTok(false);
3414 if (Token.is(AsmToken::Identifier)) {
3415 DEBUG(dbgs() << ".. identifier\n");
3416 StringRef Identifier = Token.getIdentifier();
3417 OperandMatchResultTy ResTy =
3418 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3420 } else if (Token.is(AsmToken::Integer)) {
3421 DEBUG(dbgs() << ".. integer\n");
3422 Operands.push_back(MipsOperand::createNumericReg(
3423 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3425 return MatchOperand_Success;
3428 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3430 return MatchOperand_NoMatch;
3433 MipsAsmParser::OperandMatchResultTy
3434 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3435 MCAsmParser &Parser = getParser();
3436 DEBUG(dbgs() << "parseAnyRegister\n");
3438 auto Token = Parser.getTok();
3440 SMLoc S = Token.getLoc();
3442 if (Token.isNot(AsmToken::Dollar)) {
3443 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3444 if (Token.is(AsmToken::Identifier)) {
3445 if (searchSymbolAlias(Operands))
3446 return MatchOperand_Success;
3448 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3449 return MatchOperand_NoMatch;
3451 DEBUG(dbgs() << ".. $\n");
3453 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3454 if (ResTy == MatchOperand_Success) {
3456 Parser.Lex(); // identifier
3461 MipsAsmParser::OperandMatchResultTy
3462 MipsAsmParser::parseImm(OperandVector &Operands) {
3463 MCAsmParser &Parser = getParser();
3464 switch (getLexer().getKind()) {
3466 return MatchOperand_NoMatch;
3467 case AsmToken::LParen:
3468 case AsmToken::Minus:
3469 case AsmToken::Plus:
3470 case AsmToken::Integer:
3471 case AsmToken::Tilde:
3472 case AsmToken::String:
3476 const MCExpr *IdVal;
3477 SMLoc S = Parser.getTok().getLoc();
3478 if (getParser().parseExpression(IdVal))
3479 return MatchOperand_ParseFail;
3481 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3482 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3483 return MatchOperand_Success;
3486 MipsAsmParser::OperandMatchResultTy
3487 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3488 MCAsmParser &Parser = getParser();
3489 DEBUG(dbgs() << "parseJumpTarget\n");
3491 SMLoc S = getLexer().getLoc();
3493 // Integers and expressions are acceptable
3494 OperandMatchResultTy ResTy = parseImm(Operands);
3495 if (ResTy != MatchOperand_NoMatch)
3498 // Registers are a valid target and have priority over symbols.
3499 ResTy = parseAnyRegister(Operands);
3500 if (ResTy != MatchOperand_NoMatch)
3503 const MCExpr *Expr = nullptr;
3504 if (Parser.parseExpression(Expr)) {
3505 // We have no way of knowing if a symbol was consumed so we must ParseFail
3506 return MatchOperand_ParseFail;
3509 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3510 return MatchOperand_Success;
3513 MipsAsmParser::OperandMatchResultTy
3514 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3515 MCAsmParser &Parser = getParser();
3516 const MCExpr *IdVal;
3517 // If the first token is '$' we may have register operand.
3518 if (Parser.getTok().is(AsmToken::Dollar))
3519 return MatchOperand_NoMatch;
3520 SMLoc S = Parser.getTok().getLoc();
3521 if (getParser().parseExpression(IdVal))
3522 return MatchOperand_ParseFail;
3523 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3524 assert(MCE && "Unexpected MCExpr type.");
3525 int64_t Val = MCE->getValue();
3526 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3527 Operands.push_back(MipsOperand::CreateImm(
3528 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3529 return MatchOperand_Success;
3532 MipsAsmParser::OperandMatchResultTy
3533 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3534 MCAsmParser &Parser = getParser();
3535 switch (getLexer().getKind()) {
3537 return MatchOperand_NoMatch;
3538 case AsmToken::LParen:
3539 case AsmToken::Plus:
3540 case AsmToken::Minus:
3541 case AsmToken::Integer:
3546 SMLoc S = Parser.getTok().getLoc();
3548 if (getParser().parseExpression(Expr))
3549 return MatchOperand_ParseFail;
3552 if (!Expr->evaluateAsAbsolute(Val)) {
3553 Error(S, "expected immediate value");
3554 return MatchOperand_ParseFail;
3557 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3558 // and because the CPU always adds one to the immediate field, the allowed
3559 // range becomes 1..4. We'll only check the range here and will deal
3560 // with the addition/subtraction when actually decoding/encoding
3562 if (Val < 1 || Val > 4) {
3563 Error(S, "immediate not in range (1..4)");
3564 return MatchOperand_ParseFail;
3568 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3569 return MatchOperand_Success;
3572 MipsAsmParser::OperandMatchResultTy
3573 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3574 MCAsmParser &Parser = getParser();
3575 SmallVector<unsigned, 10> Regs;
3577 unsigned PrevReg = Mips::NoRegister;
3578 bool RegRange = false;
3579 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3581 if (Parser.getTok().isNot(AsmToken::Dollar))
3582 return MatchOperand_ParseFail;
3584 SMLoc S = Parser.getTok().getLoc();
3585 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3586 SMLoc E = getLexer().getLoc();
3587 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3588 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3590 // Remove last register operand because registers from register range
3591 // should be inserted first.
3592 if (RegNo == Mips::RA) {
3593 Regs.push_back(RegNo);
3595 unsigned TmpReg = PrevReg + 1;
3596 while (TmpReg <= RegNo) {
3597 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3598 Error(E, "invalid register operand");
3599 return MatchOperand_ParseFail;
3603 Regs.push_back(TmpReg++);
3609 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3610 (RegNo != Mips::RA)) {
3611 Error(E, "$16 or $31 expected");
3612 return MatchOperand_ParseFail;
3613 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3614 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3615 Error(E, "invalid register operand");
3616 return MatchOperand_ParseFail;
3617 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3618 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3619 Error(E, "consecutive register numbers expected");
3620 return MatchOperand_ParseFail;
3623 Regs.push_back(RegNo);
3626 if (Parser.getTok().is(AsmToken::Minus))
3629 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3630 !Parser.getTok().isNot(AsmToken::Comma)) {
3631 Error(E, "',' or '-' expected");
3632 return MatchOperand_ParseFail;
3635 Lex(); // Consume comma or minus
3636 if (Parser.getTok().isNot(AsmToken::Dollar))
3642 SMLoc E = Parser.getTok().getLoc();
3643 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3644 parseMemOperand(Operands);
3645 return MatchOperand_Success;
3648 MipsAsmParser::OperandMatchResultTy
3649 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3650 MCAsmParser &Parser = getParser();
3652 SMLoc S = Parser.getTok().getLoc();
3653 if (parseAnyRegister(Operands) != MatchOperand_Success)
3654 return MatchOperand_ParseFail;
3656 SMLoc E = Parser.getTok().getLoc();
3657 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3658 unsigned Reg = Op.getGPR32Reg();
3659 Operands.pop_back();
3660 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3661 return MatchOperand_Success;
3664 MipsAsmParser::OperandMatchResultTy
3665 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3666 MCAsmParser &Parser = getParser();
3667 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3668 SmallVector<unsigned, 10> Regs;
3670 if (Parser.getTok().isNot(AsmToken::Dollar))
3671 return MatchOperand_ParseFail;
3673 SMLoc S = Parser.getTok().getLoc();
3675 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3676 return MatchOperand_ParseFail;
3678 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3679 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3680 Regs.push_back(RegNo);
3682 SMLoc E = Parser.getTok().getLoc();
3683 if (Parser.getTok().isNot(AsmToken::Comma)) {
3684 Error(E, "',' expected");
3685 return MatchOperand_ParseFail;
3691 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3692 return MatchOperand_ParseFail;
3694 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3695 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3696 Regs.push_back(RegNo);
3698 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3700 return MatchOperand_Success;
3703 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3705 MCSymbolRefExpr::VariantKind VK =
3706 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3707 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3708 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3709 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3710 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3711 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3712 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3713 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3714 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3715 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3716 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3717 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3718 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3719 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3720 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3721 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3722 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3723 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3724 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3725 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3726 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3727 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3728 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3729 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3730 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3731 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3732 .Default(MCSymbolRefExpr::VK_None);
3734 assert(VK != MCSymbolRefExpr::VK_None);
3739 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3741 /// ::= '(', register, ')'
3742 /// handle it before we iterate so we don't get tripped up by the lack of
3744 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3745 MCAsmParser &Parser = getParser();
3746 if (getLexer().is(AsmToken::LParen)) {
3748 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3750 if (parseOperand(Operands, Name)) {
3751 SMLoc Loc = getLexer().getLoc();
3752 Parser.eatToEndOfStatement();
3753 return Error(Loc, "unexpected token in argument list");
3755 if (Parser.getTok().isNot(AsmToken::RParen)) {
3756 SMLoc Loc = getLexer().getLoc();
3757 Parser.eatToEndOfStatement();
3758 return Error(Loc, "unexpected token, expected ')'");
3761 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3767 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3768 /// either one of these.
3769 /// ::= '[', register, ']'
3770 /// ::= '[', integer, ']'
3771 /// handle it before we iterate so we don't get tripped up by the lack of
3773 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3774 OperandVector &Operands) {
3775 MCAsmParser &Parser = getParser();
3776 if (getLexer().is(AsmToken::LBrac)) {
3778 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3780 if (parseOperand(Operands, Name)) {
3781 SMLoc Loc = getLexer().getLoc();
3782 Parser.eatToEndOfStatement();
3783 return Error(Loc, "unexpected token in argument list");
3785 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3786 SMLoc Loc = getLexer().getLoc();
3787 Parser.eatToEndOfStatement();
3788 return Error(Loc, "unexpected token, expected ']'");
3791 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3797 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3798 SMLoc NameLoc, OperandVector &Operands) {
3799 MCAsmParser &Parser = getParser();
3800 DEBUG(dbgs() << "ParseInstruction\n");
3802 // We have reached first instruction, module directive are now forbidden.
3803 getTargetStreamer().forbidModuleDirective();
3805 // Check if we have valid mnemonic
3806 if (!mnemonicIsValid(Name, 0)) {
3807 Parser.eatToEndOfStatement();
3808 return Error(NameLoc, "unknown instruction");
3810 // First operand in MCInst is instruction mnemonic.
3811 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3813 // Read the remaining operands.
3814 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3815 // Read the first operand.
3816 if (parseOperand(Operands, Name)) {
3817 SMLoc Loc = getLexer().getLoc();
3818 Parser.eatToEndOfStatement();
3819 return Error(Loc, "unexpected token in argument list");
3821 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3823 // AFAIK, parenthesis suffixes are never on the first operand
3825 while (getLexer().is(AsmToken::Comma)) {
3826 Parser.Lex(); // Eat the comma.
3827 // Parse and remember the operand.
3828 if (parseOperand(Operands, Name)) {
3829 SMLoc Loc = getLexer().getLoc();
3830 Parser.eatToEndOfStatement();
3831 return Error(Loc, "unexpected token in argument list");
3833 // Parse bracket and parenthesis suffixes before we iterate
3834 if (getLexer().is(AsmToken::LBrac)) {
3835 if (parseBracketSuffix(Name, Operands))
3837 } else if (getLexer().is(AsmToken::LParen) &&
3838 parseParenSuffix(Name, Operands))
3842 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3843 SMLoc Loc = getLexer().getLoc();
3844 Parser.eatToEndOfStatement();
3845 return Error(Loc, "unexpected token in argument list");
3847 Parser.Lex(); // Consume the EndOfStatement.
3851 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3852 MCAsmParser &Parser = getParser();
3853 SMLoc Loc = getLexer().getLoc();
3854 Parser.eatToEndOfStatement();
3855 return Error(Loc, ErrorMsg);
3858 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3859 return Error(Loc, ErrorMsg);
3862 bool MipsAsmParser::parseSetNoAtDirective() {
3863 MCAsmParser &Parser = getParser();
3864 // Line should look like: ".set noat".
3866 // Set the $at register to $0.
3867 AssemblerOptions.back()->setATRegIndex(0);
3869 Parser.Lex(); // Eat "noat".
3871 // If this is not the end of the statement, report an error.
3872 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3873 reportParseError("unexpected token, expected end of statement");
3877 getTargetStreamer().emitDirectiveSetNoAt();
3878 Parser.Lex(); // Consume the EndOfStatement.
3882 bool MipsAsmParser::parseSetAtDirective() {
3883 // Line can be: ".set at", which sets $at to $1
3884 // or ".set at=$reg", which sets $at to $reg.
3885 MCAsmParser &Parser = getParser();
3886 Parser.Lex(); // Eat "at".
3888 if (getLexer().is(AsmToken::EndOfStatement)) {
3889 // No register was specified, so we set $at to $1.
3890 AssemblerOptions.back()->setATRegIndex(1);
3892 getTargetStreamer().emitDirectiveSetAt();
3893 Parser.Lex(); // Consume the EndOfStatement.
3897 if (getLexer().isNot(AsmToken::Equal)) {
3898 reportParseError("unexpected token, expected equals sign");
3901 Parser.Lex(); // Eat "=".
3903 if (getLexer().isNot(AsmToken::Dollar)) {
3904 if (getLexer().is(AsmToken::EndOfStatement)) {
3905 reportParseError("no register specified");
3908 reportParseError("unexpected token, expected dollar sign '$'");
3912 Parser.Lex(); // Eat "$".
3914 // Find out what "reg" is.
3916 const AsmToken &Reg = Parser.getTok();
3917 if (Reg.is(AsmToken::Identifier)) {
3918 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3919 } else if (Reg.is(AsmToken::Integer)) {
3920 AtRegNo = Reg.getIntVal();
3922 reportParseError("unexpected token, expected identifier or integer");
3926 // Check if $reg is a valid register. If it is, set $at to $reg.
3927 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3928 reportParseError("invalid register");
3931 Parser.Lex(); // Eat "reg".
3933 // If this is not the end of the statement, report an error.
3934 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3935 reportParseError("unexpected token, expected end of statement");
3939 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3941 Parser.Lex(); // Consume the EndOfStatement.
3945 bool MipsAsmParser::parseSetReorderDirective() {
3946 MCAsmParser &Parser = getParser();
3948 // If this is not the end of the statement, report an error.
3949 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3950 reportParseError("unexpected token, expected end of statement");
3953 AssemblerOptions.back()->setReorder();
3954 getTargetStreamer().emitDirectiveSetReorder();
3955 Parser.Lex(); // Consume the EndOfStatement.
3959 bool MipsAsmParser::parseSetNoReorderDirective() {
3960 MCAsmParser &Parser = getParser();
3962 // If this is not the end of the statement, report an error.
3963 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3964 reportParseError("unexpected token, expected end of statement");
3967 AssemblerOptions.back()->setNoReorder();
3968 getTargetStreamer().emitDirectiveSetNoReorder();
3969 Parser.Lex(); // Consume the EndOfStatement.
3973 bool MipsAsmParser::parseSetMacroDirective() {
3974 MCAsmParser &Parser = getParser();
3976 // If this is not the end of the statement, report an error.
3977 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3978 reportParseError("unexpected token, expected end of statement");
3981 AssemblerOptions.back()->setMacro();
3982 getTargetStreamer().emitDirectiveSetMacro();
3983 Parser.Lex(); // Consume the EndOfStatement.
3987 bool MipsAsmParser::parseSetNoMacroDirective() {
3988 MCAsmParser &Parser = getParser();
3990 // If this is not the end of the statement, report an error.
3991 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3992 reportParseError("unexpected token, expected end of statement");
3995 if (AssemblerOptions.back()->isReorder()) {
3996 reportParseError("`noreorder' must be set before `nomacro'");
3999 AssemblerOptions.back()->setNoMacro();
4000 getTargetStreamer().emitDirectiveSetNoMacro();
4001 Parser.Lex(); // Consume the EndOfStatement.
4005 bool MipsAsmParser::parseSetMsaDirective() {
4006 MCAsmParser &Parser = getParser();
4009 // If this is not the end of the statement, report an error.
4010 if (getLexer().isNot(AsmToken::EndOfStatement))
4011 return reportParseError("unexpected token, expected end of statement");
4013 setFeatureBits(Mips::FeatureMSA, "msa");
4014 getTargetStreamer().emitDirectiveSetMsa();
4018 bool MipsAsmParser::parseSetNoMsaDirective() {
4019 MCAsmParser &Parser = getParser();
4022 // If this is not the end of the statement, report an error.
4023 if (getLexer().isNot(AsmToken::EndOfStatement))
4024 return reportParseError("unexpected token, expected end of statement");
4026 clearFeatureBits(Mips::FeatureMSA, "msa");
4027 getTargetStreamer().emitDirectiveSetNoMsa();
4031 bool MipsAsmParser::parseSetNoDspDirective() {
4032 MCAsmParser &Parser = getParser();
4033 Parser.Lex(); // Eat "nodsp".
4035 // If this is not the end of the statement, report an error.
4036 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4037 reportParseError("unexpected token, expected end of statement");
4041 clearFeatureBits(Mips::FeatureDSP, "dsp");
4042 getTargetStreamer().emitDirectiveSetNoDsp();
4046 bool MipsAsmParser::parseSetMips16Directive() {
4047 MCAsmParser &Parser = getParser();
4048 Parser.Lex(); // Eat "mips16".
4050 // If this is not the end of the statement, report an error.
4051 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4052 reportParseError("unexpected token, expected end of statement");
4056 setFeatureBits(Mips::FeatureMips16, "mips16");
4057 getTargetStreamer().emitDirectiveSetMips16();
4058 Parser.Lex(); // Consume the EndOfStatement.
4062 bool MipsAsmParser::parseSetNoMips16Directive() {
4063 MCAsmParser &Parser = getParser();
4064 Parser.Lex(); // Eat "nomips16".
4066 // If this is not the end of the statement, report an error.
4067 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4068 reportParseError("unexpected token, expected end of statement");
4072 clearFeatureBits(Mips::FeatureMips16, "mips16");
4073 getTargetStreamer().emitDirectiveSetNoMips16();
4074 Parser.Lex(); // Consume the EndOfStatement.
4078 bool MipsAsmParser::parseSetFpDirective() {
4079 MCAsmParser &Parser = getParser();
4080 MipsABIFlagsSection::FpABIKind FpAbiVal;
4081 // Line can be: .set fp=32
4084 Parser.Lex(); // Eat fp token
4085 AsmToken Tok = Parser.getTok();
4086 if (Tok.isNot(AsmToken::Equal)) {
4087 reportParseError("unexpected token, expected equals sign '='");
4090 Parser.Lex(); // Eat '=' token.
4091 Tok = Parser.getTok();
4093 if (!parseFpABIValue(FpAbiVal, ".set"))
4096 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4097 reportParseError("unexpected token, expected end of statement");
4100 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4101 Parser.Lex(); // Consume the EndOfStatement.
4105 bool MipsAsmParser::parseSetOddSPRegDirective() {
4106 MCAsmParser &Parser = getParser();
4108 Parser.Lex(); // Eat "oddspreg".
4109 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4110 reportParseError("unexpected token, expected end of statement");
4114 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4115 getTargetStreamer().emitDirectiveSetOddSPReg();
4119 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4120 MCAsmParser &Parser = getParser();
4122 Parser.Lex(); // Eat "nooddspreg".
4123 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4124 reportParseError("unexpected token, expected end of statement");
4128 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4129 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4133 bool MipsAsmParser::parseSetPopDirective() {
4134 MCAsmParser &Parser = getParser();
4135 SMLoc Loc = getLexer().getLoc();
4138 if (getLexer().isNot(AsmToken::EndOfStatement))
4139 return reportParseError("unexpected token, expected end of statement");
4141 // Always keep an element on the options "stack" to prevent the user
4142 // from changing the initial options. This is how we remember them.
4143 if (AssemblerOptions.size() == 2)
4144 return reportParseError(Loc, ".set pop with no .set push");
4146 AssemblerOptions.pop_back();
4147 setAvailableFeatures(
4148 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4149 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4151 getTargetStreamer().emitDirectiveSetPop();
4155 bool MipsAsmParser::parseSetPushDirective() {
4156 MCAsmParser &Parser = getParser();
4158 if (getLexer().isNot(AsmToken::EndOfStatement))
4159 return reportParseError("unexpected token, expected end of statement");
4161 // Create a copy of the current assembler options environment and push it.
4162 AssemblerOptions.push_back(
4163 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4165 getTargetStreamer().emitDirectiveSetPush();
4169 bool MipsAsmParser::parseSetSoftFloatDirective() {
4170 MCAsmParser &Parser = getParser();
4172 if (getLexer().isNot(AsmToken::EndOfStatement))
4173 return reportParseError("unexpected token, expected end of statement");
4175 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4176 getTargetStreamer().emitDirectiveSetSoftFloat();
4180 bool MipsAsmParser::parseSetHardFloatDirective() {
4181 MCAsmParser &Parser = getParser();
4183 if (getLexer().isNot(AsmToken::EndOfStatement))
4184 return reportParseError("unexpected token, expected end of statement");
4186 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4187 getTargetStreamer().emitDirectiveSetHardFloat();
4191 bool MipsAsmParser::parseSetAssignment() {
4193 const MCExpr *Value;
4194 MCAsmParser &Parser = getParser();
4196 if (Parser.parseIdentifier(Name))
4197 reportParseError("expected identifier after .set");
4199 if (getLexer().isNot(AsmToken::Comma))
4200 return reportParseError("unexpected token, expected comma");
4203 if (Parser.parseExpression(Value))
4204 return reportParseError("expected valid expression after comma");
4206 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4207 Sym->setVariableValue(Value);
4212 bool MipsAsmParser::parseSetMips0Directive() {
4213 MCAsmParser &Parser = getParser();
4215 if (getLexer().isNot(AsmToken::EndOfStatement))
4216 return reportParseError("unexpected token, expected end of statement");
4218 // Reset assembler options to their initial values.
4219 setAvailableFeatures(
4220 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4221 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4222 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4224 getTargetStreamer().emitDirectiveSetMips0();
4228 bool MipsAsmParser::parseSetArchDirective() {
4229 MCAsmParser &Parser = getParser();
4231 if (getLexer().isNot(AsmToken::Equal))
4232 return reportParseError("unexpected token, expected equals sign");
4236 if (Parser.parseIdentifier(Arch))
4237 return reportParseError("expected arch identifier");
4239 StringRef ArchFeatureName =
4240 StringSwitch<StringRef>(Arch)
4241 .Case("mips1", "mips1")
4242 .Case("mips2", "mips2")
4243 .Case("mips3", "mips3")
4244 .Case("mips4", "mips4")
4245 .Case("mips5", "mips5")
4246 .Case("mips32", "mips32")
4247 .Case("mips32r2", "mips32r2")
4248 .Case("mips32r3", "mips32r3")
4249 .Case("mips32r5", "mips32r5")
4250 .Case("mips32r6", "mips32r6")
4251 .Case("mips64", "mips64")
4252 .Case("mips64r2", "mips64r2")
4253 .Case("mips64r3", "mips64r3")
4254 .Case("mips64r5", "mips64r5")
4255 .Case("mips64r6", "mips64r6")
4256 .Case("cnmips", "cnmips")
4257 .Case("r4000", "mips3") // This is an implementation of Mips3.
4260 if (ArchFeatureName.empty())
4261 return reportParseError("unsupported architecture");
4263 selectArch(ArchFeatureName);
4264 getTargetStreamer().emitDirectiveSetArch(Arch);
4268 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4269 MCAsmParser &Parser = getParser();
4271 if (getLexer().isNot(AsmToken::EndOfStatement))
4272 return reportParseError("unexpected token, expected end of statement");
4276 llvm_unreachable("Unimplemented feature");
4277 case Mips::FeatureDSP:
4278 setFeatureBits(Mips::FeatureDSP, "dsp");
4279 getTargetStreamer().emitDirectiveSetDsp();
4281 case Mips::FeatureMicroMips:
4282 getTargetStreamer().emitDirectiveSetMicroMips();
4284 case Mips::FeatureMips1:
4285 selectArch("mips1");
4286 getTargetStreamer().emitDirectiveSetMips1();
4288 case Mips::FeatureMips2:
4289 selectArch("mips2");
4290 getTargetStreamer().emitDirectiveSetMips2();
4292 case Mips::FeatureMips3:
4293 selectArch("mips3");
4294 getTargetStreamer().emitDirectiveSetMips3();
4296 case Mips::FeatureMips4:
4297 selectArch("mips4");
4298 getTargetStreamer().emitDirectiveSetMips4();
4300 case Mips::FeatureMips5:
4301 selectArch("mips5");
4302 getTargetStreamer().emitDirectiveSetMips5();
4304 case Mips::FeatureMips32:
4305 selectArch("mips32");
4306 getTargetStreamer().emitDirectiveSetMips32();
4308 case Mips::FeatureMips32r2:
4309 selectArch("mips32r2");
4310 getTargetStreamer().emitDirectiveSetMips32R2();
4312 case Mips::FeatureMips32r3:
4313 selectArch("mips32r3");
4314 getTargetStreamer().emitDirectiveSetMips32R3();
4316 case Mips::FeatureMips32r5:
4317 selectArch("mips32r5");
4318 getTargetStreamer().emitDirectiveSetMips32R5();
4320 case Mips::FeatureMips32r6:
4321 selectArch("mips32r6");
4322 getTargetStreamer().emitDirectiveSetMips32R6();
4324 case Mips::FeatureMips64:
4325 selectArch("mips64");
4326 getTargetStreamer().emitDirectiveSetMips64();
4328 case Mips::FeatureMips64r2:
4329 selectArch("mips64r2");
4330 getTargetStreamer().emitDirectiveSetMips64R2();
4332 case Mips::FeatureMips64r3:
4333 selectArch("mips64r3");
4334 getTargetStreamer().emitDirectiveSetMips64R3();
4336 case Mips::FeatureMips64r5:
4337 selectArch("mips64r5");
4338 getTargetStreamer().emitDirectiveSetMips64R5();
4340 case Mips::FeatureMips64r6:
4341 selectArch("mips64r6");
4342 getTargetStreamer().emitDirectiveSetMips64R6();
4348 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4349 MCAsmParser &Parser = getParser();
4350 if (getLexer().isNot(AsmToken::Comma)) {
4351 SMLoc Loc = getLexer().getLoc();
4352 Parser.eatToEndOfStatement();
4353 return Error(Loc, ErrorStr);
4356 Parser.Lex(); // Eat the comma.
4360 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4361 if (AssemblerOptions.back()->isReorder())
4362 Warning(Loc, ".cpload should be inside a noreorder section");
4364 if (inMips16Mode()) {
4365 reportParseError(".cpload is not supported in Mips16 mode");
4369 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4370 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4371 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4372 reportParseError("expected register containing function address");
4376 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4377 if (!RegOpnd.isGPRAsmReg()) {
4378 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4382 // If this is not the end of the statement, report an error.
4383 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4384 reportParseError("unexpected token, expected end of statement");
4388 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4392 bool MipsAsmParser::parseDirectiveCPSetup() {
4393 MCAsmParser &Parser = getParser();
4396 bool SaveIsReg = true;
4398 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4399 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4400 if (ResTy == MatchOperand_NoMatch) {
4401 reportParseError("expected register containing function address");
4402 Parser.eatToEndOfStatement();
4406 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4407 if (!FuncRegOpnd.isGPRAsmReg()) {
4408 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4409 Parser.eatToEndOfStatement();
4413 FuncReg = FuncRegOpnd.getGPR32Reg();
4416 if (!eatComma("unexpected token, expected comma"))
4419 ResTy = parseAnyRegister(TmpReg);
4420 if (ResTy == MatchOperand_NoMatch) {
4421 const AsmToken &Tok = Parser.getTok();
4422 if (Tok.is(AsmToken::Integer)) {
4423 Save = Tok.getIntVal();
4427 reportParseError("expected save register or stack offset");
4428 Parser.eatToEndOfStatement();
4432 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4433 if (!SaveOpnd.isGPRAsmReg()) {
4434 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4435 Parser.eatToEndOfStatement();
4438 Save = SaveOpnd.getGPR32Reg();
4441 if (!eatComma("unexpected token, expected comma"))
4445 if (Parser.parseExpression(Expr)) {
4446 reportParseError("expected expression");
4450 if (Expr->getKind() != MCExpr::SymbolRef) {
4451 reportParseError("expected symbol");
4454 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4456 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4461 bool MipsAsmParser::parseDirectiveNaN() {
4462 MCAsmParser &Parser = getParser();
4463 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4464 const AsmToken &Tok = Parser.getTok();
4466 if (Tok.getString() == "2008") {
4468 getTargetStreamer().emitDirectiveNaN2008();
4470 } else if (Tok.getString() == "legacy") {
4472 getTargetStreamer().emitDirectiveNaNLegacy();
4476 // If we don't recognize the option passed to the .nan
4477 // directive (e.g. no option or unknown option), emit an error.
4478 reportParseError("invalid option in .nan directive");
4482 bool MipsAsmParser::parseDirectiveSet() {
4483 MCAsmParser &Parser = getParser();
4484 // Get the next token.
4485 const AsmToken &Tok = Parser.getTok();
4487 if (Tok.getString() == "noat") {
4488 return parseSetNoAtDirective();
4489 } else if (Tok.getString() == "at") {
4490 return parseSetAtDirective();
4491 } else if (Tok.getString() == "arch") {
4492 return parseSetArchDirective();
4493 } else if (Tok.getString() == "fp") {
4494 return parseSetFpDirective();
4495 } else if (Tok.getString() == "oddspreg") {
4496 return parseSetOddSPRegDirective();
4497 } else if (Tok.getString() == "nooddspreg") {
4498 return parseSetNoOddSPRegDirective();
4499 } else if (Tok.getString() == "pop") {
4500 return parseSetPopDirective();
4501 } else if (Tok.getString() == "push") {
4502 return parseSetPushDirective();
4503 } else if (Tok.getString() == "reorder") {
4504 return parseSetReorderDirective();
4505 } else if (Tok.getString() == "noreorder") {
4506 return parseSetNoReorderDirective();
4507 } else if (Tok.getString() == "macro") {
4508 return parseSetMacroDirective();
4509 } else if (Tok.getString() == "nomacro") {
4510 return parseSetNoMacroDirective();
4511 } else if (Tok.getString() == "mips16") {
4512 return parseSetMips16Directive();
4513 } else if (Tok.getString() == "nomips16") {
4514 return parseSetNoMips16Directive();
4515 } else if (Tok.getString() == "nomicromips") {
4516 getTargetStreamer().emitDirectiveSetNoMicroMips();
4517 Parser.eatToEndOfStatement();
4519 } else if (Tok.getString() == "micromips") {
4520 return parseSetFeature(Mips::FeatureMicroMips);
4521 } else if (Tok.getString() == "mips0") {
4522 return parseSetMips0Directive();
4523 } else if (Tok.getString() == "mips1") {
4524 return parseSetFeature(Mips::FeatureMips1);
4525 } else if (Tok.getString() == "mips2") {
4526 return parseSetFeature(Mips::FeatureMips2);
4527 } else if (Tok.getString() == "mips3") {
4528 return parseSetFeature(Mips::FeatureMips3);
4529 } else if (Tok.getString() == "mips4") {
4530 return parseSetFeature(Mips::FeatureMips4);
4531 } else if (Tok.getString() == "mips5") {
4532 return parseSetFeature(Mips::FeatureMips5);
4533 } else if (Tok.getString() == "mips32") {
4534 return parseSetFeature(Mips::FeatureMips32);
4535 } else if (Tok.getString() == "mips32r2") {
4536 return parseSetFeature(Mips::FeatureMips32r2);
4537 } else if (Tok.getString() == "mips32r3") {
4538 return parseSetFeature(Mips::FeatureMips32r3);
4539 } else if (Tok.getString() == "mips32r5") {
4540 return parseSetFeature(Mips::FeatureMips32r5);
4541 } else if (Tok.getString() == "mips32r6") {
4542 return parseSetFeature(Mips::FeatureMips32r6);
4543 } else if (Tok.getString() == "mips64") {
4544 return parseSetFeature(Mips::FeatureMips64);
4545 } else if (Tok.getString() == "mips64r2") {
4546 return parseSetFeature(Mips::FeatureMips64r2);
4547 } else if (Tok.getString() == "mips64r3") {
4548 return parseSetFeature(Mips::FeatureMips64r3);
4549 } else if (Tok.getString() == "mips64r5") {
4550 return parseSetFeature(Mips::FeatureMips64r5);
4551 } else if (Tok.getString() == "mips64r6") {
4552 return parseSetFeature(Mips::FeatureMips64r6);
4553 } else if (Tok.getString() == "dsp") {
4554 return parseSetFeature(Mips::FeatureDSP);
4555 } else if (Tok.getString() == "nodsp") {
4556 return parseSetNoDspDirective();
4557 } else if (Tok.getString() == "msa") {
4558 return parseSetMsaDirective();
4559 } else if (Tok.getString() == "nomsa") {
4560 return parseSetNoMsaDirective();
4561 } else if (Tok.getString() == "softfloat") {
4562 return parseSetSoftFloatDirective();
4563 } else if (Tok.getString() == "hardfloat") {
4564 return parseSetHardFloatDirective();
4566 // It is just an identifier, look for an assignment.
4567 parseSetAssignment();
4574 /// parseDataDirective
4575 /// ::= .word [ expression (, expression)* ]
4576 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4577 MCAsmParser &Parser = getParser();
4578 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4580 const MCExpr *Value;
4581 if (getParser().parseExpression(Value))
4584 getParser().getStreamer().EmitValue(Value, Size);
4586 if (getLexer().is(AsmToken::EndOfStatement))
4589 if (getLexer().isNot(AsmToken::Comma))
4590 return Error(L, "unexpected token, expected comma");
4599 /// parseDirectiveGpWord
4600 /// ::= .gpword local_sym
4601 bool MipsAsmParser::parseDirectiveGpWord() {
4602 MCAsmParser &Parser = getParser();
4603 const MCExpr *Value;
4604 // EmitGPRel32Value requires an expression, so we are using base class
4605 // method to evaluate the expression.
4606 if (getParser().parseExpression(Value))
4608 getParser().getStreamer().EmitGPRel32Value(Value);
4610 if (getLexer().isNot(AsmToken::EndOfStatement))
4611 return Error(getLexer().getLoc(),
4612 "unexpected token, expected end of statement");
4613 Parser.Lex(); // Eat EndOfStatement token.
4617 /// parseDirectiveGpDWord
4618 /// ::= .gpdword local_sym
4619 bool MipsAsmParser::parseDirectiveGpDWord() {
4620 MCAsmParser &Parser = getParser();
4621 const MCExpr *Value;
4622 // EmitGPRel64Value requires an expression, so we are using base class
4623 // method to evaluate the expression.
4624 if (getParser().parseExpression(Value))
4626 getParser().getStreamer().EmitGPRel64Value(Value);
4628 if (getLexer().isNot(AsmToken::EndOfStatement))
4629 return Error(getLexer().getLoc(),
4630 "unexpected token, expected end of statement");
4631 Parser.Lex(); // Eat EndOfStatement token.
4635 bool MipsAsmParser::parseDirectiveOption() {
4636 MCAsmParser &Parser = getParser();
4637 // Get the option token.
4638 AsmToken Tok = Parser.getTok();
4639 // At the moment only identifiers are supported.
4640 if (Tok.isNot(AsmToken::Identifier)) {
4641 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4642 Parser.eatToEndOfStatement();
4646 StringRef Option = Tok.getIdentifier();
4648 if (Option == "pic0") {
4649 getTargetStreamer().emitDirectiveOptionPic0();
4651 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4652 Error(Parser.getTok().getLoc(),
4653 "unexpected token, expected end of statement");
4654 Parser.eatToEndOfStatement();
4659 if (Option == "pic2") {
4660 getTargetStreamer().emitDirectiveOptionPic2();
4662 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4663 Error(Parser.getTok().getLoc(),
4664 "unexpected token, expected end of statement");
4665 Parser.eatToEndOfStatement();
4671 Warning(Parser.getTok().getLoc(),
4672 "unknown option, expected 'pic0' or 'pic2'");
4673 Parser.eatToEndOfStatement();
4677 /// parseInsnDirective
4679 bool MipsAsmParser::parseInsnDirective() {
4680 // If this is not the end of the statement, report an error.
4681 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4682 reportParseError("unexpected token, expected end of statement");
4686 // The actual label marking happens in
4687 // MipsELFStreamer::createPendingLabelRelocs().
4688 getTargetStreamer().emitDirectiveInsn();
4690 getParser().Lex(); // Eat EndOfStatement token.
4694 /// parseDirectiveModule
4695 /// ::= .module oddspreg
4696 /// ::= .module nooddspreg
4697 /// ::= .module fp=value
4698 bool MipsAsmParser::parseDirectiveModule() {
4699 MCAsmParser &Parser = getParser();
4700 MCAsmLexer &Lexer = getLexer();
4701 SMLoc L = Lexer.getLoc();
4703 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4704 // TODO : get a better message.
4705 reportParseError(".module directive must appear before any code");
4710 if (Parser.parseIdentifier(Option)) {
4711 reportParseError("expected .module option identifier");
4715 if (Option == "oddspreg") {
4716 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4718 // Synchronize the abiflags information with the FeatureBits information we
4720 getTargetStreamer().updateABIInfo(*this);
4722 // If printing assembly, use the recently updated abiflags information.
4723 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4724 // emitted at the end).
4725 getTargetStreamer().emitDirectiveModuleOddSPReg();
4727 // If this is not the end of the statement, report an error.
4728 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4729 reportParseError("unexpected token, expected end of statement");
4733 return false; // parseDirectiveModule has finished successfully.
4734 } else if (Option == "nooddspreg") {
4736 Error(L, "'.module nooddspreg' requires the O32 ABI");
4740 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4742 // Synchronize the abiflags information with the FeatureBits information we
4744 getTargetStreamer().updateABIInfo(*this);
4746 // If printing assembly, use the recently updated abiflags information.
4747 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4748 // emitted at the end).
4749 getTargetStreamer().emitDirectiveModuleOddSPReg();
4751 // If this is not the end of the statement, report an error.
4752 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4753 reportParseError("unexpected token, expected end of statement");
4757 return false; // parseDirectiveModule has finished successfully.
4758 } else if (Option == "fp") {
4759 return parseDirectiveModuleFP();
4761 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4765 /// parseDirectiveModuleFP
4769 bool MipsAsmParser::parseDirectiveModuleFP() {
4770 MCAsmParser &Parser = getParser();
4771 MCAsmLexer &Lexer = getLexer();
4773 if (Lexer.isNot(AsmToken::Equal)) {
4774 reportParseError("unexpected token, expected equals sign '='");
4777 Parser.Lex(); // Eat '=' token.
4779 MipsABIFlagsSection::FpABIKind FpABI;
4780 if (!parseFpABIValue(FpABI, ".module"))
4783 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4784 reportParseError("unexpected token, expected end of statement");
4788 // Synchronize the abiflags information with the FeatureBits information we
4790 getTargetStreamer().updateABIInfo(*this);
4792 // If printing assembly, use the recently updated abiflags information.
4793 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4794 // emitted at the end).
4795 getTargetStreamer().emitDirectiveModuleFP();
4797 Parser.Lex(); // Consume the EndOfStatement.
4801 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4802 StringRef Directive) {
4803 MCAsmParser &Parser = getParser();
4804 MCAsmLexer &Lexer = getLexer();
4806 if (Lexer.is(AsmToken::Identifier)) {
4807 StringRef Value = Parser.getTok().getString();
4810 if (Value != "xx") {
4811 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4816 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4820 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4821 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4822 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4826 if (Lexer.is(AsmToken::Integer)) {
4827 unsigned Value = Parser.getTok().getIntVal();
4830 if (Value != 32 && Value != 64) {
4831 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4837 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4841 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4842 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4843 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4845 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4846 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4847 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4856 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4857 MCAsmParser &Parser = getParser();
4858 StringRef IDVal = DirectiveID.getString();
4860 if (IDVal == ".cpload")
4861 return parseDirectiveCpLoad(DirectiveID.getLoc());
4862 if (IDVal == ".dword") {
4863 parseDataDirective(8, DirectiveID.getLoc());
4866 if (IDVal == ".ent") {
4867 StringRef SymbolName;
4869 if (Parser.parseIdentifier(SymbolName)) {
4870 reportParseError("expected identifier after .ent");
4874 // There's an undocumented extension that allows an integer to
4875 // follow the name of the procedure which AFAICS is ignored by GAS.
4876 // Example: .ent foo,2
4877 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4878 if (getLexer().isNot(AsmToken::Comma)) {
4879 // Even though we accept this undocumented extension for compatibility
4880 // reasons, the additional integer argument does not actually change
4881 // the behaviour of the '.ent' directive, so we would like to discourage
4882 // its use. We do this by not referring to the extended version in
4883 // error messages which are not directly related to its use.
4884 reportParseError("unexpected token, expected end of statement");
4887 Parser.Lex(); // Eat the comma.
4888 const MCExpr *DummyNumber;
4889 int64_t DummyNumberVal;
4890 // If the user was explicitly trying to use the extended version,
4891 // we still give helpful extension-related error messages.
4892 if (Parser.parseExpression(DummyNumber)) {
4893 reportParseError("expected number after comma");
4896 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4897 reportParseError("expected an absolute expression after comma");
4902 // If this is not the end of the statement, report an error.
4903 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4904 reportParseError("unexpected token, expected end of statement");
4908 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4910 getTargetStreamer().emitDirectiveEnt(*Sym);
4915 if (IDVal == ".end") {
4916 StringRef SymbolName;
4918 if (Parser.parseIdentifier(SymbolName)) {
4919 reportParseError("expected identifier after .end");
4923 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4924 reportParseError("unexpected token, expected end of statement");
4928 if (CurrentFn == nullptr) {
4929 reportParseError(".end used without .ent");
4933 if ((SymbolName != CurrentFn->getName())) {
4934 reportParseError(".end symbol does not match .ent symbol");
4938 getTargetStreamer().emitDirectiveEnd(SymbolName);
4939 CurrentFn = nullptr;
4943 if (IDVal == ".frame") {
4944 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4945 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4946 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4947 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4948 reportParseError("expected stack register");
4952 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4953 if (!StackRegOpnd.isGPRAsmReg()) {
4954 reportParseError(StackRegOpnd.getStartLoc(),
4955 "expected general purpose register");
4958 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4960 if (Parser.getTok().is(AsmToken::Comma))
4963 reportParseError("unexpected token, expected comma");
4967 // Parse the frame size.
4968 const MCExpr *FrameSize;
4969 int64_t FrameSizeVal;
4971 if (Parser.parseExpression(FrameSize)) {
4972 reportParseError("expected frame size value");
4976 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4977 reportParseError("frame size not an absolute expression");
4981 if (Parser.getTok().is(AsmToken::Comma))
4984 reportParseError("unexpected token, expected comma");
4988 // Parse the return register.
4990 ResTy = parseAnyRegister(TmpReg);
4991 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4992 reportParseError("expected return register");
4996 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4997 if (!ReturnRegOpnd.isGPRAsmReg()) {
4998 reportParseError(ReturnRegOpnd.getStartLoc(),
4999 "expected general purpose register");
5003 // If this is not the end of the statement, report an error.
5004 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5005 reportParseError("unexpected token, expected end of statement");
5009 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5010 ReturnRegOpnd.getGPR32Reg());
5014 if (IDVal == ".set") {
5015 return parseDirectiveSet();
5018 if (IDVal == ".mask" || IDVal == ".fmask") {
5019 // .mask bitmask, frame_offset
5020 // bitmask: One bit for each register used.
5021 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5022 // first register is expected to be saved.
5024 // .mask 0x80000000, -4
5025 // .fmask 0x80000000, -4
5028 // Parse the bitmask
5029 const MCExpr *BitMask;
5032 if (Parser.parseExpression(BitMask)) {
5033 reportParseError("expected bitmask value");
5037 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5038 reportParseError("bitmask not an absolute expression");
5042 if (Parser.getTok().is(AsmToken::Comma))
5045 reportParseError("unexpected token, expected comma");
5049 // Parse the frame_offset
5050 const MCExpr *FrameOffset;
5051 int64_t FrameOffsetVal;
5053 if (Parser.parseExpression(FrameOffset)) {
5054 reportParseError("expected frame offset value");
5058 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5059 reportParseError("frame offset not an absolute expression");
5063 // If this is not the end of the statement, report an error.
5064 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5065 reportParseError("unexpected token, expected end of statement");
5069 if (IDVal == ".mask")
5070 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5072 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5076 if (IDVal == ".nan")
5077 return parseDirectiveNaN();
5079 if (IDVal == ".gpword") {
5080 parseDirectiveGpWord();
5084 if (IDVal == ".gpdword") {
5085 parseDirectiveGpDWord();
5089 if (IDVal == ".word") {
5090 parseDataDirective(4, DirectiveID.getLoc());
5094 if (IDVal == ".option")
5095 return parseDirectiveOption();
5097 if (IDVal == ".abicalls") {
5098 getTargetStreamer().emitDirectiveAbiCalls();
5099 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5100 Error(Parser.getTok().getLoc(),
5101 "unexpected token, expected end of statement");
5103 Parser.eatToEndOfStatement();
5108 if (IDVal == ".cpsetup")
5109 return parseDirectiveCPSetup();
5111 if (IDVal == ".module")
5112 return parseDirectiveModule();
5114 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5115 return parseInternalDirectiveReallowModule();
5117 if (IDVal == ".insn")
5118 return parseInsnDirective();
5123 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5124 // If this is not the end of the statement, report an error.
5125 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5126 reportParseError("unexpected token, expected end of statement");
5130 getTargetStreamer().reallowModuleDirective();
5132 getParser().Lex(); // Eat EndOfStatement token.
5136 extern "C" void LLVMInitializeMipsAsmParser() {
5137 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5138 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5139 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5140 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5143 #define GET_REGISTER_MATCHER
5144 #define GET_MATCHER_IMPLEMENTATION
5145 #include "MipsGenAsmMatcher.inc"