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 bool MatchingInlineAsm) override;
132 /// Parse a register as used in CFI directives
133 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
135 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
137 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
139 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
140 SMLoc NameLoc, OperandVector &Operands) override;
142 bool ParseDirective(AsmToken DirectiveID) override;
144 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
148 StringRef Identifier, SMLoc S);
150 MipsAsmParser::OperandMatchResultTy
151 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
153 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
163 MipsAsmParser::OperandMatchResultTy
164 parseRegisterPair (OperandVector &Operands);
166 MipsAsmParser::OperandMatchResultTy
167 parseMovePRegPair(OperandVector &Operands);
169 MipsAsmParser::OperandMatchResultTy
170 parseRegisterList (OperandVector &Operands);
172 bool searchSymbolAlias(OperandVector &Operands);
174 bool parseOperand(OperandVector &, StringRef Mnemonic);
176 bool needsExpansion(MCInst &Inst);
178 // Expands assembly pseudo instructions.
179 // Returns false on success, true otherwise.
180 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
183 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
187 bool Is32BitImm, SMLoc IDLoc,
188 SmallVectorImpl<MCInst> &Instructions);
190 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
191 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
192 SmallVectorImpl<MCInst> &Instructions);
194 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
195 SmallVectorImpl<MCInst> &Instructions);
197 bool expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
202 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
205 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
209 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
210 SmallVectorImpl<MCInst> &Instructions);
212 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
213 SmallVectorImpl<MCInst> &Instructions);
215 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
228 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
230 bool reportParseError(Twine ErrorMsg);
231 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
233 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
234 bool parseRelocOperand(const MCExpr *&Res);
236 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
238 bool isEvaluated(const MCExpr *Expr);
239 bool parseSetMips0Directive();
240 bool parseSetArchDirective();
241 bool parseSetFeature(uint64_t Feature);
242 bool parseDirectiveCpLoad(SMLoc Loc);
243 bool parseDirectiveCPSetup();
244 bool parseDirectiveNaN();
245 bool parseDirectiveSet();
246 bool parseDirectiveOption();
247 bool parseInsnDirective();
249 bool parseSetAtDirective();
250 bool parseSetNoAtDirective();
251 bool parseSetMacroDirective();
252 bool parseSetNoMacroDirective();
253 bool parseSetMsaDirective();
254 bool parseSetNoMsaDirective();
255 bool parseSetNoDspDirective();
256 bool parseSetReorderDirective();
257 bool parseSetNoReorderDirective();
258 bool parseSetMips16Directive();
259 bool parseSetNoMips16Directive();
260 bool parseSetFpDirective();
261 bool parseSetOddSPRegDirective();
262 bool parseSetNoOddSPRegDirective();
263 bool parseSetPopDirective();
264 bool parseSetPushDirective();
265 bool parseSetSoftFloatDirective();
266 bool parseSetHardFloatDirective();
268 bool parseSetAssignment();
270 bool parseDataDirective(unsigned Size, SMLoc L);
271 bool parseDirectiveGpWord();
272 bool parseDirectiveGpDWord();
273 bool parseDirectiveModule();
274 bool parseDirectiveModuleFP();
275 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
276 StringRef Directive);
278 bool parseInternalDirectiveReallowModule();
280 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
282 bool eatComma(StringRef ErrorStr);
284 int matchCPURegisterName(StringRef Symbol);
286 int matchHWRegsRegisterName(StringRef Symbol);
288 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
290 int matchFPURegisterName(StringRef Name);
292 int matchFCCRegisterName(StringRef Name);
294 int matchACRegisterName(StringRef Name);
296 int matchMSA128RegisterName(StringRef Name);
298 int matchMSA128CtrlRegisterName(StringRef Name);
300 unsigned getReg(int RC, int RegNo);
302 unsigned getGPR(int RegNo);
304 /// Returns the internal register number for the current AT. Also checks if
305 /// the current AT is unavailable (set to $0) and gives an error if it is.
306 /// This should be used in pseudo-instruction expansions which need AT.
307 unsigned getATReg(SMLoc Loc);
309 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
310 SmallVectorImpl<MCInst> &Instructions);
312 // Helper function that checks if the value of a vector index is within the
313 // boundaries of accepted values for each RegisterKind
314 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
315 bool validateMSAIndex(int Val, int RegKind);
317 // Selects a new architecture by updating the FeatureBits with the necessary
318 // info including implied dependencies.
319 // Internally, it clears all the feature bits related to *any* architecture
320 // and selects the new one using the ToggleFeature functionality of the
321 // MCSubtargetInfo object that handles implied dependencies. The reason we
322 // clear all the arch related bits manually is because ToggleFeature only
323 // clears the features that imply the feature being cleared and not the
324 // features implied by the feature being cleared. This is easier to see
326 // --------------------------------------------------
327 // | Feature | Implies |
328 // | -------------------------------------------------|
329 // | FeatureMips1 | None |
330 // | FeatureMips2 | FeatureMips1 |
331 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
332 // | FeatureMips4 | FeatureMips3 |
334 // --------------------------------------------------
336 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
337 // FeatureMipsGP64 | FeatureMips1)
338 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
339 void selectArch(StringRef ArchFeature) {
340 FeatureBitset FeatureBits = STI.getFeatureBits();
341 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
342 STI.setFeatureBits(FeatureBits);
343 setAvailableFeatures(
344 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
345 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
348 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
349 if (!(STI.getFeatureBits()[Feature])) {
350 setAvailableFeatures(
351 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
352 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
356 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
357 if (STI.getFeatureBits()[Feature]) {
358 setAvailableFeatures(
359 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
360 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
365 enum MipsMatchResultTy {
366 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
367 #define GET_OPERAND_DIAGNOSTIC_TYPES
368 #include "MipsGenAsmMatcher.inc"
369 #undef GET_OPERAND_DIAGNOSTIC_TYPES
373 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
374 const MCInstrInfo &MII, const MCTargetOptions &Options)
375 : MCTargetAsmParser(), STI(sti),
376 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
377 sti.getCPU(), Options)) {
378 MCAsmParserExtension::Initialize(parser);
380 parser.addAliasForDirective(".asciiz", ".asciz");
382 // Initialize the set of available features.
383 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
385 // Remember the initial assembler options. The user can not modify these.
386 AssemblerOptions.push_back(
387 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
389 // Create an assembler options environment for the user to modify.
390 AssemblerOptions.push_back(
391 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
393 getTargetStreamer().updateABIInfo(*this);
395 if (!isABI_O32() && !useOddSPReg() != 0)
396 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
400 Triple TheTriple(sti.getTargetTriple());
401 if ((TheTriple.getArch() == Triple::mips) ||
402 (TheTriple.getArch() == Triple::mips64))
403 IsLittleEndian = false;
405 IsLittleEndian = true;
408 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
409 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
411 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
412 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
413 const MipsABIInfo &getABI() const { return ABI; }
414 bool isABI_N32() const { return ABI.IsN32(); }
415 bool isABI_N64() const { return ABI.IsN64(); }
416 bool isABI_O32() const { return ABI.IsO32(); }
417 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
419 bool useOddSPReg() const {
420 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
423 bool inMicroMipsMode() const {
424 return STI.getFeatureBits()[Mips::FeatureMicroMips];
426 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
427 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
428 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
429 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
430 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
431 bool hasMips32() const {
432 return STI.getFeatureBits()[Mips::FeatureMips32];
434 bool hasMips64() const {
435 return STI.getFeatureBits()[Mips::FeatureMips64];
437 bool hasMips32r2() const {
438 return STI.getFeatureBits()[Mips::FeatureMips32r2];
440 bool hasMips64r2() const {
441 return STI.getFeatureBits()[Mips::FeatureMips64r2];
443 bool hasMips32r3() const {
444 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
446 bool hasMips64r3() const {
447 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
449 bool hasMips32r5() const {
450 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
452 bool hasMips64r5() const {
453 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
455 bool hasMips32r6() const {
456 return STI.getFeatureBits()[Mips::FeatureMips32r6];
458 bool hasMips64r6() const {
459 return STI.getFeatureBits()[Mips::FeatureMips64r6];
462 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
463 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
464 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
465 bool hasCnMips() const {
466 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
469 bool inMips16Mode() const {
470 return STI.getFeatureBits()[Mips::FeatureMips16];
473 bool useSoftFloat() const {
474 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
477 /// Warn if RegIndex is the same as the current AT.
478 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
480 void warnIfNoMacro(SMLoc Loc);
482 bool isLittle() const { return IsLittleEndian; }
488 /// MipsOperand - Instances of this class represent a parsed Mips machine
490 class MipsOperand : public MCParsedAsmOperand {
492 /// Broad categories of register classes
493 /// The exact class is finalized by the render method.
495 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
496 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
498 RegKind_FCC = 4, /// FCC
499 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
500 RegKind_MSACtrl = 16, /// MSA control registers
501 RegKind_COP2 = 32, /// COP2
502 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
504 RegKind_CCR = 128, /// CCR
505 RegKind_HWRegs = 256, /// HWRegs
506 RegKind_COP3 = 512, /// COP3
507 RegKind_COP0 = 1024, /// COP0
508 /// Potentially any (e.g. $1)
509 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
510 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
511 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
516 k_Immediate, /// An immediate (possibly involving symbol references)
517 k_Memory, /// Base + Offset Memory Address
518 k_PhysRegister, /// A physical register from the Mips namespace
519 k_RegisterIndex, /// A register index in one or more RegKind.
520 k_Token, /// A simple token
521 k_RegList, /// A physical register list
522 k_RegPair /// A pair of physical register
526 MipsOperand(KindTy K, MipsAsmParser &Parser)
527 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
530 /// For diagnostics, and checking the assembler temporary
531 MipsAsmParser &AsmParser;
539 unsigned Num; /// Register Number
543 unsigned Index; /// Index into the register class
544 RegKind Kind; /// Bitfield of the kinds it could possibly be
545 const MCRegisterInfo *RegInfo;
558 SmallVector<unsigned, 10> *List;
563 struct PhysRegOp PhysReg;
564 struct RegIdxOp RegIdx;
567 struct RegListOp RegList;
570 SMLoc StartLoc, EndLoc;
572 /// Internal constructor for register kinds
573 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
574 const MCRegisterInfo *RegInfo,
576 MipsAsmParser &Parser) {
577 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
578 Op->RegIdx.Index = Index;
579 Op->RegIdx.RegInfo = RegInfo;
580 Op->RegIdx.Kind = RegKind;
587 /// Coerce the register to GPR32 and return the real register for the current
589 unsigned getGPR32Reg() const {
590 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
591 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
592 unsigned ClassID = Mips::GPR32RegClassID;
593 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
596 /// Coerce the register to GPR32 and return the real register for the current
598 unsigned getGPRMM16Reg() const {
599 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
600 unsigned ClassID = Mips::GPR32RegClassID;
601 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
604 /// Coerce the register to GPR64 and return the real register for the current
606 unsigned getGPR64Reg() const {
607 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
608 unsigned ClassID = Mips::GPR64RegClassID;
609 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
613 /// Coerce the register to AFGR64 and return the real register for the current
615 unsigned getAFGR64Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
617 if (RegIdx.Index % 2 != 0)
618 AsmParser.Warning(StartLoc, "Float register should be even.");
619 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
620 .getRegister(RegIdx.Index / 2);
623 /// Coerce the register to FGR64 and return the real register for the current
625 unsigned getFGR64Reg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
627 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
628 .getRegister(RegIdx.Index);
631 /// Coerce the register to FGR32 and return the real register for the current
633 unsigned getFGR32Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
635 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
636 .getRegister(RegIdx.Index);
639 /// Coerce the register to FGRH32 and return the real register for the current
641 unsigned getFGRH32Reg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
643 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
644 .getRegister(RegIdx.Index);
647 /// Coerce the register to FCC and return the real register for the current
649 unsigned getFCCReg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
651 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
652 .getRegister(RegIdx.Index);
655 /// Coerce the register to MSA128 and return the real register for the current
657 unsigned getMSA128Reg() const {
658 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
659 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
661 unsigned ClassID = Mips::MSA128BRegClassID;
662 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
665 /// Coerce the register to MSACtrl and return the real register for the
667 unsigned getMSACtrlReg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
669 unsigned ClassID = Mips::MSACtrlRegClassID;
670 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
673 /// Coerce the register to COP0 and return the real register for the
675 unsigned getCOP0Reg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
677 unsigned ClassID = Mips::COP0RegClassID;
678 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
681 /// Coerce the register to COP2 and return the real register for the
683 unsigned getCOP2Reg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
685 unsigned ClassID = Mips::COP2RegClassID;
686 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
689 /// Coerce the register to COP3 and return the real register for the
691 unsigned getCOP3Reg() const {
692 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
693 unsigned ClassID = Mips::COP3RegClassID;
694 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
697 /// Coerce the register to ACC64DSP and return the real register for the
699 unsigned getACC64DSPReg() const {
700 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
701 unsigned ClassID = Mips::ACC64DSPRegClassID;
702 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
705 /// Coerce the register to HI32DSP and return the real register for the
707 unsigned getHI32DSPReg() const {
708 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
709 unsigned ClassID = Mips::HI32DSPRegClassID;
710 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
713 /// Coerce the register to LO32DSP and return the real register for the
715 unsigned getLO32DSPReg() const {
716 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
717 unsigned ClassID = Mips::LO32DSPRegClassID;
718 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
721 /// Coerce the register to CCR and return the real register for the
723 unsigned getCCRReg() const {
724 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
725 unsigned ClassID = Mips::CCRRegClassID;
726 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
729 /// Coerce the register to HWRegs and return the real register for the
731 unsigned getHWRegsReg() const {
732 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
733 unsigned ClassID = Mips::HWRegsRegClassID;
734 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
738 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
739 // Add as immediate when possible. Null MCExpr = 0.
741 Inst.addOperand(MCOperand::createImm(0));
742 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
743 Inst.addOperand(MCOperand::createImm(CE->getValue()));
745 Inst.addOperand(MCOperand::createExpr(Expr));
748 void addRegOperands(MCInst &Inst, unsigned N) const {
749 llvm_unreachable("Use a custom parser instead");
752 /// Render the operand to an MCInst as a GPR32
753 /// Asserts if the wrong number of operands are requested, or the operand
754 /// is not a k_RegisterIndex compatible with RegKind_GPR
755 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
756 assert(N == 1 && "Invalid number of operands!");
757 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
760 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
761 assert(N == 1 && "Invalid number of operands!");
762 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
765 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 1 && "Invalid number of operands!");
767 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
770 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
771 assert(N == 1 && "Invalid number of operands!");
772 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
775 /// Render the operand to an MCInst as a GPR64
776 /// Asserts if the wrong number of operands are requested, or the operand
777 /// is not a k_RegisterIndex compatible with RegKind_GPR
778 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
783 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
788 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
793 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
796 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
797 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
798 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
802 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
803 assert(N == 1 && "Invalid number of operands!");
804 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
807 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
808 assert(N == 1 && "Invalid number of operands!");
809 Inst.addOperand(MCOperand::createReg(getFCCReg()));
812 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
813 assert(N == 1 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
817 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
822 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 1 && "Invalid number of operands!");
824 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
827 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 1 && "Invalid number of operands!");
829 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
832 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 1 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
837 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!");
839 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
842 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 1 && "Invalid number of operands!");
844 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
847 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
849 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
852 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
853 assert(N == 1 && "Invalid number of operands!");
854 Inst.addOperand(MCOperand::createReg(getCCRReg()));
857 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
858 assert(N == 1 && "Invalid number of operands!");
859 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
862 void addImmOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 1 && "Invalid number of operands!");
864 const MCExpr *Expr = getImm();
868 void addMemOperands(MCInst &Inst, unsigned N) const {
869 assert(N == 2 && "Invalid number of operands!");
871 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
873 const MCExpr *Expr = getMemOff();
877 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
878 assert(N == 2 && "Invalid number of operands!");
880 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
882 const MCExpr *Expr = getMemOff();
886 void addRegListOperands(MCInst &Inst, unsigned N) const {
887 assert(N == 1 && "Invalid number of operands!");
889 for (auto RegNo : getRegList())
890 Inst.addOperand(MCOperand::createReg(RegNo));
893 void addRegPairOperands(MCInst &Inst, unsigned N) const {
894 assert(N == 2 && "Invalid number of operands!");
895 unsigned RegNo = getRegPair();
896 Inst.addOperand(MCOperand::createReg(RegNo++));
897 Inst.addOperand(MCOperand::createReg(RegNo));
900 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
901 assert(N == 2 && "Invalid number of operands!");
902 for (auto RegNo : getRegList())
903 Inst.addOperand(MCOperand::createReg(RegNo));
906 bool isReg() const override {
907 // As a special case until we sort out the definition of div/divu, pretend
908 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
909 if (isGPRAsmReg() && RegIdx.Index == 0)
912 return Kind == k_PhysRegister;
914 bool isRegIdx() const { return Kind == k_RegisterIndex; }
915 bool isImm() const override { return Kind == k_Immediate; }
916 bool isConstantImm() const {
917 return isImm() && dyn_cast<MCConstantExpr>(getImm());
919 template <unsigned Bits> bool isUImm() const {
920 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
922 bool isToken() const override {
923 // Note: It's not possible to pretend that other operand kinds are tokens.
924 // The matcher emitter checks tokens first.
925 return Kind == k_Token;
927 bool isMem() const override { return Kind == k_Memory; }
928 bool isConstantMemOff() const {
929 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
931 template <unsigned Bits> bool isMemWithSimmOffset() const {
932 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
934 bool isMemWithGRPMM16Base() const {
935 return isMem() && getMemBase()->isMM16AsmReg();
937 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
938 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
939 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
941 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
942 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
943 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
944 && (getMemBase()->getGPR32Reg() == Mips::SP);
946 bool isRegList16() const {
950 int Size = RegList.List->size();
951 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
952 RegList.List->back() != Mips::RA)
955 int PrevReg = *RegList.List->begin();
956 for (int i = 1; i < Size - 1; i++) {
957 int Reg = (*(RegList.List))[i];
958 if ( Reg != PrevReg + 1)
965 bool isInvNum() const { return Kind == k_Immediate; }
966 bool isLSAImm() const {
967 if (!isConstantImm())
969 int64_t Val = getConstantImm();
970 return 1 <= Val && Val <= 4;
972 bool isRegList() const { return Kind == k_RegList; }
973 bool isMovePRegPair() const {
974 if (Kind != k_RegList || RegList.List->size() != 2)
977 unsigned R0 = RegList.List->front();
978 unsigned R1 = RegList.List->back();
980 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
981 (R0 == Mips::A1 && R1 == Mips::A3) ||
982 (R0 == Mips::A2 && R1 == Mips::A3) ||
983 (R0 == Mips::A0 && R1 == Mips::S5) ||
984 (R0 == Mips::A0 && R1 == Mips::S6) ||
985 (R0 == Mips::A0 && R1 == Mips::A1) ||
986 (R0 == Mips::A0 && R1 == Mips::A2) ||
987 (R0 == Mips::A0 && R1 == Mips::A3))
993 StringRef getToken() const {
994 assert(Kind == k_Token && "Invalid access!");
995 return StringRef(Tok.Data, Tok.Length);
997 bool isRegPair() const { return Kind == k_RegPair; }
999 unsigned getReg() const override {
1000 // As a special case until we sort out the definition of div/divu, pretend
1001 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1002 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1003 RegIdx.Kind & RegKind_GPR)
1004 return getGPR32Reg(); // FIXME: GPR64 too
1006 assert(Kind == k_PhysRegister && "Invalid access!");
1010 const MCExpr *getImm() const {
1011 assert((Kind == k_Immediate) && "Invalid access!");
1015 int64_t getConstantImm() const {
1016 const MCExpr *Val = getImm();
1017 return static_cast<const MCConstantExpr *>(Val)->getValue();
1020 MipsOperand *getMemBase() const {
1021 assert((Kind == k_Memory) && "Invalid access!");
1025 const MCExpr *getMemOff() const {
1026 assert((Kind == k_Memory) && "Invalid access!");
1030 int64_t getConstantMemOff() const {
1031 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1034 const SmallVectorImpl<unsigned> &getRegList() const {
1035 assert((Kind == k_RegList) && "Invalid access!");
1036 return *(RegList.List);
1039 unsigned getRegPair() const {
1040 assert((Kind == k_RegPair) && "Invalid access!");
1041 return RegIdx.Index;
1044 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1045 MipsAsmParser &Parser) {
1046 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1047 Op->Tok.Data = Str.data();
1048 Op->Tok.Length = Str.size();
1054 /// Create a numeric register (e.g. $1). The exact register remains
1055 /// unresolved until an instruction successfully matches
1056 static std::unique_ptr<MipsOperand>
1057 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1058 SMLoc E, MipsAsmParser &Parser) {
1059 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1060 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1063 /// Create a register that is definitely a GPR.
1064 /// This is typically only used for named registers such as $gp.
1065 static std::unique_ptr<MipsOperand>
1066 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1067 MipsAsmParser &Parser) {
1068 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1071 /// Create a register that is definitely a FGR.
1072 /// This is typically only used for named registers such as $f0.
1073 static std::unique_ptr<MipsOperand>
1074 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1075 MipsAsmParser &Parser) {
1076 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1079 /// Create a register that is definitely a HWReg.
1080 /// This is typically only used for named registers such as $hwr_cpunum.
1081 static std::unique_ptr<MipsOperand>
1082 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1083 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1084 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1087 /// Create a register that is definitely an FCC.
1088 /// This is typically only used for named registers such as $fcc0.
1089 static std::unique_ptr<MipsOperand>
1090 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1091 MipsAsmParser &Parser) {
1092 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1095 /// Create a register that is definitely an ACC.
1096 /// This is typically only used for named registers such as $ac0.
1097 static std::unique_ptr<MipsOperand>
1098 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1099 MipsAsmParser &Parser) {
1100 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1103 /// Create a register that is definitely an MSA128.
1104 /// This is typically only used for named registers such as $w0.
1105 static std::unique_ptr<MipsOperand>
1106 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1107 SMLoc E, MipsAsmParser &Parser) {
1108 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1111 /// Create a register that is definitely an MSACtrl.
1112 /// This is typically only used for named registers such as $msaaccess.
1113 static std::unique_ptr<MipsOperand>
1114 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1115 SMLoc E, MipsAsmParser &Parser) {
1116 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1119 static std::unique_ptr<MipsOperand>
1120 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1121 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1128 static std::unique_ptr<MipsOperand>
1129 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1130 SMLoc E, MipsAsmParser &Parser) {
1131 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1132 Op->Mem.Base = Base.release();
1139 static std::unique_ptr<MipsOperand>
1140 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1141 MipsAsmParser &Parser) {
1142 assert (Regs.size() > 0 && "Empty list not allowed");
1144 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1145 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1146 Op->StartLoc = StartLoc;
1147 Op->EndLoc = EndLoc;
1151 static std::unique_ptr<MipsOperand>
1152 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1153 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1154 Op->RegIdx.Index = RegNo;
1160 bool isGPRAsmReg() const {
1161 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1163 bool isMM16AsmReg() const {
1164 if (!(isRegIdx() && RegIdx.Kind))
1166 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1167 || RegIdx.Index == 16 || RegIdx.Index == 17);
1169 bool isMM16AsmRegZero() const {
1170 if (!(isRegIdx() && RegIdx.Kind))
1172 return (RegIdx.Index == 0 ||
1173 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1174 RegIdx.Index == 17);
1176 bool isMM16AsmRegMoveP() const {
1177 if (!(isRegIdx() && RegIdx.Kind))
1179 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1180 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1182 bool isFGRAsmReg() const {
1183 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1184 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1186 bool isHWRegsAsmReg() const {
1187 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1189 bool isCCRAsmReg() const {
1190 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1192 bool isFCCAsmReg() const {
1193 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1195 if (!AsmParser.hasEightFccRegisters())
1196 return RegIdx.Index == 0;
1197 return RegIdx.Index <= 7;
1199 bool isACCAsmReg() const {
1200 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1202 bool isCOP0AsmReg() const {
1203 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1205 bool isCOP2AsmReg() const {
1206 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1208 bool isCOP3AsmReg() const {
1209 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1211 bool isMSA128AsmReg() const {
1212 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1214 bool isMSACtrlAsmReg() const {
1215 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1218 /// getStartLoc - Get the location of the first token of this operand.
1219 SMLoc getStartLoc() const override { return StartLoc; }
1220 /// getEndLoc - Get the location of the last token of this operand.
1221 SMLoc getEndLoc() const override { return EndLoc; }
1223 virtual ~MipsOperand() {
1231 delete RegList.List;
1232 case k_PhysRegister:
1233 case k_RegisterIndex:
1240 void print(raw_ostream &OS) const override {
1249 Mem.Base->print(OS);
1254 case k_PhysRegister:
1255 OS << "PhysReg<" << PhysReg.Num << ">";
1257 case k_RegisterIndex:
1258 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1265 for (auto Reg : (*RegList.List))
1270 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1274 }; // class MipsOperand
1278 extern const MCInstrDesc MipsInsts[];
1280 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1281 return MipsInsts[Opcode];
1284 static bool hasShortDelaySlot(unsigned Opcode) {
1287 case Mips::JALRS_MM:
1288 case Mips::JALRS16_MM:
1289 case Mips::BGEZALS_MM:
1290 case Mips::BLTZALS_MM:
1297 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1298 SmallVectorImpl<MCInst> &Instructions) {
1299 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1303 if (MCID.isBranch() || MCID.isCall()) {
1304 const unsigned Opcode = Inst.getOpcode();
1314 assert(hasCnMips() && "instruction only valid for octeon cpus");
1321 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1322 Offset = Inst.getOperand(2);
1323 if (!Offset.isImm())
1324 break; // We'll deal with this situation later on when applying fixups.
1325 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1326 return Error(IDLoc, "branch target out of range");
1327 if (OffsetToAlignment(Offset.getImm(),
1328 1LL << (inMicroMipsMode() ? 1 : 2)))
1329 return Error(IDLoc, "branch to misaligned address");
1343 case Mips::BGEZAL_MM:
1344 case Mips::BLTZAL_MM:
1347 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1348 Offset = Inst.getOperand(1);
1349 if (!Offset.isImm())
1350 break; // We'll deal with this situation later on when applying fixups.
1351 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1352 return Error(IDLoc, "branch target out of range");
1353 if (OffsetToAlignment(Offset.getImm(),
1354 1LL << (inMicroMipsMode() ? 1 : 2)))
1355 return Error(IDLoc, "branch to misaligned address");
1357 case Mips::BEQZ16_MM:
1358 case Mips::BNEZ16_MM:
1359 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1360 Offset = Inst.getOperand(1);
1361 if (!Offset.isImm())
1362 break; // We'll deal with this situation later on when applying fixups.
1363 if (!isIntN(8, Offset.getImm()))
1364 return Error(IDLoc, "branch target out of range");
1365 if (OffsetToAlignment(Offset.getImm(), 2LL))
1366 return Error(IDLoc, "branch to misaligned address");
1371 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1372 // We still accept it but it is a normal nop.
1373 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1374 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1375 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1380 const unsigned Opcode = Inst.getOpcode();
1392 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1393 // The offset is handled above
1394 Opnd = Inst.getOperand(1);
1396 return Error(IDLoc, "expected immediate operand kind");
1397 Imm = Opnd.getImm();
1398 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1399 Opcode == Mips::BBIT1 ? 63 : 31))
1400 return Error(IDLoc, "immediate operand value out of range");
1402 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1404 Inst.getOperand(1).setImm(Imm - 32);
1412 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1414 Opnd = Inst.getOperand(3);
1416 return Error(IDLoc, "expected immediate operand kind");
1417 Imm = Opnd.getImm();
1418 if (Imm < 0 || Imm > 31)
1419 return Error(IDLoc, "immediate operand value out of range");
1421 Opnd = Inst.getOperand(2);
1423 return Error(IDLoc, "expected immediate operand kind");
1424 Imm = Opnd.getImm();
1425 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1426 Opcode == Mips::EXTS ? 63 : 31))
1427 return Error(IDLoc, "immediate operand value out of range");
1429 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1430 Inst.getOperand(2).setImm(Imm - 32);
1436 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1437 Opnd = Inst.getOperand(2);
1439 return Error(IDLoc, "expected immediate operand kind");
1440 Imm = Opnd.getImm();
1441 if (!isInt<10>(Imm))
1442 return Error(IDLoc, "immediate operand value out of range");
1447 if (MCID.mayLoad() || MCID.mayStore()) {
1448 // Check the offset of memory operand, if it is a symbol
1449 // reference or immediate we may have to expand instructions.
1450 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1451 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1452 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1453 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1454 MCOperand &Op = Inst.getOperand(i);
1456 int MemOffset = Op.getImm();
1457 if (MemOffset < -32768 || MemOffset > 32767) {
1458 // Offset can't exceed 16bit value.
1459 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1462 } else if (Op.isExpr()) {
1463 const MCExpr *Expr = Op.getExpr();
1464 if (Expr->getKind() == MCExpr::SymbolRef) {
1465 const MCSymbolRefExpr *SR =
1466 static_cast<const MCSymbolRefExpr *>(Expr);
1467 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1469 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1472 } else if (!isEvaluated(Expr)) {
1473 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1481 if (inMicroMipsMode()) {
1482 if (MCID.mayLoad()) {
1483 // Try to create 16-bit GP relative load instruction.
1484 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1485 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1486 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1487 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1488 MCOperand &Op = Inst.getOperand(i);
1490 int MemOffset = Op.getImm();
1491 MCOperand &DstReg = Inst.getOperand(0);
1492 MCOperand &BaseReg = Inst.getOperand(1);
1493 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1494 getContext().getRegisterInfo()->getRegClass(
1495 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1496 BaseReg.getReg() == Mips::GP) {
1498 TmpInst.setLoc(IDLoc);
1499 TmpInst.setOpcode(Mips::LWGP_MM);
1500 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1501 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1502 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1503 Instructions.push_back(TmpInst);
1511 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1516 switch (Inst.getOpcode()) {
1519 case Mips::ADDIUS5_MM:
1520 Opnd = Inst.getOperand(2);
1522 return Error(IDLoc, "expected immediate operand kind");
1523 Imm = Opnd.getImm();
1524 if (Imm < -8 || Imm > 7)
1525 return Error(IDLoc, "immediate operand value out of range");
1527 case Mips::ADDIUSP_MM:
1528 Opnd = Inst.getOperand(0);
1530 return Error(IDLoc, "expected immediate operand kind");
1531 Imm = Opnd.getImm();
1532 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1534 return Error(IDLoc, "immediate operand value out of range");
1536 case Mips::SLL16_MM:
1537 case Mips::SRL16_MM:
1538 Opnd = Inst.getOperand(2);
1540 return Error(IDLoc, "expected immediate operand kind");
1541 Imm = Opnd.getImm();
1542 if (Imm < 1 || Imm > 8)
1543 return Error(IDLoc, "immediate operand value out of range");
1546 Opnd = Inst.getOperand(1);
1548 return Error(IDLoc, "expected immediate operand kind");
1549 Imm = Opnd.getImm();
1550 if (Imm < -1 || Imm > 126)
1551 return Error(IDLoc, "immediate operand value out of range");
1553 case Mips::ADDIUR2_MM:
1554 Opnd = Inst.getOperand(2);
1556 return Error(IDLoc, "expected immediate operand kind");
1557 Imm = Opnd.getImm();
1558 if (!(Imm == 1 || Imm == -1 ||
1559 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1560 return Error(IDLoc, "immediate operand value out of range");
1562 case Mips::ADDIUR1SP_MM:
1563 Opnd = Inst.getOperand(1);
1565 return Error(IDLoc, "expected immediate operand kind");
1566 Imm = Opnd.getImm();
1567 if (OffsetToAlignment(Imm, 4LL))
1568 return Error(IDLoc, "misaligned immediate operand value");
1569 if (Imm < 0 || Imm > 255)
1570 return Error(IDLoc, "immediate operand value out of range");
1572 case Mips::ANDI16_MM:
1573 Opnd = Inst.getOperand(2);
1575 return Error(IDLoc, "expected immediate operand kind");
1576 Imm = Opnd.getImm();
1577 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1578 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1579 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1580 return Error(IDLoc, "immediate operand value out of range");
1582 case Mips::LBU16_MM:
1583 Opnd = Inst.getOperand(2);
1585 return Error(IDLoc, "expected immediate operand kind");
1586 Imm = Opnd.getImm();
1587 if (Imm < -1 || Imm > 14)
1588 return Error(IDLoc, "immediate operand value out of range");
1591 Opnd = Inst.getOperand(2);
1593 return Error(IDLoc, "expected immediate operand kind");
1594 Imm = Opnd.getImm();
1595 if (Imm < 0 || Imm > 15)
1596 return Error(IDLoc, "immediate operand value out of range");
1598 case Mips::LHU16_MM:
1600 Opnd = Inst.getOperand(2);
1602 return Error(IDLoc, "expected immediate operand kind");
1603 Imm = Opnd.getImm();
1604 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1605 return Error(IDLoc, "immediate operand value out of range");
1609 Opnd = Inst.getOperand(2);
1611 return Error(IDLoc, "expected immediate operand kind");
1612 Imm = Opnd.getImm();
1613 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1614 return Error(IDLoc, "immediate operand value out of range");
1618 Opnd = Inst.getOperand(2);
1620 return Error(IDLoc, "expected immediate operand kind");
1621 Imm = Opnd.getImm();
1622 if (!isUInt<5>(Imm))
1623 return Error(IDLoc, "immediate operand value out of range");
1625 case Mips::ADDIUPC_MM:
1626 MCOperand Opnd = Inst.getOperand(1);
1628 return Error(IDLoc, "expected immediate operand kind");
1629 int Imm = Opnd.getImm();
1630 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1631 return Error(IDLoc, "immediate operand value out of range");
1636 if (needsExpansion(Inst)) {
1637 if (expandInstruction(Inst, IDLoc, Instructions))
1640 Instructions.push_back(Inst);
1642 // If this instruction has a delay slot and .set reorder is active,
1643 // emit a NOP after it.
1644 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1645 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1650 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1652 switch (Inst.getOpcode()) {
1653 case Mips::LoadImm32:
1654 case Mips::LoadImm64:
1655 case Mips::LoadAddrImm32:
1656 case Mips::LoadAddrReg32:
1657 case Mips::B_MM_Pseudo:
1660 case Mips::JalOneReg:
1661 case Mips::JalTwoReg:
1680 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1681 SmallVectorImpl<MCInst> &Instructions) {
1682 switch (Inst.getOpcode()) {
1683 default: llvm_unreachable("unimplemented expansion");
1684 case Mips::LoadImm32:
1685 return expandLoadImm(Inst, true, IDLoc, Instructions);
1686 case Mips::LoadImm64:
1687 return expandLoadImm(Inst, false, IDLoc, Instructions);
1688 case Mips::LoadAddrImm32:
1689 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1690 case Mips::LoadAddrReg32:
1691 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1692 case Mips::B_MM_Pseudo:
1693 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1696 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1697 case Mips::JalOneReg:
1698 case Mips::JalTwoReg:
1699 return expandJalWithRegs(Inst, IDLoc, Instructions);
1702 return expandBranchImm(Inst, IDLoc, Instructions);
1711 return expandCondBranches(Inst, IDLoc, Instructions);
1713 return expandUlhu(Inst, IDLoc, Instructions);
1715 return expandUlw(Inst, IDLoc, Instructions);
1720 template <unsigned ShiftAmount>
1721 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1722 SmallVectorImpl<MCInst> &Instructions) {
1724 if (ShiftAmount >= 32) {
1725 tmpInst.setOpcode(Mips::DSLL32);
1726 tmpInst.addOperand(MCOperand::createReg(RegNo));
1727 tmpInst.addOperand(MCOperand::createReg(RegNo));
1728 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1729 tmpInst.setLoc(IDLoc);
1730 Instructions.push_back(tmpInst);
1732 } else if (ShiftAmount > 0) {
1733 tmpInst.setOpcode(Mips::DSLL);
1734 tmpInst.addOperand(MCOperand::createReg(RegNo));
1735 tmpInst.addOperand(MCOperand::createReg(RegNo));
1736 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1737 tmpInst.setLoc(IDLoc);
1738 Instructions.push_back(tmpInst);
1741 // There's no need for an ORi if the immediate is 0.
1742 if (Operand.isImm() && Operand.getImm() == 0)
1745 tmpInst.setOpcode(Mips::ORi);
1746 tmpInst.addOperand(MCOperand::createReg(RegNo));
1747 tmpInst.addOperand(MCOperand::createReg(RegNo));
1748 tmpInst.addOperand(Operand);
1749 tmpInst.setLoc(IDLoc);
1750 Instructions.push_back(tmpInst);
1753 template <unsigned ShiftAmount>
1754 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1755 SmallVectorImpl<MCInst> &Instructions) {
1756 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1761 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1762 SmallVectorImpl<MCInst> &Instructions) {
1763 // Create a JALR instruction which is going to replace the pseudo-JAL.
1765 JalrInst.setLoc(IDLoc);
1766 const MCOperand FirstRegOp = Inst.getOperand(0);
1767 const unsigned Opcode = Inst.getOpcode();
1769 if (Opcode == Mips::JalOneReg) {
1770 // jal $rs => jalr $rs
1771 if (inMicroMipsMode()) {
1772 JalrInst.setOpcode(Mips::JALR16_MM);
1773 JalrInst.addOperand(FirstRegOp);
1775 JalrInst.setOpcode(Mips::JALR);
1776 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1777 JalrInst.addOperand(FirstRegOp);
1779 } else if (Opcode == Mips::JalTwoReg) {
1780 // jal $rd, $rs => jalr $rd, $rs
1781 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1782 JalrInst.addOperand(FirstRegOp);
1783 const MCOperand SecondRegOp = Inst.getOperand(1);
1784 JalrInst.addOperand(SecondRegOp);
1786 Instructions.push_back(JalrInst);
1788 // If .set reorder is active, emit a NOP after it.
1789 if (AssemblerOptions.back()->isReorder()) {
1790 // This is a 32-bit NOP because these 2 pseudo-instructions
1791 // do not have a short delay slot.
1793 NopInst.setOpcode(Mips::SLL);
1794 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1795 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1796 NopInst.addOperand(MCOperand::createImm(0));
1797 Instructions.push_back(NopInst);
1803 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1804 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1805 SmallVectorImpl<MCInst> &Instructions) {
1806 if (!Is32BitImm && !isGP64bit()) {
1807 Error(IDLoc, "instruction requires a 64-bit architecture");
1811 bool UseSrcReg = false;
1812 if (SrcReg != Mips::NoRegister)
1817 unsigned TmpReg = DstReg;
1818 if (UseSrcReg && (DstReg == SrcReg)) {
1819 // At this point we need AT to perform the expansions and we exit if it is
1821 unsigned ATReg = getATReg(IDLoc);
1827 tmpInst.setLoc(IDLoc);
1828 // FIXME: gas has a special case for values that are 000...1111, which
1829 // becomes a li -1 and then a dsrl
1830 if (0 <= ImmValue && ImmValue <= 65535) {
1831 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1832 // li d,j => ori d,$zero,j
1834 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1835 tmpInst.setOpcode(Mips::ORi);
1836 tmpInst.addOperand(MCOperand::createReg(DstReg));
1837 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1838 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1839 Instructions.push_back(tmpInst);
1840 } else if (ImmValue < 0 && ImmValue >= -32768) {
1841 // For negative signed 16-bit values (-32768 <= j < 0):
1842 // li d,j => addiu d,$zero,j
1844 SrcReg = Mips::ZERO;
1845 tmpInst.setOpcode(Mips::ADDiu);
1846 tmpInst.addOperand(MCOperand::createReg(DstReg));
1847 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1848 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1849 Instructions.push_back(tmpInst);
1850 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1851 warnIfNoMacro(IDLoc);
1853 // For all other values which are representable as a 32-bit integer:
1854 // li d,j => lui d,hi16(j)
1856 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1857 uint16_t Bits15To0 = ImmValue & 0xffff;
1859 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1860 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1862 tmpInst.setOpcode(Mips::ORi);
1863 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1864 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1865 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1866 tmpInst.setLoc(IDLoc);
1867 Instructions.push_back(tmpInst);
1868 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1869 createLShiftOri<16>(0, TmpReg, IDLoc, Instructions);
1871 tmpInst.setOpcode(Mips::LUi);
1872 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1873 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1874 Instructions.push_back(tmpInst);
1876 createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1879 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1881 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1883 Error(IDLoc, "instruction requires a 32-bit immediate");
1886 warnIfNoMacro(IDLoc);
1888 // <------- lo32 ------>
1889 // <------- hi32 ------>
1890 // <- hi16 -> <- lo16 ->
1891 // _________________________________
1893 // | 16-bits | 16-bits | 16-bits |
1894 // |__________|__________|__________|
1896 // For any 64-bit value that is representable as a 48-bit integer:
1897 // li d,j => lui d,hi16(j)
1898 // ori d,d,hi16(lo32(j))
1900 // ori d,d,lo16(lo32(j))
1901 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1902 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1903 uint16_t Bits15To0 = ImmValue & 0xffff;
1905 tmpInst.setOpcode(Mips::LUi);
1906 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1907 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1908 Instructions.push_back(tmpInst);
1909 createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1910 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1913 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1917 Error(IDLoc, "instruction requires a 32-bit immediate");
1920 warnIfNoMacro(IDLoc);
1922 // <------- hi32 ------> <------- lo32 ------>
1923 // <- hi16 -> <- lo16 ->
1924 // ___________________________________________
1926 // | 16-bits | 16-bits | 16-bits | 16-bits |
1927 // |__________|__________|__________|__________|
1929 // For all other values which are representable as a 64-bit integer:
1930 // li d,j => lui d,hi16(j)
1931 // ori d,d,lo16(hi32(j))
1933 // ori d,d,hi16(lo32(j))
1935 // ori d,d,lo16(lo32(j))
1936 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1937 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1938 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1939 uint16_t Bits15To0 = ImmValue & 0xffff;
1941 tmpInst.setOpcode(Mips::LUi);
1942 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1943 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1944 Instructions.push_back(tmpInst);
1945 createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1947 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1948 // two left shifts of 16 bits.
1949 if (Bits31To16 == 0) {
1950 createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1952 createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1953 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1957 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1962 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1963 SmallVectorImpl<MCInst> &Instructions) {
1964 const MCOperand &ImmOp = Inst.getOperand(1);
1965 assert(ImmOp.isImm() && "expected immediate operand kind");
1966 const MCOperand &DstRegOp = Inst.getOperand(0);
1967 assert(DstRegOp.isReg() && "expected register operand kind");
1969 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1970 Is32BitImm, IDLoc, Instructions))
1977 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1978 SmallVectorImpl<MCInst> &Instructions) {
1979 const MCOperand &DstRegOp = Inst.getOperand(0);
1980 assert(DstRegOp.isReg() && "expected register operand kind");
1982 const MCOperand &SrcRegOp = Inst.getOperand(1);
1983 assert(SrcRegOp.isReg() && "expected register operand kind");
1985 const MCOperand &ImmOp = Inst.getOperand(2);
1986 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1987 "expected immediate operand kind");
1988 if (!ImmOp.isImm()) {
1989 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1990 SrcRegOp.getReg(), Is32BitImm, IDLoc,
1997 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1998 Is32BitImm, IDLoc, Instructions))
2005 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2006 SmallVectorImpl<MCInst> &Instructions) {
2007 const MCOperand &DstRegOp = Inst.getOperand(0);
2008 assert(DstRegOp.isReg() && "expected register operand kind");
2010 const MCOperand &ImmOp = Inst.getOperand(1);
2011 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
2012 "expected immediate operand kind");
2013 if (!ImmOp.isImm()) {
2014 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
2015 Mips::NoRegister, Is32BitImm, IDLoc,
2022 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2023 Is32BitImm, IDLoc, Instructions))
2029 bool MipsAsmParser::loadAndAddSymbolAddress(
2030 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2031 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2032 warnIfNoMacro(IDLoc);
2034 if (Is32BitSym && isABI_N64())
2035 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
2038 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2039 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2040 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2041 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2042 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2044 bool UseSrcReg = SrcReg != Mips::NoRegister;
2046 unsigned TmpReg = DstReg;
2047 if (UseSrcReg && (DstReg == SrcReg)) {
2048 // At this point we need AT to perform the expansions and we exit if it is
2050 unsigned ATReg = getATReg(IDLoc);
2057 // If it's a 64-bit architecture, expand to:
2058 // la d,sym => lui d,highest(sym)
2059 // ori d,d,higher(sym)
2061 // ori d,d,hi16(sym)
2063 // ori d,d,lo16(sym)
2064 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2065 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2066 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2067 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2069 tmpInst.setOpcode(Mips::LUi);
2070 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2071 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2072 Instructions.push_back(tmpInst);
2074 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2076 createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2078 createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2081 // Otherwise, expand to:
2082 // la d,sym => lui d,hi16(sym)
2083 // ori d,d,lo16(sym)
2084 tmpInst.setOpcode(Mips::LUi);
2085 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2086 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2087 Instructions.push_back(tmpInst);
2089 createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2094 createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2099 bool MipsAsmParser::expandUncondBranchMMPseudo(
2100 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2101 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2102 "unexpected number of operands");
2104 MCOperand Offset = Inst.getOperand(0);
2105 if (Offset.isExpr()) {
2107 Inst.setOpcode(Mips::BEQ_MM);
2108 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2109 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2110 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2112 assert(Offset.isImm() && "expected immediate operand kind");
2113 if (isIntN(11, Offset.getImm())) {
2114 // If offset fits into 11 bits then this instruction becomes microMIPS
2115 // 16-bit unconditional branch instruction.
2116 Inst.setOpcode(Mips::B16_MM);
2118 if (!isIntN(17, Offset.getImm()))
2119 Error(IDLoc, "branch target out of range");
2120 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2121 Error(IDLoc, "branch to misaligned address");
2123 Inst.setOpcode(Mips::BEQ_MM);
2124 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2125 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2126 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2129 Instructions.push_back(Inst);
2131 // If .set reorder is active, emit a NOP after the branch instruction.
2132 if (AssemblerOptions.back()->isReorder())
2133 createNop(true, IDLoc, Instructions);
2138 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2139 SmallVectorImpl<MCInst> &Instructions) {
2140 const MCOperand &DstRegOp = Inst.getOperand(0);
2141 assert(DstRegOp.isReg() && "expected register operand kind");
2143 const MCOperand &ImmOp = Inst.getOperand(1);
2144 assert(ImmOp.isImm() && "expected immediate operand kind");
2146 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2147 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2149 unsigned OpCode = 0;
2150 switch(Inst.getOpcode()) {
2158 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2162 int64_t ImmValue = ImmOp.getImm();
2163 if (ImmValue == 0) {
2165 BranchInst.setOpcode(OpCode);
2166 BranchInst.addOperand(DstRegOp);
2167 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2168 BranchInst.addOperand(MemOffsetOp);
2169 Instructions.push_back(BranchInst);
2171 warnIfNoMacro(IDLoc);
2173 unsigned ATReg = getATReg(IDLoc);
2177 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2182 BranchInst.setOpcode(OpCode);
2183 BranchInst.addOperand(DstRegOp);
2184 BranchInst.addOperand(MCOperand::createReg(ATReg));
2185 BranchInst.addOperand(MemOffsetOp);
2186 Instructions.push_back(BranchInst);
2191 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2192 SmallVectorImpl<MCInst> &Instructions,
2193 bool isLoad, bool isImmOpnd) {
2195 unsigned ImmOffset, HiOffset, LoOffset;
2196 const MCExpr *ExprOffset;
2198 // 1st operand is either the source or destination register.
2199 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2200 unsigned RegOpNum = Inst.getOperand(0).getReg();
2201 // 2nd operand is the base register.
2202 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2203 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2204 // 3rd operand is either an immediate or expression.
2206 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2207 ImmOffset = Inst.getOperand(2).getImm();
2208 LoOffset = ImmOffset & 0x0000ffff;
2209 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2210 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2211 if (LoOffset & 0x8000)
2214 ExprOffset = Inst.getOperand(2).getExpr();
2215 // All instructions will have the same location.
2216 TempInst.setLoc(IDLoc);
2217 // These are some of the types of expansions we perform here:
2218 // 1) lw $8, sym => lui $8, %hi(sym)
2219 // lw $8, %lo(sym)($8)
2220 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2222 // lw $8, %lo(offset)($9)
2223 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2225 // lw $8, %lo(offset)($at)
2226 // 4) sw $8, sym => lui $at, %hi(sym)
2227 // sw $8, %lo(sym)($at)
2228 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2230 // sw $8, %lo(offset)($at)
2231 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2232 // ldc1 $f0, %lo(sym)($at)
2234 // For load instructions we can use the destination register as a temporary
2235 // if base and dst are different (examples 1 and 2) and if the base register
2236 // is general purpose otherwise we must use $at (example 6) and error if it's
2237 // not available. For stores we must use $at (examples 4 and 5) because we
2238 // must not clobber the source register setting up the offset.
2239 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2240 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2241 unsigned RegClassIDOp0 =
2242 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2243 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2244 (RegClassIDOp0 == Mips::GPR64RegClassID);
2245 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2246 TmpRegNum = RegOpNum;
2248 // At this point we need AT to perform the expansions and we exit if it is
2250 TmpRegNum = getATReg(IDLoc);
2255 TempInst.setOpcode(Mips::LUi);
2256 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2258 TempInst.addOperand(MCOperand::createImm(HiOffset));
2260 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2261 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2263 // Add the instruction to the list.
2264 Instructions.push_back(TempInst);
2265 // Prepare TempInst for next instruction.
2267 // Add temp register to base.
2268 if (BaseRegNum != Mips::ZERO) {
2269 TempInst.setOpcode(Mips::ADDu);
2270 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2271 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2272 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2273 Instructions.push_back(TempInst);
2276 // And finally, create original instruction with low part
2277 // of offset and new base.
2278 TempInst.setOpcode(Inst.getOpcode());
2279 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2280 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2282 TempInst.addOperand(MCOperand::createImm(LoOffset));
2284 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2285 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2287 Instructions.push_back(TempInst);
2292 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2293 SmallVectorImpl<MCInst> &Instructions) {
2294 unsigned OpNum = Inst.getNumOperands();
2295 unsigned Opcode = Inst.getOpcode();
2296 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2298 assert (Inst.getOperand(OpNum - 1).isImm() &&
2299 Inst.getOperand(OpNum - 2).isReg() &&
2300 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2302 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2303 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2304 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2305 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2306 // It can be implemented as SWM16 or LWM16 instruction.
2307 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2309 Inst.setOpcode(NewOpcode);
2310 Instructions.push_back(Inst);
2314 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2315 SmallVectorImpl<MCInst> &Instructions) {
2316 unsigned PseudoOpcode = Inst.getOpcode();
2317 unsigned SrcReg = Inst.getOperand(0).getReg();
2318 unsigned TrgReg = Inst.getOperand(1).getReg();
2319 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2321 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2322 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2324 switch (PseudoOpcode) {
2327 AcceptsEquality = false;
2328 ReverseOrderSLT = false;
2329 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2330 ZeroSrcOpcode = Mips::BGTZ;
2331 ZeroTrgOpcode = Mips::BLTZ;
2335 AcceptsEquality = true;
2336 ReverseOrderSLT = true;
2337 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2338 ZeroSrcOpcode = Mips::BGEZ;
2339 ZeroTrgOpcode = Mips::BLEZ;
2343 AcceptsEquality = true;
2344 ReverseOrderSLT = false;
2345 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2346 ZeroSrcOpcode = Mips::BLEZ;
2347 ZeroTrgOpcode = Mips::BGEZ;
2351 AcceptsEquality = false;
2352 ReverseOrderSLT = true;
2353 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2354 ZeroSrcOpcode = Mips::BLTZ;
2355 ZeroTrgOpcode = Mips::BGTZ;
2358 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2362 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2363 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2364 if (IsSrcRegZero && IsTrgRegZero) {
2365 // FIXME: All of these Opcode-specific if's are needed for compatibility
2366 // with GAS' behaviour. However, they may not generate the most efficient
2367 // code in some circumstances.
2368 if (PseudoOpcode == Mips::BLT) {
2369 BranchInst.setOpcode(Mips::BLTZ);
2370 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2371 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2372 Instructions.push_back(BranchInst);
2375 if (PseudoOpcode == Mips::BLE) {
2376 BranchInst.setOpcode(Mips::BLEZ);
2377 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2378 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2379 Instructions.push_back(BranchInst);
2380 Warning(IDLoc, "branch is always taken");
2383 if (PseudoOpcode == Mips::BGE) {
2384 BranchInst.setOpcode(Mips::BGEZ);
2385 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2386 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2387 Instructions.push_back(BranchInst);
2388 Warning(IDLoc, "branch is always taken");
2391 if (PseudoOpcode == Mips::BGT) {
2392 BranchInst.setOpcode(Mips::BGTZ);
2393 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2394 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2395 Instructions.push_back(BranchInst);
2398 if (PseudoOpcode == Mips::BGTU) {
2399 BranchInst.setOpcode(Mips::BNE);
2400 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2401 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2402 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2403 Instructions.push_back(BranchInst);
2406 if (AcceptsEquality) {
2407 // If both registers are $0 and the pseudo-branch accepts equality, it
2408 // will always be taken, so we emit an unconditional branch.
2409 BranchInst.setOpcode(Mips::BEQ);
2410 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2411 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2412 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2413 Instructions.push_back(BranchInst);
2414 Warning(IDLoc, "branch is always taken");
2417 // If both registers are $0 and the pseudo-branch does not accept
2418 // equality, it will never be taken, so we don't have to emit anything.
2421 if (IsSrcRegZero || IsTrgRegZero) {
2422 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2423 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2424 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2425 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2426 // the pseudo-branch will never be taken, so we don't emit anything.
2427 // This only applies to unsigned pseudo-branches.
2430 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2431 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2432 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2433 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2434 // the pseudo-branch will always be taken, so we emit an unconditional
2436 // This only applies to unsigned pseudo-branches.
2437 BranchInst.setOpcode(Mips::BEQ);
2438 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2439 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2440 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2441 Instructions.push_back(BranchInst);
2442 Warning(IDLoc, "branch is always taken");
2446 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2447 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2448 // the pseudo-branch will be taken only when the non-zero register is
2449 // different from 0, so we emit a BNEZ.
2451 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2452 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2453 // the pseudo-branch will be taken only when the non-zero register is
2454 // equal to 0, so we emit a BEQZ.
2456 // Because only BLEU and BGEU branch on equality, we can use the
2457 // AcceptsEquality variable to decide when to emit the BEQZ.
2458 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2459 BranchInst.addOperand(
2460 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2461 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2462 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2463 Instructions.push_back(BranchInst);
2466 // If we have a signed pseudo-branch and one of the registers is $0,
2467 // we can use an appropriate compare-to-zero branch. We select which one
2468 // to use in the switch statement above.
2469 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2470 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2471 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2472 Instructions.push_back(BranchInst);
2476 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2477 // expansions. If it is not available, we return.
2478 unsigned ATRegNum = getATReg(IDLoc);
2482 warnIfNoMacro(IDLoc);
2484 // SLT fits well with 2 of our 4 pseudo-branches:
2485 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2486 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2487 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2488 // This is accomplished by using a BNEZ with the result of the SLT.
2490 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2491 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2492 // Because only BGE and BLE branch on equality, we can use the
2493 // AcceptsEquality variable to decide when to emit the BEQZ.
2494 // Note that the order of the SLT arguments doesn't change between
2497 // The same applies to the unsigned variants, except that SLTu is used
2500 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2501 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2502 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2503 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2504 Instructions.push_back(SetInst);
2506 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2507 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2508 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2509 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2510 Instructions.push_back(BranchInst);
2514 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2515 SmallVectorImpl<MCInst> &Instructions) {
2516 if (hasMips32r6() || hasMips64r6()) {
2517 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2521 warnIfNoMacro(IDLoc);
2523 const MCOperand &DstRegOp = Inst.getOperand(0);
2524 assert(DstRegOp.isReg() && "expected register operand kind");
2526 const MCOperand &SrcRegOp = Inst.getOperand(1);
2527 assert(SrcRegOp.isReg() && "expected register operand kind");
2529 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2530 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2532 unsigned DstReg = DstRegOp.getReg();
2533 unsigned SrcReg = SrcRegOp.getReg();
2534 int64_t OffsetValue = OffsetImmOp.getImm();
2536 // NOTE: We always need AT for ULHU, as it is always used as the source
2537 // register for one of the LBu's.
2538 unsigned ATReg = getATReg(IDLoc);
2542 // When the value of offset+1 does not fit in 16 bits, we have to load the
2543 // offset in AT, (D)ADDu the original source register (if there was one), and
2544 // then use AT as the source register for the 2 generated LBu's.
2545 bool LoadedOffsetInAT = false;
2546 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2547 LoadedOffsetInAT = true;
2549 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2550 IDLoc, Instructions))
2553 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2554 // because it will make our output more similar to GAS'. For example,
2555 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2556 // instead of just an "ori $1, $9, 32768".
2557 // NOTE: If there is no source register specified in the ULHU, the parser
2558 // will interpret it as $0.
2559 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2560 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2563 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2564 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2565 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2567 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2569 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2570 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2572 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2573 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2576 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2579 TmpInst.setOpcode(Mips::LBu);
2580 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2581 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2582 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2583 Instructions.push_back(TmpInst);
2586 TmpInst.setOpcode(Mips::LBu);
2587 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2588 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2589 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2590 Instructions.push_back(TmpInst);
2593 TmpInst.setOpcode(Mips::SLL);
2594 TmpInst.addOperand(MCOperand::createReg(SllReg));
2595 TmpInst.addOperand(MCOperand::createReg(SllReg));
2596 TmpInst.addOperand(MCOperand::createImm(8));
2597 Instructions.push_back(TmpInst);
2600 TmpInst.setOpcode(Mips::OR);
2601 TmpInst.addOperand(MCOperand::createReg(DstReg));
2602 TmpInst.addOperand(MCOperand::createReg(DstReg));
2603 TmpInst.addOperand(MCOperand::createReg(ATReg));
2604 Instructions.push_back(TmpInst);
2609 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2610 SmallVectorImpl<MCInst> &Instructions) {
2611 if (hasMips32r6() || hasMips64r6()) {
2612 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2616 const MCOperand &DstRegOp = Inst.getOperand(0);
2617 assert(DstRegOp.isReg() && "expected register operand kind");
2619 const MCOperand &SrcRegOp = Inst.getOperand(1);
2620 assert(SrcRegOp.isReg() && "expected register operand kind");
2622 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2623 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2625 unsigned SrcReg = SrcRegOp.getReg();
2626 int64_t OffsetValue = OffsetImmOp.getImm();
2629 // When the value of offset+3 does not fit in 16 bits, we have to load the
2630 // offset in AT, (D)ADDu the original source register (if there was one), and
2631 // then use AT as the source register for the generated LWL and LWR.
2632 bool LoadedOffsetInAT = false;
2633 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2634 ATReg = getATReg(IDLoc);
2637 LoadedOffsetInAT = true;
2639 warnIfNoMacro(IDLoc);
2641 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2642 IDLoc, Instructions))
2645 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2646 // because it will make our output more similar to GAS'. For example,
2647 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2648 // instead of just an "ori $1, $9, 32768".
2649 // NOTE: If there is no source register specified in the ULW, the parser
2650 // will interpret it as $0.
2651 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2652 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2655 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2656 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2658 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2659 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2661 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2662 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2665 MCInst LeftLoadInst;
2666 LeftLoadInst.setOpcode(Mips::LWL);
2667 LeftLoadInst.addOperand(DstRegOp);
2668 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2669 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2670 Instructions.push_back(LeftLoadInst);
2672 MCInst RightLoadInst;
2673 RightLoadInst.setOpcode(Mips::LWR);
2674 RightLoadInst.addOperand(DstRegOp);
2675 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2676 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2677 Instructions.push_back(RightLoadInst);
2682 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2683 SmallVectorImpl<MCInst> &Instructions) {
2685 if (hasShortDelaySlot) {
2686 NopInst.setOpcode(Mips::MOVE16_MM);
2687 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2688 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2690 NopInst.setOpcode(Mips::SLL);
2691 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2692 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2693 NopInst.addOperand(MCOperand::createImm(0));
2695 Instructions.push_back(NopInst);
2698 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2699 unsigned TrgReg, bool Is64Bit,
2700 SmallVectorImpl<MCInst> &Instructions) {
2702 AdduInst.setOpcode(Is64Bit ? Mips::DADDu : Mips::ADDu);
2703 AdduInst.addOperand(MCOperand::createReg(DstReg));
2704 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2705 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2706 Instructions.push_back(AdduInst);
2709 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2710 // As described by the Mips32r2 spec, the registers Rd and Rs for
2711 // jalr.hb must be different.
2712 unsigned Opcode = Inst.getOpcode();
2714 if (Opcode == Mips::JALR_HB &&
2715 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2716 return Match_RequiresDifferentSrcAndDst;
2718 return Match_Success;
2721 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2722 OperandVector &Operands,
2724 uint64_t &ErrorInfo,
2725 bool MatchingInlineAsm) {
2728 SmallVector<MCInst, 8> Instructions;
2729 unsigned MatchResult =
2730 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2732 switch (MatchResult) {
2733 case Match_Success: {
2734 if (processInstruction(Inst, IDLoc, Instructions))
2736 for (unsigned i = 0; i < Instructions.size(); i++)
2737 Out.EmitInstruction(Instructions[i], STI);
2740 case Match_MissingFeature:
2741 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2743 case Match_InvalidOperand: {
2744 SMLoc ErrorLoc = IDLoc;
2745 if (ErrorInfo != ~0ULL) {
2746 if (ErrorInfo >= Operands.size())
2747 return Error(IDLoc, "too few operands for instruction");
2749 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2750 if (ErrorLoc == SMLoc())
2754 return Error(ErrorLoc, "invalid operand for instruction");
2756 case Match_MnemonicFail:
2757 return Error(IDLoc, "invalid instruction");
2758 case Match_RequiresDifferentSrcAndDst:
2759 return Error(IDLoc, "source and destination must be different");
2762 llvm_unreachable("Implement any new match types added!");
2765 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2766 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2767 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2768 ") without \".set noat\"");
2771 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2772 if (!AssemblerOptions.back()->isMacro())
2773 Warning(Loc, "macro instruction expanded into multiple instructions");
2777 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2778 SMRange Range, bool ShowColors) {
2779 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2780 Range, SMFixIt(Range, FixMsg),
2784 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2787 CC = StringSwitch<unsigned>(Name)
2823 if (!(isABI_N32() || isABI_N64()))
2826 if (12 <= CC && CC <= 15) {
2827 // Name is one of t4-t7
2828 AsmToken RegTok = getLexer().peekTok();
2829 SMRange RegRange = RegTok.getLocRange();
2831 StringRef FixedName = StringSwitch<StringRef>(Name)
2837 assert(FixedName != "" && "Register name is not one of t4-t7.");
2839 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2840 "Did you mean $" + FixedName + "?", RegRange);
2843 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2844 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2845 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2846 if (8 <= CC && CC <= 11)
2850 CC = StringSwitch<unsigned>(Name)
2862 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2865 CC = StringSwitch<unsigned>(Name)
2866 .Case("hwr_cpunum", 0)
2867 .Case("hwr_synci_step", 1)
2869 .Case("hwr_ccres", 3)
2870 .Case("hwr_ulr", 29)
2876 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2878 if (Name[0] == 'f') {
2879 StringRef NumString = Name.substr(1);
2881 if (NumString.getAsInteger(10, IntVal))
2882 return -1; // This is not an integer.
2883 if (IntVal > 31) // Maximum index for fpu register.
2890 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2892 if (Name.startswith("fcc")) {
2893 StringRef NumString = Name.substr(3);
2895 if (NumString.getAsInteger(10, IntVal))
2896 return -1; // This is not an integer.
2897 if (IntVal > 7) // There are only 8 fcc registers.
2904 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2906 if (Name.startswith("ac")) {
2907 StringRef NumString = Name.substr(2);
2909 if (NumString.getAsInteger(10, IntVal))
2910 return -1; // This is not an integer.
2911 if (IntVal > 3) // There are only 3 acc registers.
2918 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2921 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2930 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2933 CC = StringSwitch<unsigned>(Name)
2936 .Case("msaaccess", 2)
2938 .Case("msamodify", 4)
2939 .Case("msarequest", 5)
2941 .Case("msaunmap", 7)
2947 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2948 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2950 reportParseError(Loc,
2951 "pseudo-instruction requires $at, which is not available");
2954 unsigned AT = getReg(
2955 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2959 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2960 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2963 unsigned MipsAsmParser::getGPR(int RegNo) {
2964 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2968 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2970 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2973 return getReg(RegClass, RegNum);
2976 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2977 MCAsmParser &Parser = getParser();
2978 DEBUG(dbgs() << "parseOperand\n");
2980 // Check if the current operand has a custom associated parser, if so, try to
2981 // custom parse the operand, or fallback to the general approach.
2982 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2983 if (ResTy == MatchOperand_Success)
2985 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2986 // there was a match, but an error occurred, in which case, just return that
2987 // the operand parsing failed.
2988 if (ResTy == MatchOperand_ParseFail)
2991 DEBUG(dbgs() << ".. Generic Parser\n");
2993 switch (getLexer().getKind()) {
2995 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2997 case AsmToken::Dollar: {
2998 // Parse the register.
2999 SMLoc S = Parser.getTok().getLoc();
3001 // Almost all registers have been parsed by custom parsers. There is only
3002 // one exception to this. $zero (and it's alias $0) will reach this point
3003 // for div, divu, and similar instructions because it is not an operand
3004 // to the instruction definition but an explicit register. Special case
3005 // this situation for now.
3006 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3009 // Maybe it is a symbol reference.
3010 StringRef Identifier;
3011 if (Parser.parseIdentifier(Identifier))
3014 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3015 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3016 // Otherwise create a symbol reference.
3018 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3020 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3023 // Else drop to expression parsing.
3024 case AsmToken::LParen:
3025 case AsmToken::Minus:
3026 case AsmToken::Plus:
3027 case AsmToken::Integer:
3028 case AsmToken::Tilde:
3029 case AsmToken::String: {
3030 DEBUG(dbgs() << ".. generic integer\n");
3031 OperandMatchResultTy ResTy = parseImm(Operands);
3032 return ResTy != MatchOperand_Success;
3034 case AsmToken::Percent: {
3035 // It is a symbol reference or constant expression.
3036 const MCExpr *IdVal;
3037 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3038 if (parseRelocOperand(IdVal))
3041 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3043 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3045 } // case AsmToken::Percent
3046 } // switch(getLexer().getKind())
3050 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3051 StringRef RelocStr) {
3053 // Check the type of the expression.
3054 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3055 // It's a constant, evaluate reloc value.
3057 switch (getVariantKind(RelocStr)) {
3058 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3059 // Get the 1st 16-bits.
3060 Val = MCE->getValue() & 0xffff;
3062 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3063 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3064 // 16 bits being negative.
3065 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3067 case MCSymbolRefExpr::VK_Mips_HIGHER:
3068 // Get the 3rd 16-bits.
3069 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3071 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3072 // Get the 4th 16-bits.
3073 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3076 report_fatal_error("unsupported reloc value");
3078 return MCConstantExpr::create(Val, getContext());
3081 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3082 // It's a symbol, create a symbolic expression from the symbol.
3083 const MCSymbol *Symbol = &MSRE->getSymbol();
3084 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3085 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3089 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3090 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3092 // Try to create target expression.
3093 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3094 return MipsMCExpr::create(VK, Expr, getContext());
3096 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3097 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3098 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3102 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3103 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3104 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3107 // Just return the original expression.
3111 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3113 switch (Expr->getKind()) {
3114 case MCExpr::Constant:
3116 case MCExpr::SymbolRef:
3117 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3118 case MCExpr::Binary:
3119 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3120 if (!isEvaluated(BE->getLHS()))
3122 return isEvaluated(BE->getRHS());
3125 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3126 case MCExpr::Target:
3132 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3133 MCAsmParser &Parser = getParser();
3134 Parser.Lex(); // Eat the % token.
3135 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3136 if (Tok.isNot(AsmToken::Identifier))
3139 std::string Str = Tok.getIdentifier();
3141 Parser.Lex(); // Eat the identifier.
3142 // Now make an expression from the rest of the operand.
3143 const MCExpr *IdVal;
3146 if (getLexer().getKind() == AsmToken::LParen) {
3148 Parser.Lex(); // Eat the '(' token.
3149 if (getLexer().getKind() == AsmToken::Percent) {
3150 Parser.Lex(); // Eat the % token.
3151 const AsmToken &nextTok = Parser.getTok();
3152 if (nextTok.isNot(AsmToken::Identifier))
3155 Str += nextTok.getIdentifier();
3156 Parser.Lex(); // Eat the identifier.
3157 if (getLexer().getKind() != AsmToken::LParen)
3162 if (getParser().parseParenExpression(IdVal, EndLoc))
3165 while (getLexer().getKind() == AsmToken::RParen)
3166 Parser.Lex(); // Eat the ')' token.
3169 return true; // Parenthesis must follow the relocation operand.
3171 Res = evaluateRelocExpr(IdVal, Str);
3175 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3177 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3178 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3179 if (ResTy == MatchOperand_Success) {
3180 assert(Operands.size() == 1);
3181 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3182 StartLoc = Operand.getStartLoc();
3183 EndLoc = Operand.getEndLoc();
3185 // AFAIK, we only support numeric registers and named GPR's in CFI
3187 // Don't worry about eating tokens before failing. Using an unrecognised
3188 // register is a parse error.
3189 if (Operand.isGPRAsmReg()) {
3190 // Resolve to GPR32 or GPR64 appropriately.
3191 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3194 return (RegNo == (unsigned)-1);
3197 assert(Operands.size() == 0);
3198 return (RegNo == (unsigned)-1);
3201 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3202 MCAsmParser &Parser = getParser();
3205 unsigned NumOfLParen = 0;
3207 while (getLexer().getKind() == AsmToken::LParen) {
3212 switch (getLexer().getKind()) {
3215 case AsmToken::Identifier:
3216 case AsmToken::LParen:
3217 case AsmToken::Integer:
3218 case AsmToken::Minus:
3219 case AsmToken::Plus:
3221 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3223 Result = (getParser().parseExpression(Res));
3224 while (getLexer().getKind() == AsmToken::RParen)
3227 case AsmToken::Percent:
3228 Result = parseRelocOperand(Res);
3233 MipsAsmParser::OperandMatchResultTy
3234 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3235 MCAsmParser &Parser = getParser();
3236 DEBUG(dbgs() << "parseMemOperand\n");
3237 const MCExpr *IdVal = nullptr;
3239 bool isParenExpr = false;
3240 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3241 // First operand is the offset.
3242 S = Parser.getTok().getLoc();
3244 if (getLexer().getKind() == AsmToken::LParen) {
3249 if (getLexer().getKind() != AsmToken::Dollar) {
3250 if (parseMemOffset(IdVal, isParenExpr))
3251 return MatchOperand_ParseFail;
3253 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3254 if (Tok.isNot(AsmToken::LParen)) {
3255 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3256 if (Mnemonic.getToken() == "la") {
3258 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3259 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3260 return MatchOperand_Success;
3262 if (Tok.is(AsmToken::EndOfStatement)) {
3264 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3266 // Zero register assumed, add a memory operand with ZERO as its base.
3267 // "Base" will be managed by k_Memory.
3268 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3271 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3272 return MatchOperand_Success;
3274 Error(Parser.getTok().getLoc(), "'(' expected");
3275 return MatchOperand_ParseFail;
3278 Parser.Lex(); // Eat the '(' token.
3281 Res = parseAnyRegister(Operands);
3282 if (Res != MatchOperand_Success)
3285 if (Parser.getTok().isNot(AsmToken::RParen)) {
3286 Error(Parser.getTok().getLoc(), "')' expected");
3287 return MatchOperand_ParseFail;
3290 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3292 Parser.Lex(); // Eat the ')' token.
3295 IdVal = MCConstantExpr::create(0, getContext());
3297 // Replace the register operand with the memory operand.
3298 std::unique_ptr<MipsOperand> op(
3299 static_cast<MipsOperand *>(Operands.back().release()));
3300 // Remove the register from the operands.
3301 // "op" will be managed by k_Memory.
3302 Operands.pop_back();
3303 // Add the memory operand.
3304 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3306 if (IdVal->evaluateAsAbsolute(Imm))
3307 IdVal = MCConstantExpr::create(Imm, getContext());
3308 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3309 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3313 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3314 return MatchOperand_Success;
3317 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3318 MCAsmParser &Parser = getParser();
3319 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3321 SMLoc S = Parser.getTok().getLoc();
3323 if (Sym->isVariable())
3324 Expr = Sym->getVariableValue();
3327 if (Expr->getKind() == MCExpr::SymbolRef) {
3328 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3329 StringRef DefSymbol = Ref->getSymbol().getName();
3330 if (DefSymbol.startswith("$")) {
3331 OperandMatchResultTy ResTy =
3332 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3333 if (ResTy == MatchOperand_Success) {
3336 } else if (ResTy == MatchOperand_ParseFail)
3337 llvm_unreachable("Should never ParseFail");
3340 } else if (Expr->getKind() == MCExpr::Constant) {
3342 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3344 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3351 MipsAsmParser::OperandMatchResultTy
3352 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3353 StringRef Identifier,
3355 int Index = matchCPURegisterName(Identifier);
3357 Operands.push_back(MipsOperand::createGPRReg(
3358 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3359 return MatchOperand_Success;
3362 Index = matchHWRegsRegisterName(Identifier);
3364 Operands.push_back(MipsOperand::createHWRegsReg(
3365 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3366 return MatchOperand_Success;
3369 Index = matchFPURegisterName(Identifier);
3371 Operands.push_back(MipsOperand::createFGRReg(
3372 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3373 return MatchOperand_Success;
3376 Index = matchFCCRegisterName(Identifier);
3378 Operands.push_back(MipsOperand::createFCCReg(
3379 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3380 return MatchOperand_Success;
3383 Index = matchACRegisterName(Identifier);
3385 Operands.push_back(MipsOperand::createACCReg(
3386 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3387 return MatchOperand_Success;
3390 Index = matchMSA128RegisterName(Identifier);
3392 Operands.push_back(MipsOperand::createMSA128Reg(
3393 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3394 return MatchOperand_Success;
3397 Index = matchMSA128CtrlRegisterName(Identifier);
3399 Operands.push_back(MipsOperand::createMSACtrlReg(
3400 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3401 return MatchOperand_Success;
3404 return MatchOperand_NoMatch;
3407 MipsAsmParser::OperandMatchResultTy
3408 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3409 MCAsmParser &Parser = getParser();
3410 auto Token = Parser.getLexer().peekTok(false);
3412 if (Token.is(AsmToken::Identifier)) {
3413 DEBUG(dbgs() << ".. identifier\n");
3414 StringRef Identifier = Token.getIdentifier();
3415 OperandMatchResultTy ResTy =
3416 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3418 } else if (Token.is(AsmToken::Integer)) {
3419 DEBUG(dbgs() << ".. integer\n");
3420 Operands.push_back(MipsOperand::createNumericReg(
3421 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3423 return MatchOperand_Success;
3426 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3428 return MatchOperand_NoMatch;
3431 MipsAsmParser::OperandMatchResultTy
3432 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3433 MCAsmParser &Parser = getParser();
3434 DEBUG(dbgs() << "parseAnyRegister\n");
3436 auto Token = Parser.getTok();
3438 SMLoc S = Token.getLoc();
3440 if (Token.isNot(AsmToken::Dollar)) {
3441 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3442 if (Token.is(AsmToken::Identifier)) {
3443 if (searchSymbolAlias(Operands))
3444 return MatchOperand_Success;
3446 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3447 return MatchOperand_NoMatch;
3449 DEBUG(dbgs() << ".. $\n");
3451 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3452 if (ResTy == MatchOperand_Success) {
3454 Parser.Lex(); // identifier
3459 MipsAsmParser::OperandMatchResultTy
3460 MipsAsmParser::parseImm(OperandVector &Operands) {
3461 MCAsmParser &Parser = getParser();
3462 switch (getLexer().getKind()) {
3464 return MatchOperand_NoMatch;
3465 case AsmToken::LParen:
3466 case AsmToken::Minus:
3467 case AsmToken::Plus:
3468 case AsmToken::Integer:
3469 case AsmToken::Tilde:
3470 case AsmToken::String:
3474 const MCExpr *IdVal;
3475 SMLoc S = Parser.getTok().getLoc();
3476 if (getParser().parseExpression(IdVal))
3477 return MatchOperand_ParseFail;
3479 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3480 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3481 return MatchOperand_Success;
3484 MipsAsmParser::OperandMatchResultTy
3485 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3486 MCAsmParser &Parser = getParser();
3487 DEBUG(dbgs() << "parseJumpTarget\n");
3489 SMLoc S = getLexer().getLoc();
3491 // Integers and expressions are acceptable
3492 OperandMatchResultTy ResTy = parseImm(Operands);
3493 if (ResTy != MatchOperand_NoMatch)
3496 // Registers are a valid target and have priority over symbols.
3497 ResTy = parseAnyRegister(Operands);
3498 if (ResTy != MatchOperand_NoMatch)
3501 const MCExpr *Expr = nullptr;
3502 if (Parser.parseExpression(Expr)) {
3503 // We have no way of knowing if a symbol was consumed so we must ParseFail
3504 return MatchOperand_ParseFail;
3507 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3508 return MatchOperand_Success;
3511 MipsAsmParser::OperandMatchResultTy
3512 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3513 MCAsmParser &Parser = getParser();
3514 const MCExpr *IdVal;
3515 // If the first token is '$' we may have register operand.
3516 if (Parser.getTok().is(AsmToken::Dollar))
3517 return MatchOperand_NoMatch;
3518 SMLoc S = Parser.getTok().getLoc();
3519 if (getParser().parseExpression(IdVal))
3520 return MatchOperand_ParseFail;
3521 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3522 assert(MCE && "Unexpected MCExpr type.");
3523 int64_t Val = MCE->getValue();
3524 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3525 Operands.push_back(MipsOperand::CreateImm(
3526 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3527 return MatchOperand_Success;
3530 MipsAsmParser::OperandMatchResultTy
3531 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3532 MCAsmParser &Parser = getParser();
3533 switch (getLexer().getKind()) {
3535 return MatchOperand_NoMatch;
3536 case AsmToken::LParen:
3537 case AsmToken::Plus:
3538 case AsmToken::Minus:
3539 case AsmToken::Integer:
3544 SMLoc S = Parser.getTok().getLoc();
3546 if (getParser().parseExpression(Expr))
3547 return MatchOperand_ParseFail;
3550 if (!Expr->evaluateAsAbsolute(Val)) {
3551 Error(S, "expected immediate value");
3552 return MatchOperand_ParseFail;
3555 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3556 // and because the CPU always adds one to the immediate field, the allowed
3557 // range becomes 1..4. We'll only check the range here and will deal
3558 // with the addition/subtraction when actually decoding/encoding
3560 if (Val < 1 || Val > 4) {
3561 Error(S, "immediate not in range (1..4)");
3562 return MatchOperand_ParseFail;
3566 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3567 return MatchOperand_Success;
3570 MipsAsmParser::OperandMatchResultTy
3571 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3572 MCAsmParser &Parser = getParser();
3573 SmallVector<unsigned, 10> Regs;
3575 unsigned PrevReg = Mips::NoRegister;
3576 bool RegRange = false;
3577 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3579 if (Parser.getTok().isNot(AsmToken::Dollar))
3580 return MatchOperand_ParseFail;
3582 SMLoc S = Parser.getTok().getLoc();
3583 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3584 SMLoc E = getLexer().getLoc();
3585 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3586 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3588 // Remove last register operand because registers from register range
3589 // should be inserted first.
3590 if (RegNo == Mips::RA) {
3591 Regs.push_back(RegNo);
3593 unsigned TmpReg = PrevReg + 1;
3594 while (TmpReg <= RegNo) {
3595 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3596 Error(E, "invalid register operand");
3597 return MatchOperand_ParseFail;
3601 Regs.push_back(TmpReg++);
3607 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3608 (RegNo != Mips::RA)) {
3609 Error(E, "$16 or $31 expected");
3610 return MatchOperand_ParseFail;
3611 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3612 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3613 Error(E, "invalid register operand");
3614 return MatchOperand_ParseFail;
3615 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3616 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3617 Error(E, "consecutive register numbers expected");
3618 return MatchOperand_ParseFail;
3621 Regs.push_back(RegNo);
3624 if (Parser.getTok().is(AsmToken::Minus))
3627 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3628 !Parser.getTok().isNot(AsmToken::Comma)) {
3629 Error(E, "',' or '-' expected");
3630 return MatchOperand_ParseFail;
3633 Lex(); // Consume comma or minus
3634 if (Parser.getTok().isNot(AsmToken::Dollar))
3640 SMLoc E = Parser.getTok().getLoc();
3641 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3642 parseMemOperand(Operands);
3643 return MatchOperand_Success;
3646 MipsAsmParser::OperandMatchResultTy
3647 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3648 MCAsmParser &Parser = getParser();
3650 SMLoc S = Parser.getTok().getLoc();
3651 if (parseAnyRegister(Operands) != MatchOperand_Success)
3652 return MatchOperand_ParseFail;
3654 SMLoc E = Parser.getTok().getLoc();
3655 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3656 unsigned Reg = Op.getGPR32Reg();
3657 Operands.pop_back();
3658 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3659 return MatchOperand_Success;
3662 MipsAsmParser::OperandMatchResultTy
3663 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3664 MCAsmParser &Parser = getParser();
3665 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3666 SmallVector<unsigned, 10> Regs;
3668 if (Parser.getTok().isNot(AsmToken::Dollar))
3669 return MatchOperand_ParseFail;
3671 SMLoc S = Parser.getTok().getLoc();
3673 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3674 return MatchOperand_ParseFail;
3676 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3677 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3678 Regs.push_back(RegNo);
3680 SMLoc E = Parser.getTok().getLoc();
3681 if (Parser.getTok().isNot(AsmToken::Comma)) {
3682 Error(E, "',' expected");
3683 return MatchOperand_ParseFail;
3689 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3690 return MatchOperand_ParseFail;
3692 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3693 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3694 Regs.push_back(RegNo);
3696 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3698 return MatchOperand_Success;
3701 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3703 MCSymbolRefExpr::VariantKind VK =
3704 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3705 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3706 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3707 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3708 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3709 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3710 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3711 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3712 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3713 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3714 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3715 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3716 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3717 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3718 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3719 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3720 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3721 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3722 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3723 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3724 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3725 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3726 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3727 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3728 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3729 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3730 .Default(MCSymbolRefExpr::VK_None);
3732 assert(VK != MCSymbolRefExpr::VK_None);
3737 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3739 /// ::= '(', register, ')'
3740 /// handle it before we iterate so we don't get tripped up by the lack of
3742 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3743 MCAsmParser &Parser = getParser();
3744 if (getLexer().is(AsmToken::LParen)) {
3746 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3748 if (parseOperand(Operands, Name)) {
3749 SMLoc Loc = getLexer().getLoc();
3750 Parser.eatToEndOfStatement();
3751 return Error(Loc, "unexpected token in argument list");
3753 if (Parser.getTok().isNot(AsmToken::RParen)) {
3754 SMLoc Loc = getLexer().getLoc();
3755 Parser.eatToEndOfStatement();
3756 return Error(Loc, "unexpected token, expected ')'");
3759 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3765 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3766 /// either one of these.
3767 /// ::= '[', register, ']'
3768 /// ::= '[', integer, ']'
3769 /// handle it before we iterate so we don't get tripped up by the lack of
3771 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3772 OperandVector &Operands) {
3773 MCAsmParser &Parser = getParser();
3774 if (getLexer().is(AsmToken::LBrac)) {
3776 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3778 if (parseOperand(Operands, Name)) {
3779 SMLoc Loc = getLexer().getLoc();
3780 Parser.eatToEndOfStatement();
3781 return Error(Loc, "unexpected token in argument list");
3783 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3784 SMLoc Loc = getLexer().getLoc();
3785 Parser.eatToEndOfStatement();
3786 return Error(Loc, "unexpected token, expected ']'");
3789 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3795 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3796 SMLoc NameLoc, OperandVector &Operands) {
3797 MCAsmParser &Parser = getParser();
3798 DEBUG(dbgs() << "ParseInstruction\n");
3800 // We have reached first instruction, module directive are now forbidden.
3801 getTargetStreamer().forbidModuleDirective();
3803 // Check if we have valid mnemonic
3804 if (!mnemonicIsValid(Name, 0)) {
3805 Parser.eatToEndOfStatement();
3806 return Error(NameLoc, "unknown instruction");
3808 // First operand in MCInst is instruction mnemonic.
3809 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3811 // Read the remaining operands.
3812 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3813 // Read the first operand.
3814 if (parseOperand(Operands, Name)) {
3815 SMLoc Loc = getLexer().getLoc();
3816 Parser.eatToEndOfStatement();
3817 return Error(Loc, "unexpected token in argument list");
3819 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3821 // AFAIK, parenthesis suffixes are never on the first operand
3823 while (getLexer().is(AsmToken::Comma)) {
3824 Parser.Lex(); // Eat the comma.
3825 // Parse and remember the operand.
3826 if (parseOperand(Operands, Name)) {
3827 SMLoc Loc = getLexer().getLoc();
3828 Parser.eatToEndOfStatement();
3829 return Error(Loc, "unexpected token in argument list");
3831 // Parse bracket and parenthesis suffixes before we iterate
3832 if (getLexer().is(AsmToken::LBrac)) {
3833 if (parseBracketSuffix(Name, Operands))
3835 } else if (getLexer().is(AsmToken::LParen) &&
3836 parseParenSuffix(Name, Operands))
3840 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3841 SMLoc Loc = getLexer().getLoc();
3842 Parser.eatToEndOfStatement();
3843 return Error(Loc, "unexpected token in argument list");
3845 Parser.Lex(); // Consume the EndOfStatement.
3849 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3850 MCAsmParser &Parser = getParser();
3851 SMLoc Loc = getLexer().getLoc();
3852 Parser.eatToEndOfStatement();
3853 return Error(Loc, ErrorMsg);
3856 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3857 return Error(Loc, ErrorMsg);
3860 bool MipsAsmParser::parseSetNoAtDirective() {
3861 MCAsmParser &Parser = getParser();
3862 // Line should look like: ".set noat".
3864 // Set the $at register to $0.
3865 AssemblerOptions.back()->setATRegIndex(0);
3867 Parser.Lex(); // Eat "noat".
3869 // If this is not the end of the statement, report an error.
3870 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3871 reportParseError("unexpected token, expected end of statement");
3875 getTargetStreamer().emitDirectiveSetNoAt();
3876 Parser.Lex(); // Consume the EndOfStatement.
3880 bool MipsAsmParser::parseSetAtDirective() {
3881 // Line can be: ".set at", which sets $at to $1
3882 // or ".set at=$reg", which sets $at to $reg.
3883 MCAsmParser &Parser = getParser();
3884 Parser.Lex(); // Eat "at".
3886 if (getLexer().is(AsmToken::EndOfStatement)) {
3887 // No register was specified, so we set $at to $1.
3888 AssemblerOptions.back()->setATRegIndex(1);
3890 getTargetStreamer().emitDirectiveSetAt();
3891 Parser.Lex(); // Consume the EndOfStatement.
3895 if (getLexer().isNot(AsmToken::Equal)) {
3896 reportParseError("unexpected token, expected equals sign");
3899 Parser.Lex(); // Eat "=".
3901 if (getLexer().isNot(AsmToken::Dollar)) {
3902 if (getLexer().is(AsmToken::EndOfStatement)) {
3903 reportParseError("no register specified");
3906 reportParseError("unexpected token, expected dollar sign '$'");
3910 Parser.Lex(); // Eat "$".
3912 // Find out what "reg" is.
3914 const AsmToken &Reg = Parser.getTok();
3915 if (Reg.is(AsmToken::Identifier)) {
3916 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3917 } else if (Reg.is(AsmToken::Integer)) {
3918 AtRegNo = Reg.getIntVal();
3920 reportParseError("unexpected token, expected identifier or integer");
3924 // Check if $reg is a valid register. If it is, set $at to $reg.
3925 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3926 reportParseError("invalid register");
3929 Parser.Lex(); // Eat "reg".
3931 // If this is not the end of the statement, report an error.
3932 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3933 reportParseError("unexpected token, expected end of statement");
3937 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3939 Parser.Lex(); // Consume the EndOfStatement.
3943 bool MipsAsmParser::parseSetReorderDirective() {
3944 MCAsmParser &Parser = getParser();
3946 // If this is not the end of the statement, report an error.
3947 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3948 reportParseError("unexpected token, expected end of statement");
3951 AssemblerOptions.back()->setReorder();
3952 getTargetStreamer().emitDirectiveSetReorder();
3953 Parser.Lex(); // Consume the EndOfStatement.
3957 bool MipsAsmParser::parseSetNoReorderDirective() {
3958 MCAsmParser &Parser = getParser();
3960 // If this is not the end of the statement, report an error.
3961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3962 reportParseError("unexpected token, expected end of statement");
3965 AssemblerOptions.back()->setNoReorder();
3966 getTargetStreamer().emitDirectiveSetNoReorder();
3967 Parser.Lex(); // Consume the EndOfStatement.
3971 bool MipsAsmParser::parseSetMacroDirective() {
3972 MCAsmParser &Parser = getParser();
3974 // If this is not the end of the statement, report an error.
3975 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3976 reportParseError("unexpected token, expected end of statement");
3979 AssemblerOptions.back()->setMacro();
3980 getTargetStreamer().emitDirectiveSetMacro();
3981 Parser.Lex(); // Consume the EndOfStatement.
3985 bool MipsAsmParser::parseSetNoMacroDirective() {
3986 MCAsmParser &Parser = getParser();
3988 // If this is not the end of the statement, report an error.
3989 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3990 reportParseError("unexpected token, expected end of statement");
3993 if (AssemblerOptions.back()->isReorder()) {
3994 reportParseError("`noreorder' must be set before `nomacro'");
3997 AssemblerOptions.back()->setNoMacro();
3998 getTargetStreamer().emitDirectiveSetNoMacro();
3999 Parser.Lex(); // Consume the EndOfStatement.
4003 bool MipsAsmParser::parseSetMsaDirective() {
4004 MCAsmParser &Parser = getParser();
4007 // If this is not the end of the statement, report an error.
4008 if (getLexer().isNot(AsmToken::EndOfStatement))
4009 return reportParseError("unexpected token, expected end of statement");
4011 setFeatureBits(Mips::FeatureMSA, "msa");
4012 getTargetStreamer().emitDirectiveSetMsa();
4016 bool MipsAsmParser::parseSetNoMsaDirective() {
4017 MCAsmParser &Parser = getParser();
4020 // If this is not the end of the statement, report an error.
4021 if (getLexer().isNot(AsmToken::EndOfStatement))
4022 return reportParseError("unexpected token, expected end of statement");
4024 clearFeatureBits(Mips::FeatureMSA, "msa");
4025 getTargetStreamer().emitDirectiveSetNoMsa();
4029 bool MipsAsmParser::parseSetNoDspDirective() {
4030 MCAsmParser &Parser = getParser();
4031 Parser.Lex(); // Eat "nodsp".
4033 // If this is not the end of the statement, report an error.
4034 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4035 reportParseError("unexpected token, expected end of statement");
4039 clearFeatureBits(Mips::FeatureDSP, "dsp");
4040 getTargetStreamer().emitDirectiveSetNoDsp();
4044 bool MipsAsmParser::parseSetMips16Directive() {
4045 MCAsmParser &Parser = getParser();
4046 Parser.Lex(); // Eat "mips16".
4048 // If this is not the end of the statement, report an error.
4049 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4050 reportParseError("unexpected token, expected end of statement");
4054 setFeatureBits(Mips::FeatureMips16, "mips16");
4055 getTargetStreamer().emitDirectiveSetMips16();
4056 Parser.Lex(); // Consume the EndOfStatement.
4060 bool MipsAsmParser::parseSetNoMips16Directive() {
4061 MCAsmParser &Parser = getParser();
4062 Parser.Lex(); // Eat "nomips16".
4064 // If this is not the end of the statement, report an error.
4065 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4066 reportParseError("unexpected token, expected end of statement");
4070 clearFeatureBits(Mips::FeatureMips16, "mips16");
4071 getTargetStreamer().emitDirectiveSetNoMips16();
4072 Parser.Lex(); // Consume the EndOfStatement.
4076 bool MipsAsmParser::parseSetFpDirective() {
4077 MCAsmParser &Parser = getParser();
4078 MipsABIFlagsSection::FpABIKind FpAbiVal;
4079 // Line can be: .set fp=32
4082 Parser.Lex(); // Eat fp token
4083 AsmToken Tok = Parser.getTok();
4084 if (Tok.isNot(AsmToken::Equal)) {
4085 reportParseError("unexpected token, expected equals sign '='");
4088 Parser.Lex(); // Eat '=' token.
4089 Tok = Parser.getTok();
4091 if (!parseFpABIValue(FpAbiVal, ".set"))
4094 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4095 reportParseError("unexpected token, expected end of statement");
4098 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4099 Parser.Lex(); // Consume the EndOfStatement.
4103 bool MipsAsmParser::parseSetOddSPRegDirective() {
4104 MCAsmParser &Parser = getParser();
4106 Parser.Lex(); // Eat "oddspreg".
4107 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4108 reportParseError("unexpected token, expected end of statement");
4112 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4113 getTargetStreamer().emitDirectiveSetOddSPReg();
4117 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4118 MCAsmParser &Parser = getParser();
4120 Parser.Lex(); // Eat "nooddspreg".
4121 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4122 reportParseError("unexpected token, expected end of statement");
4126 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4127 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4131 bool MipsAsmParser::parseSetPopDirective() {
4132 MCAsmParser &Parser = getParser();
4133 SMLoc Loc = getLexer().getLoc();
4136 if (getLexer().isNot(AsmToken::EndOfStatement))
4137 return reportParseError("unexpected token, expected end of statement");
4139 // Always keep an element on the options "stack" to prevent the user
4140 // from changing the initial options. This is how we remember them.
4141 if (AssemblerOptions.size() == 2)
4142 return reportParseError(Loc, ".set pop with no .set push");
4144 AssemblerOptions.pop_back();
4145 setAvailableFeatures(
4146 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4147 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4149 getTargetStreamer().emitDirectiveSetPop();
4153 bool MipsAsmParser::parseSetPushDirective() {
4154 MCAsmParser &Parser = getParser();
4156 if (getLexer().isNot(AsmToken::EndOfStatement))
4157 return reportParseError("unexpected token, expected end of statement");
4159 // Create a copy of the current assembler options environment and push it.
4160 AssemblerOptions.push_back(
4161 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4163 getTargetStreamer().emitDirectiveSetPush();
4167 bool MipsAsmParser::parseSetSoftFloatDirective() {
4168 MCAsmParser &Parser = getParser();
4170 if (getLexer().isNot(AsmToken::EndOfStatement))
4171 return reportParseError("unexpected token, expected end of statement");
4173 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4174 getTargetStreamer().emitDirectiveSetSoftFloat();
4178 bool MipsAsmParser::parseSetHardFloatDirective() {
4179 MCAsmParser &Parser = getParser();
4181 if (getLexer().isNot(AsmToken::EndOfStatement))
4182 return reportParseError("unexpected token, expected end of statement");
4184 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4185 getTargetStreamer().emitDirectiveSetHardFloat();
4189 bool MipsAsmParser::parseSetAssignment() {
4191 const MCExpr *Value;
4192 MCAsmParser &Parser = getParser();
4194 if (Parser.parseIdentifier(Name))
4195 reportParseError("expected identifier after .set");
4197 if (getLexer().isNot(AsmToken::Comma))
4198 return reportParseError("unexpected token, expected comma");
4201 if (Parser.parseExpression(Value))
4202 return reportParseError("expected valid expression after comma");
4204 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4205 Sym->setVariableValue(Value);
4210 bool MipsAsmParser::parseSetMips0Directive() {
4211 MCAsmParser &Parser = getParser();
4213 if (getLexer().isNot(AsmToken::EndOfStatement))
4214 return reportParseError("unexpected token, expected end of statement");
4216 // Reset assembler options to their initial values.
4217 setAvailableFeatures(
4218 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4219 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4220 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4222 getTargetStreamer().emitDirectiveSetMips0();
4226 bool MipsAsmParser::parseSetArchDirective() {
4227 MCAsmParser &Parser = getParser();
4229 if (getLexer().isNot(AsmToken::Equal))
4230 return reportParseError("unexpected token, expected equals sign");
4234 if (Parser.parseIdentifier(Arch))
4235 return reportParseError("expected arch identifier");
4237 StringRef ArchFeatureName =
4238 StringSwitch<StringRef>(Arch)
4239 .Case("mips1", "mips1")
4240 .Case("mips2", "mips2")
4241 .Case("mips3", "mips3")
4242 .Case("mips4", "mips4")
4243 .Case("mips5", "mips5")
4244 .Case("mips32", "mips32")
4245 .Case("mips32r2", "mips32r2")
4246 .Case("mips32r3", "mips32r3")
4247 .Case("mips32r5", "mips32r5")
4248 .Case("mips32r6", "mips32r6")
4249 .Case("mips64", "mips64")
4250 .Case("mips64r2", "mips64r2")
4251 .Case("mips64r3", "mips64r3")
4252 .Case("mips64r5", "mips64r5")
4253 .Case("mips64r6", "mips64r6")
4254 .Case("cnmips", "cnmips")
4255 .Case("r4000", "mips3") // This is an implementation of Mips3.
4258 if (ArchFeatureName.empty())
4259 return reportParseError("unsupported architecture");
4261 selectArch(ArchFeatureName);
4262 getTargetStreamer().emitDirectiveSetArch(Arch);
4266 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4267 MCAsmParser &Parser = getParser();
4269 if (getLexer().isNot(AsmToken::EndOfStatement))
4270 return reportParseError("unexpected token, expected end of statement");
4274 llvm_unreachable("Unimplemented feature");
4275 case Mips::FeatureDSP:
4276 setFeatureBits(Mips::FeatureDSP, "dsp");
4277 getTargetStreamer().emitDirectiveSetDsp();
4279 case Mips::FeatureMicroMips:
4280 getTargetStreamer().emitDirectiveSetMicroMips();
4282 case Mips::FeatureMips1:
4283 selectArch("mips1");
4284 getTargetStreamer().emitDirectiveSetMips1();
4286 case Mips::FeatureMips2:
4287 selectArch("mips2");
4288 getTargetStreamer().emitDirectiveSetMips2();
4290 case Mips::FeatureMips3:
4291 selectArch("mips3");
4292 getTargetStreamer().emitDirectiveSetMips3();
4294 case Mips::FeatureMips4:
4295 selectArch("mips4");
4296 getTargetStreamer().emitDirectiveSetMips4();
4298 case Mips::FeatureMips5:
4299 selectArch("mips5");
4300 getTargetStreamer().emitDirectiveSetMips5();
4302 case Mips::FeatureMips32:
4303 selectArch("mips32");
4304 getTargetStreamer().emitDirectiveSetMips32();
4306 case Mips::FeatureMips32r2:
4307 selectArch("mips32r2");
4308 getTargetStreamer().emitDirectiveSetMips32R2();
4310 case Mips::FeatureMips32r3:
4311 selectArch("mips32r3");
4312 getTargetStreamer().emitDirectiveSetMips32R3();
4314 case Mips::FeatureMips32r5:
4315 selectArch("mips32r5");
4316 getTargetStreamer().emitDirectiveSetMips32R5();
4318 case Mips::FeatureMips32r6:
4319 selectArch("mips32r6");
4320 getTargetStreamer().emitDirectiveSetMips32R6();
4322 case Mips::FeatureMips64:
4323 selectArch("mips64");
4324 getTargetStreamer().emitDirectiveSetMips64();
4326 case Mips::FeatureMips64r2:
4327 selectArch("mips64r2");
4328 getTargetStreamer().emitDirectiveSetMips64R2();
4330 case Mips::FeatureMips64r3:
4331 selectArch("mips64r3");
4332 getTargetStreamer().emitDirectiveSetMips64R3();
4334 case Mips::FeatureMips64r5:
4335 selectArch("mips64r5");
4336 getTargetStreamer().emitDirectiveSetMips64R5();
4338 case Mips::FeatureMips64r6:
4339 selectArch("mips64r6");
4340 getTargetStreamer().emitDirectiveSetMips64R6();
4346 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4347 MCAsmParser &Parser = getParser();
4348 if (getLexer().isNot(AsmToken::Comma)) {
4349 SMLoc Loc = getLexer().getLoc();
4350 Parser.eatToEndOfStatement();
4351 return Error(Loc, ErrorStr);
4354 Parser.Lex(); // Eat the comma.
4358 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4359 if (AssemblerOptions.back()->isReorder())
4360 Warning(Loc, ".cpload should be inside a noreorder section");
4362 if (inMips16Mode()) {
4363 reportParseError(".cpload is not supported in Mips16 mode");
4367 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4368 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4369 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4370 reportParseError("expected register containing function address");
4374 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4375 if (!RegOpnd.isGPRAsmReg()) {
4376 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4380 // If this is not the end of the statement, report an error.
4381 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4382 reportParseError("unexpected token, expected end of statement");
4386 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4390 bool MipsAsmParser::parseDirectiveCPSetup() {
4391 MCAsmParser &Parser = getParser();
4394 bool SaveIsReg = true;
4396 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4397 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4398 if (ResTy == MatchOperand_NoMatch) {
4399 reportParseError("expected register containing function address");
4400 Parser.eatToEndOfStatement();
4404 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4405 if (!FuncRegOpnd.isGPRAsmReg()) {
4406 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4407 Parser.eatToEndOfStatement();
4411 FuncReg = FuncRegOpnd.getGPR32Reg();
4414 if (!eatComma("unexpected token, expected comma"))
4417 ResTy = parseAnyRegister(TmpReg);
4418 if (ResTy == MatchOperand_NoMatch) {
4419 const AsmToken &Tok = Parser.getTok();
4420 if (Tok.is(AsmToken::Integer)) {
4421 Save = Tok.getIntVal();
4425 reportParseError("expected save register or stack offset");
4426 Parser.eatToEndOfStatement();
4430 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4431 if (!SaveOpnd.isGPRAsmReg()) {
4432 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4433 Parser.eatToEndOfStatement();
4436 Save = SaveOpnd.getGPR32Reg();
4439 if (!eatComma("unexpected token, expected comma"))
4443 if (Parser.parseExpression(Expr)) {
4444 reportParseError("expected expression");
4448 if (Expr->getKind() != MCExpr::SymbolRef) {
4449 reportParseError("expected symbol");
4452 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4454 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4459 bool MipsAsmParser::parseDirectiveNaN() {
4460 MCAsmParser &Parser = getParser();
4461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4462 const AsmToken &Tok = Parser.getTok();
4464 if (Tok.getString() == "2008") {
4466 getTargetStreamer().emitDirectiveNaN2008();
4468 } else if (Tok.getString() == "legacy") {
4470 getTargetStreamer().emitDirectiveNaNLegacy();
4474 // If we don't recognize the option passed to the .nan
4475 // directive (e.g. no option or unknown option), emit an error.
4476 reportParseError("invalid option in .nan directive");
4480 bool MipsAsmParser::parseDirectiveSet() {
4481 MCAsmParser &Parser = getParser();
4482 // Get the next token.
4483 const AsmToken &Tok = Parser.getTok();
4485 if (Tok.getString() == "noat") {
4486 return parseSetNoAtDirective();
4487 } else if (Tok.getString() == "at") {
4488 return parseSetAtDirective();
4489 } else if (Tok.getString() == "arch") {
4490 return parseSetArchDirective();
4491 } else if (Tok.getString() == "fp") {
4492 return parseSetFpDirective();
4493 } else if (Tok.getString() == "oddspreg") {
4494 return parseSetOddSPRegDirective();
4495 } else if (Tok.getString() == "nooddspreg") {
4496 return parseSetNoOddSPRegDirective();
4497 } else if (Tok.getString() == "pop") {
4498 return parseSetPopDirective();
4499 } else if (Tok.getString() == "push") {
4500 return parseSetPushDirective();
4501 } else if (Tok.getString() == "reorder") {
4502 return parseSetReorderDirective();
4503 } else if (Tok.getString() == "noreorder") {
4504 return parseSetNoReorderDirective();
4505 } else if (Tok.getString() == "macro") {
4506 return parseSetMacroDirective();
4507 } else if (Tok.getString() == "nomacro") {
4508 return parseSetNoMacroDirective();
4509 } else if (Tok.getString() == "mips16") {
4510 return parseSetMips16Directive();
4511 } else if (Tok.getString() == "nomips16") {
4512 return parseSetNoMips16Directive();
4513 } else if (Tok.getString() == "nomicromips") {
4514 getTargetStreamer().emitDirectiveSetNoMicroMips();
4515 Parser.eatToEndOfStatement();
4517 } else if (Tok.getString() == "micromips") {
4518 return parseSetFeature(Mips::FeatureMicroMips);
4519 } else if (Tok.getString() == "mips0") {
4520 return parseSetMips0Directive();
4521 } else if (Tok.getString() == "mips1") {
4522 return parseSetFeature(Mips::FeatureMips1);
4523 } else if (Tok.getString() == "mips2") {
4524 return parseSetFeature(Mips::FeatureMips2);
4525 } else if (Tok.getString() == "mips3") {
4526 return parseSetFeature(Mips::FeatureMips3);
4527 } else if (Tok.getString() == "mips4") {
4528 return parseSetFeature(Mips::FeatureMips4);
4529 } else if (Tok.getString() == "mips5") {
4530 return parseSetFeature(Mips::FeatureMips5);
4531 } else if (Tok.getString() == "mips32") {
4532 return parseSetFeature(Mips::FeatureMips32);
4533 } else if (Tok.getString() == "mips32r2") {
4534 return parseSetFeature(Mips::FeatureMips32r2);
4535 } else if (Tok.getString() == "mips32r3") {
4536 return parseSetFeature(Mips::FeatureMips32r3);
4537 } else if (Tok.getString() == "mips32r5") {
4538 return parseSetFeature(Mips::FeatureMips32r5);
4539 } else if (Tok.getString() == "mips32r6") {
4540 return parseSetFeature(Mips::FeatureMips32r6);
4541 } else if (Tok.getString() == "mips64") {
4542 return parseSetFeature(Mips::FeatureMips64);
4543 } else if (Tok.getString() == "mips64r2") {
4544 return parseSetFeature(Mips::FeatureMips64r2);
4545 } else if (Tok.getString() == "mips64r3") {
4546 return parseSetFeature(Mips::FeatureMips64r3);
4547 } else if (Tok.getString() == "mips64r5") {
4548 return parseSetFeature(Mips::FeatureMips64r5);
4549 } else if (Tok.getString() == "mips64r6") {
4550 return parseSetFeature(Mips::FeatureMips64r6);
4551 } else if (Tok.getString() == "dsp") {
4552 return parseSetFeature(Mips::FeatureDSP);
4553 } else if (Tok.getString() == "nodsp") {
4554 return parseSetNoDspDirective();
4555 } else if (Tok.getString() == "msa") {
4556 return parseSetMsaDirective();
4557 } else if (Tok.getString() == "nomsa") {
4558 return parseSetNoMsaDirective();
4559 } else if (Tok.getString() == "softfloat") {
4560 return parseSetSoftFloatDirective();
4561 } else if (Tok.getString() == "hardfloat") {
4562 return parseSetHardFloatDirective();
4564 // It is just an identifier, look for an assignment.
4565 parseSetAssignment();
4572 /// parseDataDirective
4573 /// ::= .word [ expression (, expression)* ]
4574 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4575 MCAsmParser &Parser = getParser();
4576 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4578 const MCExpr *Value;
4579 if (getParser().parseExpression(Value))
4582 getParser().getStreamer().EmitValue(Value, Size);
4584 if (getLexer().is(AsmToken::EndOfStatement))
4587 if (getLexer().isNot(AsmToken::Comma))
4588 return Error(L, "unexpected token, expected comma");
4597 /// parseDirectiveGpWord
4598 /// ::= .gpword local_sym
4599 bool MipsAsmParser::parseDirectiveGpWord() {
4600 MCAsmParser &Parser = getParser();
4601 const MCExpr *Value;
4602 // EmitGPRel32Value requires an expression, so we are using base class
4603 // method to evaluate the expression.
4604 if (getParser().parseExpression(Value))
4606 getParser().getStreamer().EmitGPRel32Value(Value);
4608 if (getLexer().isNot(AsmToken::EndOfStatement))
4609 return Error(getLexer().getLoc(),
4610 "unexpected token, expected end of statement");
4611 Parser.Lex(); // Eat EndOfStatement token.
4615 /// parseDirectiveGpDWord
4616 /// ::= .gpdword local_sym
4617 bool MipsAsmParser::parseDirectiveGpDWord() {
4618 MCAsmParser &Parser = getParser();
4619 const MCExpr *Value;
4620 // EmitGPRel64Value requires an expression, so we are using base class
4621 // method to evaluate the expression.
4622 if (getParser().parseExpression(Value))
4624 getParser().getStreamer().EmitGPRel64Value(Value);
4626 if (getLexer().isNot(AsmToken::EndOfStatement))
4627 return Error(getLexer().getLoc(),
4628 "unexpected token, expected end of statement");
4629 Parser.Lex(); // Eat EndOfStatement token.
4633 bool MipsAsmParser::parseDirectiveOption() {
4634 MCAsmParser &Parser = getParser();
4635 // Get the option token.
4636 AsmToken Tok = Parser.getTok();
4637 // At the moment only identifiers are supported.
4638 if (Tok.isNot(AsmToken::Identifier)) {
4639 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4640 Parser.eatToEndOfStatement();
4644 StringRef Option = Tok.getIdentifier();
4646 if (Option == "pic0") {
4647 getTargetStreamer().emitDirectiveOptionPic0();
4649 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4650 Error(Parser.getTok().getLoc(),
4651 "unexpected token, expected end of statement");
4652 Parser.eatToEndOfStatement();
4657 if (Option == "pic2") {
4658 getTargetStreamer().emitDirectiveOptionPic2();
4660 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4661 Error(Parser.getTok().getLoc(),
4662 "unexpected token, expected end of statement");
4663 Parser.eatToEndOfStatement();
4669 Warning(Parser.getTok().getLoc(),
4670 "unknown option, expected 'pic0' or 'pic2'");
4671 Parser.eatToEndOfStatement();
4675 /// parseInsnDirective
4677 bool MipsAsmParser::parseInsnDirective() {
4678 // If this is not the end of the statement, report an error.
4679 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4680 reportParseError("unexpected token, expected end of statement");
4684 // The actual label marking happens in
4685 // MipsELFStreamer::createPendingLabelRelocs().
4686 getTargetStreamer().emitDirectiveInsn();
4688 getParser().Lex(); // Eat EndOfStatement token.
4692 /// parseDirectiveModule
4693 /// ::= .module oddspreg
4694 /// ::= .module nooddspreg
4695 /// ::= .module fp=value
4696 bool MipsAsmParser::parseDirectiveModule() {
4697 MCAsmParser &Parser = getParser();
4698 MCAsmLexer &Lexer = getLexer();
4699 SMLoc L = Lexer.getLoc();
4701 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4702 // TODO : get a better message.
4703 reportParseError(".module directive must appear before any code");
4708 if (Parser.parseIdentifier(Option)) {
4709 reportParseError("expected .module option identifier");
4713 if (Option == "oddspreg") {
4714 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4716 // Synchronize the abiflags information with the FeatureBits information we
4718 getTargetStreamer().updateABIInfo(*this);
4720 // If printing assembly, use the recently updated abiflags information.
4721 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4722 // emitted at the end).
4723 getTargetStreamer().emitDirectiveModuleOddSPReg();
4725 // If this is not the end of the statement, report an error.
4726 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4727 reportParseError("unexpected token, expected end of statement");
4731 return false; // parseDirectiveModule has finished successfully.
4732 } else if (Option == "nooddspreg") {
4734 Error(L, "'.module nooddspreg' requires the O32 ABI");
4738 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4740 // Synchronize the abiflags information with the FeatureBits information we
4742 getTargetStreamer().updateABIInfo(*this);
4744 // If printing assembly, use the recently updated abiflags information.
4745 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4746 // emitted at the end).
4747 getTargetStreamer().emitDirectiveModuleOddSPReg();
4749 // If this is not the end of the statement, report an error.
4750 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4751 reportParseError("unexpected token, expected end of statement");
4755 return false; // parseDirectiveModule has finished successfully.
4756 } else if (Option == "fp") {
4757 return parseDirectiveModuleFP();
4759 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4763 /// parseDirectiveModuleFP
4767 bool MipsAsmParser::parseDirectiveModuleFP() {
4768 MCAsmParser &Parser = getParser();
4769 MCAsmLexer &Lexer = getLexer();
4771 if (Lexer.isNot(AsmToken::Equal)) {
4772 reportParseError("unexpected token, expected equals sign '='");
4775 Parser.Lex(); // Eat '=' token.
4777 MipsABIFlagsSection::FpABIKind FpABI;
4778 if (!parseFpABIValue(FpABI, ".module"))
4781 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4782 reportParseError("unexpected token, expected end of statement");
4786 // Synchronize the abiflags information with the FeatureBits information we
4788 getTargetStreamer().updateABIInfo(*this);
4790 // If printing assembly, use the recently updated abiflags information.
4791 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4792 // emitted at the end).
4793 getTargetStreamer().emitDirectiveModuleFP();
4795 Parser.Lex(); // Consume the EndOfStatement.
4799 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4800 StringRef Directive) {
4801 MCAsmParser &Parser = getParser();
4802 MCAsmLexer &Lexer = getLexer();
4804 if (Lexer.is(AsmToken::Identifier)) {
4805 StringRef Value = Parser.getTok().getString();
4808 if (Value != "xx") {
4809 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4814 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4818 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4819 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4820 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4824 if (Lexer.is(AsmToken::Integer)) {
4825 unsigned Value = Parser.getTok().getIntVal();
4828 if (Value != 32 && Value != 64) {
4829 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4835 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4839 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4840 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4841 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4843 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4844 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4845 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4854 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4855 MCAsmParser &Parser = getParser();
4856 StringRef IDVal = DirectiveID.getString();
4858 if (IDVal == ".cpload")
4859 return parseDirectiveCpLoad(DirectiveID.getLoc());
4860 if (IDVal == ".dword") {
4861 parseDataDirective(8, DirectiveID.getLoc());
4864 if (IDVal == ".ent") {
4865 StringRef SymbolName;
4867 if (Parser.parseIdentifier(SymbolName)) {
4868 reportParseError("expected identifier after .ent");
4872 // There's an undocumented extension that allows an integer to
4873 // follow the name of the procedure which AFAICS is ignored by GAS.
4874 // Example: .ent foo,2
4875 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4876 if (getLexer().isNot(AsmToken::Comma)) {
4877 // Even though we accept this undocumented extension for compatibility
4878 // reasons, the additional integer argument does not actually change
4879 // the behaviour of the '.ent' directive, so we would like to discourage
4880 // its use. We do this by not referring to the extended version in
4881 // error messages which are not directly related to its use.
4882 reportParseError("unexpected token, expected end of statement");
4885 Parser.Lex(); // Eat the comma.
4886 const MCExpr *DummyNumber;
4887 int64_t DummyNumberVal;
4888 // If the user was explicitly trying to use the extended version,
4889 // we still give helpful extension-related error messages.
4890 if (Parser.parseExpression(DummyNumber)) {
4891 reportParseError("expected number after comma");
4894 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4895 reportParseError("expected an absolute expression after comma");
4900 // If this is not the end of the statement, report an error.
4901 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4902 reportParseError("unexpected token, expected end of statement");
4906 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4908 getTargetStreamer().emitDirectiveEnt(*Sym);
4913 if (IDVal == ".end") {
4914 StringRef SymbolName;
4916 if (Parser.parseIdentifier(SymbolName)) {
4917 reportParseError("expected identifier after .end");
4921 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4922 reportParseError("unexpected token, expected end of statement");
4926 if (CurrentFn == nullptr) {
4927 reportParseError(".end used without .ent");
4931 if ((SymbolName != CurrentFn->getName())) {
4932 reportParseError(".end symbol does not match .ent symbol");
4936 getTargetStreamer().emitDirectiveEnd(SymbolName);
4937 CurrentFn = nullptr;
4941 if (IDVal == ".frame") {
4942 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4943 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4944 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4945 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4946 reportParseError("expected stack register");
4950 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4951 if (!StackRegOpnd.isGPRAsmReg()) {
4952 reportParseError(StackRegOpnd.getStartLoc(),
4953 "expected general purpose register");
4956 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4958 if (Parser.getTok().is(AsmToken::Comma))
4961 reportParseError("unexpected token, expected comma");
4965 // Parse the frame size.
4966 const MCExpr *FrameSize;
4967 int64_t FrameSizeVal;
4969 if (Parser.parseExpression(FrameSize)) {
4970 reportParseError("expected frame size value");
4974 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4975 reportParseError("frame size not an absolute expression");
4979 if (Parser.getTok().is(AsmToken::Comma))
4982 reportParseError("unexpected token, expected comma");
4986 // Parse the return register.
4988 ResTy = parseAnyRegister(TmpReg);
4989 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4990 reportParseError("expected return register");
4994 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4995 if (!ReturnRegOpnd.isGPRAsmReg()) {
4996 reportParseError(ReturnRegOpnd.getStartLoc(),
4997 "expected general purpose register");
5001 // If this is not the end of the statement, report an error.
5002 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5003 reportParseError("unexpected token, expected end of statement");
5007 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5008 ReturnRegOpnd.getGPR32Reg());
5012 if (IDVal == ".set") {
5013 return parseDirectiveSet();
5016 if (IDVal == ".mask" || IDVal == ".fmask") {
5017 // .mask bitmask, frame_offset
5018 // bitmask: One bit for each register used.
5019 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5020 // first register is expected to be saved.
5022 // .mask 0x80000000, -4
5023 // .fmask 0x80000000, -4
5026 // Parse the bitmask
5027 const MCExpr *BitMask;
5030 if (Parser.parseExpression(BitMask)) {
5031 reportParseError("expected bitmask value");
5035 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5036 reportParseError("bitmask not an absolute expression");
5040 if (Parser.getTok().is(AsmToken::Comma))
5043 reportParseError("unexpected token, expected comma");
5047 // Parse the frame_offset
5048 const MCExpr *FrameOffset;
5049 int64_t FrameOffsetVal;
5051 if (Parser.parseExpression(FrameOffset)) {
5052 reportParseError("expected frame offset value");
5056 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5057 reportParseError("frame offset not an absolute expression");
5061 // If this is not the end of the statement, report an error.
5062 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5063 reportParseError("unexpected token, expected end of statement");
5067 if (IDVal == ".mask")
5068 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5070 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5074 if (IDVal == ".nan")
5075 return parseDirectiveNaN();
5077 if (IDVal == ".gpword") {
5078 parseDirectiveGpWord();
5082 if (IDVal == ".gpdword") {
5083 parseDirectiveGpDWord();
5087 if (IDVal == ".word") {
5088 parseDataDirective(4, DirectiveID.getLoc());
5092 if (IDVal == ".option")
5093 return parseDirectiveOption();
5095 if (IDVal == ".abicalls") {
5096 getTargetStreamer().emitDirectiveAbiCalls();
5097 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5098 Error(Parser.getTok().getLoc(),
5099 "unexpected token, expected end of statement");
5101 Parser.eatToEndOfStatement();
5106 if (IDVal == ".cpsetup")
5107 return parseDirectiveCPSetup();
5109 if (IDVal == ".module")
5110 return parseDirectiveModule();
5112 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5113 return parseInternalDirectiveReallowModule();
5115 if (IDVal == ".insn")
5116 return parseInsnDirective();
5121 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5122 // If this is not the end of the statement, report an error.
5123 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5124 reportParseError("unexpected token, expected end of statement");
5128 getTargetStreamer().reallowModuleDirective();
5130 getParser().Lex(); // Eat EndOfStatement token.
5134 extern "C" void LLVMInitializeMipsAsmParser() {
5135 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5136 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5137 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5138 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5141 #define GET_REGISTER_MATCHER
5142 #define GET_MATCHER_IMPLEMENTATION
5143 #include "MipsGenAsmMatcher.inc"