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 "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
120 // Print a warning along with its fix-it message at the given range.
121 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
122 SMRange Range, bool ShowColors = true);
124 #define GET_ASSEMBLER_HEADER
125 #include "MipsGenAsmMatcher.inc"
127 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
129 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
130 OperandVector &Operands, MCStreamer &Out,
132 bool MatchingInlineAsm) override;
134 /// Parse a register as used in CFI directives
135 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
137 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
139 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
141 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
142 SMLoc NameLoc, OperandVector &Operands) override;
144 bool ParseDirective(AsmToken DirectiveID) override;
146 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
148 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
149 StringRef Identifier, SMLoc S);
150 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
152 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
153 OperandMatchResultTy parseImm(OperandVector &Operands);
154 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 OperandMatchResultTy parseInvNum(OperandVector &Operands);
156 OperandMatchResultTy parseLSAImm(OperandVector &Operands);
157 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
158 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
159 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
161 bool searchSymbolAlias(OperandVector &Operands);
163 bool parseOperand(OperandVector &, StringRef Mnemonic);
165 bool needsExpansion(MCInst &Inst);
167 // Expands assembly pseudo instructions.
168 // Returns false on success, true otherwise.
169 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
175 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
176 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
180 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
183 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
187 const MCOperand &Offset, bool Is32BitAddress,
188 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
197 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
210 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
211 SmallVectorImpl<MCInst> &Instructions);
213 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
214 SmallVectorImpl<MCInst> &Instructions);
216 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
217 SmallVectorImpl<MCInst> &Instructions);
219 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
220 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
222 bool reportParseError(Twine ErrorMsg);
223 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
225 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
226 bool parseRelocOperand(const MCExpr *&Res);
228 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
230 bool isEvaluated(const MCExpr *Expr);
231 bool parseSetMips0Directive();
232 bool parseSetArchDirective();
233 bool parseSetFeature(uint64_t Feature);
234 bool parseDirectiveCpLoad(SMLoc Loc);
235 bool parseDirectiveCPSetup();
236 bool parseDirectiveNaN();
237 bool parseDirectiveSet();
238 bool parseDirectiveOption();
239 bool parseInsnDirective();
241 bool parseSetAtDirective();
242 bool parseSetNoAtDirective();
243 bool parseSetMacroDirective();
244 bool parseSetNoMacroDirective();
245 bool parseSetMsaDirective();
246 bool parseSetNoMsaDirective();
247 bool parseSetNoDspDirective();
248 bool parseSetReorderDirective();
249 bool parseSetNoReorderDirective();
250 bool parseSetMips16Directive();
251 bool parseSetNoMips16Directive();
252 bool parseSetFpDirective();
253 bool parseSetOddSPRegDirective();
254 bool parseSetNoOddSPRegDirective();
255 bool parseSetPopDirective();
256 bool parseSetPushDirective();
257 bool parseSetSoftFloatDirective();
258 bool parseSetHardFloatDirective();
260 bool parseSetAssignment();
262 bool parseDataDirective(unsigned Size, SMLoc L);
263 bool parseDirectiveGpWord();
264 bool parseDirectiveGpDWord();
265 bool parseDirectiveModule();
266 bool parseDirectiveModuleFP();
267 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
268 StringRef Directive);
270 bool parseInternalDirectiveReallowModule();
272 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
274 bool eatComma(StringRef ErrorStr);
276 int matchCPURegisterName(StringRef Symbol);
278 int matchHWRegsRegisterName(StringRef Symbol);
280 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
282 int matchFPURegisterName(StringRef Name);
284 int matchFCCRegisterName(StringRef Name);
286 int matchACRegisterName(StringRef Name);
288 int matchMSA128RegisterName(StringRef Name);
290 int matchMSA128CtrlRegisterName(StringRef Name);
292 unsigned getReg(int RC, int RegNo);
294 unsigned getGPR(int RegNo);
296 /// Returns the internal register number for the current AT. Also checks if
297 /// the current AT is unavailable (set to $0) and gives an error if it is.
298 /// This should be used in pseudo-instruction expansions which need AT.
299 unsigned getATReg(SMLoc Loc);
301 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
302 SmallVectorImpl<MCInst> &Instructions);
304 // Helper function that checks if the value of a vector index is within the
305 // boundaries of accepted values for each RegisterKind
306 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
307 bool validateMSAIndex(int Val, int RegKind);
309 // Selects a new architecture by updating the FeatureBits with the necessary
310 // info including implied dependencies.
311 // Internally, it clears all the feature bits related to *any* architecture
312 // and selects the new one using the ToggleFeature functionality of the
313 // MCSubtargetInfo object that handles implied dependencies. The reason we
314 // clear all the arch related bits manually is because ToggleFeature only
315 // clears the features that imply the feature being cleared and not the
316 // features implied by the feature being cleared. This is easier to see
318 // --------------------------------------------------
319 // | Feature | Implies |
320 // | -------------------------------------------------|
321 // | FeatureMips1 | None |
322 // | FeatureMips2 | FeatureMips1 |
323 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
324 // | FeatureMips4 | FeatureMips3 |
326 // --------------------------------------------------
328 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
329 // FeatureMipsGP64 | FeatureMips1)
330 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
331 void selectArch(StringRef ArchFeature) {
332 FeatureBitset FeatureBits = STI.getFeatureBits();
333 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
334 STI.setFeatureBits(FeatureBits);
335 setAvailableFeatures(
336 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
337 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
340 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
341 if (!(STI.getFeatureBits()[Feature])) {
342 setAvailableFeatures(
343 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
344 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
348 void clearFeatureBits(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 setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
357 setFeatureBits(Feature, FeatureString);
358 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
361 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
362 clearFeatureBits(Feature, FeatureString);
363 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
367 enum MipsMatchResultTy {
368 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
369 #define GET_OPERAND_DIAGNOSTIC_TYPES
370 #include "MipsGenAsmMatcher.inc"
371 #undef GET_OPERAND_DIAGNOSTIC_TYPES
375 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
376 const MCInstrInfo &MII, const MCTargetOptions &Options)
377 : MCTargetAsmParser(Options), STI(sti),
378 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
379 sti.getCPU(), Options)) {
380 MCAsmParserExtension::Initialize(parser);
382 parser.addAliasForDirective(".asciiz", ".asciz");
384 // Initialize the set of available features.
385 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
387 // Remember the initial assembler options. The user can not modify these.
388 AssemblerOptions.push_back(
389 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
391 // Create an assembler options environment for the user to modify.
392 AssemblerOptions.push_back(
393 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
395 getTargetStreamer().updateABIInfo(*this);
397 if (!isABI_O32() && !useOddSPReg() != 0)
398 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
403 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
405 Triple TheTriple(sti.getTargetTriple());
406 if ((TheTriple.getArch() == Triple::mips) ||
407 (TheTriple.getArch() == Triple::mips64))
408 IsLittleEndian = false;
410 IsLittleEndian = true;
413 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
414 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
416 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
417 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
418 const MipsABIInfo &getABI() const { return ABI; }
419 bool isABI_N32() const { return ABI.IsN32(); }
420 bool isABI_N64() const { return ABI.IsN64(); }
421 bool isABI_O32() const { return ABI.IsO32(); }
422 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
424 bool useOddSPReg() const {
425 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
428 bool inMicroMipsMode() const {
429 return STI.getFeatureBits()[Mips::FeatureMicroMips];
431 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
432 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
433 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
434 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
435 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
436 bool hasMips32() const {
437 return STI.getFeatureBits()[Mips::FeatureMips32];
439 bool hasMips64() const {
440 return STI.getFeatureBits()[Mips::FeatureMips64];
442 bool hasMips32r2() const {
443 return STI.getFeatureBits()[Mips::FeatureMips32r2];
445 bool hasMips64r2() const {
446 return STI.getFeatureBits()[Mips::FeatureMips64r2];
448 bool hasMips32r3() const {
449 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
451 bool hasMips64r3() const {
452 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
454 bool hasMips32r5() const {
455 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
457 bool hasMips64r5() const {
458 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
460 bool hasMips32r6() const {
461 return STI.getFeatureBits()[Mips::FeatureMips32r6];
463 bool hasMips64r6() const {
464 return STI.getFeatureBits()[Mips::FeatureMips64r6];
467 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
468 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
469 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
470 bool hasCnMips() const {
471 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
478 bool inMips16Mode() const {
479 return STI.getFeatureBits()[Mips::FeatureMips16];
482 bool useTraps() const {
483 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
486 bool useSoftFloat() const {
487 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
490 /// Warn if RegIndex is the same as the current AT.
491 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
493 void warnIfNoMacro(SMLoc Loc);
495 bool isLittle() const { return IsLittleEndian; }
501 /// MipsOperand - Instances of this class represent a parsed Mips machine
503 class MipsOperand : public MCParsedAsmOperand {
505 /// Broad categories of register classes
506 /// The exact class is finalized by the render method.
508 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
509 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
511 RegKind_FCC = 4, /// FCC
512 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
513 RegKind_MSACtrl = 16, /// MSA control registers
514 RegKind_COP2 = 32, /// COP2
515 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
517 RegKind_CCR = 128, /// CCR
518 RegKind_HWRegs = 256, /// HWRegs
519 RegKind_COP3 = 512, /// COP3
520 RegKind_COP0 = 1024, /// COP0
521 /// Potentially any (e.g. $1)
522 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
523 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
524 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
529 k_Immediate, /// An immediate (possibly involving symbol references)
530 k_Memory, /// Base + Offset Memory Address
531 k_PhysRegister, /// A physical register from the Mips namespace
532 k_RegisterIndex, /// A register index in one or more RegKind.
533 k_Token, /// A simple token
534 k_RegList, /// A physical register list
535 k_RegPair /// A pair of physical register
539 MipsOperand(KindTy K, MipsAsmParser &Parser)
540 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
543 /// For diagnostics, and checking the assembler temporary
544 MipsAsmParser &AsmParser;
552 unsigned Num; /// Register Number
556 unsigned Index; /// Index into the register class
557 RegKind Kind; /// Bitfield of the kinds it could possibly be
558 const MCRegisterInfo *RegInfo;
571 SmallVector<unsigned, 10> *List;
576 struct PhysRegOp PhysReg;
577 struct RegIdxOp RegIdx;
580 struct RegListOp RegList;
583 SMLoc StartLoc, EndLoc;
585 /// Internal constructor for register kinds
586 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
587 const MCRegisterInfo *RegInfo,
589 MipsAsmParser &Parser) {
590 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
591 Op->RegIdx.Index = Index;
592 Op->RegIdx.RegInfo = RegInfo;
593 Op->RegIdx.Kind = RegKind;
600 /// Coerce the register to GPR32 and return the real register for the current
602 unsigned getGPR32Reg() const {
603 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
604 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
605 unsigned ClassID = Mips::GPR32RegClassID;
606 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
609 /// Coerce the register to GPR32 and return the real register for the current
611 unsigned getGPRMM16Reg() const {
612 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
613 unsigned ClassID = Mips::GPR32RegClassID;
614 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
617 /// Coerce the register to GPR64 and return the real register for the current
619 unsigned getGPR64Reg() const {
620 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
621 unsigned ClassID = Mips::GPR64RegClassID;
622 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
626 /// Coerce the register to AFGR64 and return the real register for the current
628 unsigned getAFGR64Reg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
630 if (RegIdx.Index % 2 != 0)
631 AsmParser.Warning(StartLoc, "Float register should be even.");
632 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
633 .getRegister(RegIdx.Index / 2);
636 /// Coerce the register to FGR64 and return the real register for the current
638 unsigned getFGR64Reg() const {
639 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
640 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
641 .getRegister(RegIdx.Index);
644 /// Coerce the register to FGR32 and return the real register for the current
646 unsigned getFGR32Reg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
648 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
649 .getRegister(RegIdx.Index);
652 /// Coerce the register to FGRH32 and return the real register for the current
654 unsigned getFGRH32Reg() const {
655 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
656 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
657 .getRegister(RegIdx.Index);
660 /// Coerce the register to FCC and return the real register for the current
662 unsigned getFCCReg() const {
663 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
664 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
665 .getRegister(RegIdx.Index);
668 /// Coerce the register to MSA128 and return the real register for the current
670 unsigned getMSA128Reg() const {
671 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
672 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
674 unsigned ClassID = Mips::MSA128BRegClassID;
675 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
678 /// Coerce the register to MSACtrl and return the real register for the
680 unsigned getMSACtrlReg() const {
681 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
682 unsigned ClassID = Mips::MSACtrlRegClassID;
683 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
686 /// Coerce the register to COP0 and return the real register for the
688 unsigned getCOP0Reg() const {
689 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
690 unsigned ClassID = Mips::COP0RegClassID;
691 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
694 /// Coerce the register to COP2 and return the real register for the
696 unsigned getCOP2Reg() const {
697 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
698 unsigned ClassID = Mips::COP2RegClassID;
699 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
702 /// Coerce the register to COP3 and return the real register for the
704 unsigned getCOP3Reg() const {
705 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
706 unsigned ClassID = Mips::COP3RegClassID;
707 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
710 /// Coerce the register to ACC64DSP and return the real register for the
712 unsigned getACC64DSPReg() const {
713 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
714 unsigned ClassID = Mips::ACC64DSPRegClassID;
715 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
718 /// Coerce the register to HI32DSP and return the real register for the
720 unsigned getHI32DSPReg() const {
721 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
722 unsigned ClassID = Mips::HI32DSPRegClassID;
723 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
726 /// Coerce the register to LO32DSP and return the real register for the
728 unsigned getLO32DSPReg() const {
729 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
730 unsigned ClassID = Mips::LO32DSPRegClassID;
731 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
734 /// Coerce the register to CCR and return the real register for the
736 unsigned getCCRReg() const {
737 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
738 unsigned ClassID = Mips::CCRRegClassID;
739 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
742 /// Coerce the register to HWRegs and return the real register for the
744 unsigned getHWRegsReg() const {
745 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
746 unsigned ClassID = Mips::HWRegsRegClassID;
747 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
751 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
752 // Add as immediate when possible. Null MCExpr = 0.
754 Inst.addOperand(MCOperand::createImm(0));
755 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
756 Inst.addOperand(MCOperand::createImm(CE->getValue()));
758 Inst.addOperand(MCOperand::createExpr(Expr));
761 void addRegOperands(MCInst &Inst, unsigned N) const {
762 llvm_unreachable("Use a custom parser instead");
765 /// Render the operand to an MCInst as a GPR32
766 /// Asserts if the wrong number of operands are requested, or the operand
767 /// is not a k_RegisterIndex compatible with RegKind_GPR
768 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
769 assert(N == 1 && "Invalid number of operands!");
770 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
773 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
778 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
783 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
788 /// Render the operand to an MCInst as a GPR64
789 /// Asserts if the wrong number of operands are requested, or the operand
790 /// is not a k_RegisterIndex compatible with RegKind_GPR
791 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
796 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
801 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
806 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
807 assert(N == 1 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
809 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
810 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
811 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
815 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
816 assert(N == 1 && "Invalid number of operands!");
817 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
820 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 1 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::createReg(getFCCReg()));
825 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
827 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
830 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
831 assert(N == 1 && "Invalid number of operands!");
832 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
835 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
836 assert(N == 1 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
840 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
842 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
845 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 1 && "Invalid number of operands!");
847 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
850 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 1 && "Invalid number of operands!");
852 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
855 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 1 && "Invalid number of operands!");
857 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
860 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
861 assert(N == 1 && "Invalid number of operands!");
862 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
865 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
866 assert(N == 1 && "Invalid number of operands!");
867 Inst.addOperand(MCOperand::createReg(getCCRReg()));
870 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
871 assert(N == 1 && "Invalid number of operands!");
872 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
875 void addImmOperands(MCInst &Inst, unsigned N) const {
876 assert(N == 1 && "Invalid number of operands!");
877 const MCExpr *Expr = getImm();
881 void addMemOperands(MCInst &Inst, unsigned N) const {
882 assert(N == 2 && "Invalid number of operands!");
884 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
885 ? getMemBase()->getGPR64Reg()
886 : getMemBase()->getGPR32Reg()));
888 const MCExpr *Expr = getMemOff();
892 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
893 assert(N == 2 && "Invalid number of operands!");
895 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
897 const MCExpr *Expr = getMemOff();
901 void addRegListOperands(MCInst &Inst, unsigned N) const {
902 assert(N == 1 && "Invalid number of operands!");
904 for (auto RegNo : getRegList())
905 Inst.addOperand(MCOperand::createReg(RegNo));
908 void addRegPairOperands(MCInst &Inst, unsigned N) const {
909 assert(N == 2 && "Invalid number of operands!");
910 unsigned RegNo = getRegPair();
911 Inst.addOperand(MCOperand::createReg(RegNo++));
912 Inst.addOperand(MCOperand::createReg(RegNo));
915 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
916 assert(N == 2 && "Invalid number of operands!");
917 for (auto RegNo : getRegList())
918 Inst.addOperand(MCOperand::createReg(RegNo));
921 bool isReg() const override {
922 // As a special case until we sort out the definition of div/divu, pretend
923 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
924 if (isGPRAsmReg() && RegIdx.Index == 0)
927 return Kind == k_PhysRegister;
929 bool isRegIdx() const { return Kind == k_RegisterIndex; }
930 bool isImm() const override { return Kind == k_Immediate; }
931 bool isConstantImm() const {
932 return isImm() && dyn_cast<MCConstantExpr>(getImm());
934 template <unsigned Bits> bool isUImm() const {
935 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
937 bool isToken() const override {
938 // Note: It's not possible to pretend that other operand kinds are tokens.
939 // The matcher emitter checks tokens first.
940 return Kind == k_Token;
942 bool isMem() const override { return Kind == k_Memory; }
943 bool isConstantMemOff() const {
944 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
946 template <unsigned Bits> bool isMemWithSimmOffset() const {
947 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
948 && getMemBase()->isGPRAsmReg();
950 bool isMemWithGRPMM16Base() const {
951 return isMem() && getMemBase()->isMM16AsmReg();
953 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
954 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
955 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
957 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
958 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
959 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
960 && (getMemBase()->getGPR32Reg() == Mips::SP);
962 bool isRegList16() const {
966 int Size = RegList.List->size();
967 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
968 RegList.List->back() != Mips::RA)
971 int PrevReg = *RegList.List->begin();
972 for (int i = 1; i < Size - 1; i++) {
973 int Reg = (*(RegList.List))[i];
974 if ( Reg != PrevReg + 1)
981 bool isInvNum() const { return Kind == k_Immediate; }
982 bool isLSAImm() const {
983 if (!isConstantImm())
985 int64_t Val = getConstantImm();
986 return 1 <= Val && Val <= 4;
988 bool isRegList() const { return Kind == k_RegList; }
989 bool isMovePRegPair() const {
990 if (Kind != k_RegList || RegList.List->size() != 2)
993 unsigned R0 = RegList.List->front();
994 unsigned R1 = RegList.List->back();
996 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
997 (R0 == Mips::A1 && R1 == Mips::A3) ||
998 (R0 == Mips::A2 && R1 == Mips::A3) ||
999 (R0 == Mips::A0 && R1 == Mips::S5) ||
1000 (R0 == Mips::A0 && R1 == Mips::S6) ||
1001 (R0 == Mips::A0 && R1 == Mips::A1) ||
1002 (R0 == Mips::A0 && R1 == Mips::A2) ||
1003 (R0 == Mips::A0 && R1 == Mips::A3))
1009 StringRef getToken() const {
1010 assert(Kind == k_Token && "Invalid access!");
1011 return StringRef(Tok.Data, Tok.Length);
1013 bool isRegPair() const { return Kind == k_RegPair; }
1015 unsigned getReg() const override {
1016 // As a special case until we sort out the definition of div/divu, pretend
1017 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1018 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1019 RegIdx.Kind & RegKind_GPR)
1020 return getGPR32Reg(); // FIXME: GPR64 too
1022 assert(Kind == k_PhysRegister && "Invalid access!");
1026 const MCExpr *getImm() const {
1027 assert((Kind == k_Immediate) && "Invalid access!");
1031 int64_t getConstantImm() const {
1032 const MCExpr *Val = getImm();
1033 return static_cast<const MCConstantExpr *>(Val)->getValue();
1036 MipsOperand *getMemBase() const {
1037 assert((Kind == k_Memory) && "Invalid access!");
1041 const MCExpr *getMemOff() const {
1042 assert((Kind == k_Memory) && "Invalid access!");
1046 int64_t getConstantMemOff() const {
1047 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1050 const SmallVectorImpl<unsigned> &getRegList() const {
1051 assert((Kind == k_RegList) && "Invalid access!");
1052 return *(RegList.List);
1055 unsigned getRegPair() const {
1056 assert((Kind == k_RegPair) && "Invalid access!");
1057 return RegIdx.Index;
1060 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1061 MipsAsmParser &Parser) {
1062 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1063 Op->Tok.Data = Str.data();
1064 Op->Tok.Length = Str.size();
1070 /// Create a numeric register (e.g. $1). The exact register remains
1071 /// unresolved until an instruction successfully matches
1072 static std::unique_ptr<MipsOperand>
1073 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1074 SMLoc E, MipsAsmParser &Parser) {
1075 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1076 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1079 /// Create a register that is definitely a GPR.
1080 /// This is typically only used for named registers such as $gp.
1081 static std::unique_ptr<MipsOperand>
1082 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1083 MipsAsmParser &Parser) {
1084 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1087 /// Create a register that is definitely a FGR.
1088 /// This is typically only used for named registers such as $f0.
1089 static std::unique_ptr<MipsOperand>
1090 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1091 MipsAsmParser &Parser) {
1092 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1095 /// Create a register that is definitely a HWReg.
1096 /// This is typically only used for named registers such as $hwr_cpunum.
1097 static std::unique_ptr<MipsOperand>
1098 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1099 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1100 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1103 /// Create a register that is definitely an FCC.
1104 /// This is typically only used for named registers such as $fcc0.
1105 static std::unique_ptr<MipsOperand>
1106 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1107 MipsAsmParser &Parser) {
1108 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1111 /// Create a register that is definitely an ACC.
1112 /// This is typically only used for named registers such as $ac0.
1113 static std::unique_ptr<MipsOperand>
1114 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1115 MipsAsmParser &Parser) {
1116 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1119 /// Create a register that is definitely an MSA128.
1120 /// This is typically only used for named registers such as $w0.
1121 static std::unique_ptr<MipsOperand>
1122 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1123 SMLoc E, MipsAsmParser &Parser) {
1124 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1127 /// Create a register that is definitely an MSACtrl.
1128 /// This is typically only used for named registers such as $msaaccess.
1129 static std::unique_ptr<MipsOperand>
1130 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1131 SMLoc E, MipsAsmParser &Parser) {
1132 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1135 static std::unique_ptr<MipsOperand>
1136 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1137 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1144 static std::unique_ptr<MipsOperand>
1145 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1146 SMLoc E, MipsAsmParser &Parser) {
1147 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1148 Op->Mem.Base = Base.release();
1155 static std::unique_ptr<MipsOperand>
1156 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1157 MipsAsmParser &Parser) {
1158 assert (Regs.size() > 0 && "Empty list not allowed");
1160 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1161 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1162 Op->StartLoc = StartLoc;
1163 Op->EndLoc = EndLoc;
1167 static std::unique_ptr<MipsOperand>
1168 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1169 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1170 Op->RegIdx.Index = RegNo;
1176 bool isGPRAsmReg() const {
1177 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1179 bool isMM16AsmReg() const {
1180 if (!(isRegIdx() && RegIdx.Kind))
1182 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1183 || RegIdx.Index == 16 || RegIdx.Index == 17);
1185 bool isMM16AsmRegZero() const {
1186 if (!(isRegIdx() && RegIdx.Kind))
1188 return (RegIdx.Index == 0 ||
1189 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1190 RegIdx.Index == 17);
1192 bool isMM16AsmRegMoveP() const {
1193 if (!(isRegIdx() && RegIdx.Kind))
1195 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1196 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1198 bool isFGRAsmReg() const {
1199 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1200 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1202 bool isHWRegsAsmReg() const {
1203 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1205 bool isCCRAsmReg() const {
1206 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1208 bool isFCCAsmReg() const {
1209 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1211 if (!AsmParser.hasEightFccRegisters())
1212 return RegIdx.Index == 0;
1213 return RegIdx.Index <= 7;
1215 bool isACCAsmReg() const {
1216 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1218 bool isCOP0AsmReg() const {
1219 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1221 bool isCOP2AsmReg() const {
1222 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1224 bool isCOP3AsmReg() const {
1225 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1227 bool isMSA128AsmReg() const {
1228 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1230 bool isMSACtrlAsmReg() const {
1231 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1234 /// getStartLoc - Get the location of the first token of this operand.
1235 SMLoc getStartLoc() const override { return StartLoc; }
1236 /// getEndLoc - Get the location of the last token of this operand.
1237 SMLoc getEndLoc() const override { return EndLoc; }
1239 virtual ~MipsOperand() {
1247 delete RegList.List;
1248 case k_PhysRegister:
1249 case k_RegisterIndex:
1256 void print(raw_ostream &OS) const override {
1265 Mem.Base->print(OS);
1270 case k_PhysRegister:
1271 OS << "PhysReg<" << PhysReg.Num << ">";
1273 case k_RegisterIndex:
1274 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1281 for (auto Reg : (*RegList.List))
1286 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1290 }; // class MipsOperand
1294 extern const MCInstrDesc MipsInsts[];
1296 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1297 return MipsInsts[Opcode];
1300 static bool hasShortDelaySlot(unsigned Opcode) {
1303 case Mips::JALRS_MM:
1304 case Mips::JALRS16_MM:
1305 case Mips::BGEZALS_MM:
1306 case Mips::BLTZALS_MM:
1313 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1314 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1315 return &SRExpr->getSymbol();
1318 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1319 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1320 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1331 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1332 return getSingleMCSymbol(UExpr->getSubExpr());
1337 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1338 if (isa<MCSymbolRefExpr>(Expr))
1341 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1342 return countMCSymbolRefExpr(BExpr->getLHS()) +
1343 countMCSymbolRefExpr(BExpr->getRHS());
1345 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1346 return countMCSymbolRefExpr(UExpr->getSubExpr());
1351 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1352 SmallVectorImpl<MCInst> &Instructions) {
1353 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1357 if (MCID.isBranch() || MCID.isCall()) {
1358 const unsigned Opcode = Inst.getOpcode();
1368 assert(hasCnMips() && "instruction only valid for octeon cpus");
1375 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1376 Offset = Inst.getOperand(2);
1377 if (!Offset.isImm())
1378 break; // We'll deal with this situation later on when applying fixups.
1379 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1380 return Error(IDLoc, "branch target out of range");
1381 if (OffsetToAlignment(Offset.getImm(),
1382 1LL << (inMicroMipsMode() ? 1 : 2)))
1383 return Error(IDLoc, "branch to misaligned address");
1397 case Mips::BGEZAL_MM:
1398 case Mips::BLTZAL_MM:
1401 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1402 Offset = Inst.getOperand(1);
1403 if (!Offset.isImm())
1404 break; // We'll deal with this situation later on when applying fixups.
1405 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1406 return Error(IDLoc, "branch target out of range");
1407 if (OffsetToAlignment(Offset.getImm(),
1408 1LL << (inMicroMipsMode() ? 1 : 2)))
1409 return Error(IDLoc, "branch to misaligned address");
1411 case Mips::BEQZ16_MM:
1412 case Mips::BEQZC16_MMR6:
1413 case Mips::BNEZ16_MM:
1414 case Mips::BNEZC16_MMR6:
1415 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1416 Offset = Inst.getOperand(1);
1417 if (!Offset.isImm())
1418 break; // We'll deal with this situation later on when applying fixups.
1419 if (!isIntN(8, Offset.getImm()))
1420 return Error(IDLoc, "branch target out of range");
1421 if (OffsetToAlignment(Offset.getImm(), 2LL))
1422 return Error(IDLoc, "branch to misaligned address");
1427 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1428 // We still accept it but it is a normal nop.
1429 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1430 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1431 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1436 const unsigned Opcode = Inst.getOpcode();
1448 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1449 // The offset is handled above
1450 Opnd = Inst.getOperand(1);
1452 return Error(IDLoc, "expected immediate operand kind");
1453 Imm = Opnd.getImm();
1454 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1455 Opcode == Mips::BBIT1 ? 63 : 31))
1456 return Error(IDLoc, "immediate operand value out of range");
1458 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1460 Inst.getOperand(1).setImm(Imm - 32);
1468 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1470 Opnd = Inst.getOperand(3);
1472 return Error(IDLoc, "expected immediate operand kind");
1473 Imm = Opnd.getImm();
1474 if (Imm < 0 || Imm > 31)
1475 return Error(IDLoc, "immediate operand value out of range");
1477 Opnd = Inst.getOperand(2);
1479 return Error(IDLoc, "expected immediate operand kind");
1480 Imm = Opnd.getImm();
1481 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1482 Opcode == Mips::EXTS ? 63 : 31))
1483 return Error(IDLoc, "immediate operand value out of range");
1485 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1486 Inst.getOperand(2).setImm(Imm - 32);
1492 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1493 Opnd = Inst.getOperand(2);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (!isInt<10>(Imm))
1498 return Error(IDLoc, "immediate operand value out of range");
1503 // This expansion is not in a function called by expandInstruction() because
1504 // the pseudo-instruction doesn't have a distinct opcode.
1505 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1507 warnIfNoMacro(IDLoc);
1509 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1511 // We can do this expansion if there's only 1 symbol in the argument
1513 if (countMCSymbolRefExpr(JalExpr) > 1)
1514 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1516 // FIXME: This is checking the expression can be handled by the later stages
1517 // of the assembler. We ought to leave it to those later stages but
1518 // we can't do that until we stop evaluateRelocExpr() rewriting the
1519 // expressions into non-equivalent forms.
1520 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1522 // FIXME: Add support for label+offset operands (currently causes an error).
1523 // FIXME: Add support for forward-declared local symbols.
1524 // FIXME: Add expansion for when the LargeGOT option is enabled.
1525 if (JalSym->isInSection() || JalSym->isTemporary()) {
1527 // If it's a local symbol and the O32 ABI is being used, we expand to:
1529 // R_(MICRO)MIPS_GOT16 label
1530 // addiu $25, $25, 0
1531 // R_(MICRO)MIPS_LO16 label
1533 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1534 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1537 LwInst.setOpcode(Mips::LW);
1538 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1539 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1540 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1541 Instructions.push_back(LwInst);
1544 AddiuInst.setOpcode(Mips::ADDiu);
1545 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1546 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1547 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1548 Instructions.push_back(AddiuInst);
1549 } else if (isABI_N32() || isABI_N64()) {
1550 // If it's a local symbol and the N32/N64 ABIs are being used,
1552 // lw/ld $25, 0($gp)
1553 // R_(MICRO)MIPS_GOT_DISP label
1555 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1558 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1559 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1560 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1561 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1562 Instructions.push_back(LoadInst);
1565 // If it's an external/weak symbol, we expand to:
1566 // lw/ld $25, 0($gp)
1567 // R_(MICRO)MIPS_CALL16 label
1569 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1572 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1573 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1574 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1575 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1576 Instructions.push_back(LoadInst);
1580 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1581 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1582 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1584 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1585 // This relocation is supposed to be an optimization hint for the linker
1586 // and is not necessary for correctness.
1591 if (MCID.mayLoad() || MCID.mayStore()) {
1592 // Check the offset of memory operand, if it is a symbol
1593 // reference or immediate we may have to expand instructions.
1594 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1595 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1596 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1597 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1598 MCOperand &Op = Inst.getOperand(i);
1600 int MemOffset = Op.getImm();
1601 if (MemOffset < -32768 || MemOffset > 32767) {
1602 // Offset can't exceed 16bit value.
1603 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1606 } else if (Op.isExpr()) {
1607 const MCExpr *Expr = Op.getExpr();
1608 if (Expr->getKind() == MCExpr::SymbolRef) {
1609 const MCSymbolRefExpr *SR =
1610 static_cast<const MCSymbolRefExpr *>(Expr);
1611 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1613 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1616 } else if (!isEvaluated(Expr)) {
1617 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1625 if (inMicroMipsMode()) {
1626 if (MCID.mayLoad()) {
1627 // Try to create 16-bit GP relative load instruction.
1628 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1629 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1630 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1631 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1632 MCOperand &Op = Inst.getOperand(i);
1634 int MemOffset = Op.getImm();
1635 MCOperand &DstReg = Inst.getOperand(0);
1636 MCOperand &BaseReg = Inst.getOperand(1);
1637 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1638 getContext().getRegisterInfo()->getRegClass(
1639 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1640 (BaseReg.getReg() == Mips::GP ||
1641 BaseReg.getReg() == Mips::GP_64)) {
1643 TmpInst.setLoc(IDLoc);
1644 TmpInst.setOpcode(Mips::LWGP_MM);
1645 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1646 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1647 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1648 Instructions.push_back(TmpInst);
1656 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1661 switch (Inst.getOpcode()) {
1664 case Mips::ADDIUS5_MM:
1665 Opnd = Inst.getOperand(2);
1667 return Error(IDLoc, "expected immediate operand kind");
1668 Imm = Opnd.getImm();
1669 if (Imm < -8 || Imm > 7)
1670 return Error(IDLoc, "immediate operand value out of range");
1672 case Mips::ADDIUSP_MM:
1673 Opnd = Inst.getOperand(0);
1675 return Error(IDLoc, "expected immediate operand kind");
1676 Imm = Opnd.getImm();
1677 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1679 return Error(IDLoc, "immediate operand value out of range");
1681 case Mips::SLL16_MM:
1682 case Mips::SRL16_MM:
1683 Opnd = Inst.getOperand(2);
1685 return Error(IDLoc, "expected immediate operand kind");
1686 Imm = Opnd.getImm();
1687 if (Imm < 1 || Imm > 8)
1688 return Error(IDLoc, "immediate operand value out of range");
1691 Opnd = Inst.getOperand(1);
1693 return Error(IDLoc, "expected immediate operand kind");
1694 Imm = Opnd.getImm();
1695 if (Imm < -1 || Imm > 126)
1696 return Error(IDLoc, "immediate operand value out of range");
1698 case Mips::ADDIUR2_MM:
1699 Opnd = Inst.getOperand(2);
1701 return Error(IDLoc, "expected immediate operand kind");
1702 Imm = Opnd.getImm();
1703 if (!(Imm == 1 || Imm == -1 ||
1704 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1705 return Error(IDLoc, "immediate operand value out of range");
1707 case Mips::ADDIUR1SP_MM:
1708 Opnd = Inst.getOperand(1);
1710 return Error(IDLoc, "expected immediate operand kind");
1711 Imm = Opnd.getImm();
1712 if (OffsetToAlignment(Imm, 4LL))
1713 return Error(IDLoc, "misaligned immediate operand value");
1714 if (Imm < 0 || Imm > 255)
1715 return Error(IDLoc, "immediate operand value out of range");
1717 case Mips::ANDI16_MM:
1718 Opnd = Inst.getOperand(2);
1720 return Error(IDLoc, "expected immediate operand kind");
1721 Imm = Opnd.getImm();
1722 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1723 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1724 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1725 return Error(IDLoc, "immediate operand value out of range");
1727 case Mips::LBU16_MM:
1728 Opnd = Inst.getOperand(2);
1730 return Error(IDLoc, "expected immediate operand kind");
1731 Imm = Opnd.getImm();
1732 if (Imm < -1 || Imm > 14)
1733 return Error(IDLoc, "immediate operand value out of range");
1736 Opnd = Inst.getOperand(2);
1738 return Error(IDLoc, "expected immediate operand kind");
1739 Imm = Opnd.getImm();
1740 if (Imm < 0 || Imm > 15)
1741 return Error(IDLoc, "immediate operand value out of range");
1743 case Mips::LHU16_MM:
1745 Opnd = Inst.getOperand(2);
1747 return Error(IDLoc, "expected immediate operand kind");
1748 Imm = Opnd.getImm();
1749 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1750 return Error(IDLoc, "immediate operand value out of range");
1754 Opnd = Inst.getOperand(2);
1756 return Error(IDLoc, "expected immediate operand kind");
1757 Imm = Opnd.getImm();
1758 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1759 return Error(IDLoc, "immediate operand value out of range");
1763 Opnd = Inst.getOperand(2);
1765 return Error(IDLoc, "expected immediate operand kind");
1766 Imm = Opnd.getImm();
1767 if (!isUInt<5>(Imm))
1768 return Error(IDLoc, "immediate operand value out of range");
1770 case Mips::ADDIUPC_MM:
1771 MCOperand Opnd = Inst.getOperand(1);
1773 return Error(IDLoc, "expected immediate operand kind");
1774 int Imm = Opnd.getImm();
1775 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1776 return Error(IDLoc, "immediate operand value out of range");
1781 if (needsExpansion(Inst)) {
1782 if (expandInstruction(Inst, IDLoc, Instructions))
1785 Instructions.push_back(Inst);
1787 // If this instruction has a delay slot and .set reorder is active,
1788 // emit a NOP after it.
1789 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1790 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1795 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1797 switch (Inst.getOpcode()) {
1798 case Mips::LoadImm32:
1799 case Mips::LoadImm64:
1800 case Mips::LoadAddrImm32:
1801 case Mips::LoadAddrImm64:
1802 case Mips::LoadAddrReg32:
1803 case Mips::LoadAddrReg64:
1804 case Mips::B_MM_Pseudo:
1805 case Mips::B_MMR6_Pseudo:
1808 case Mips::JalOneReg:
1809 case Mips::JalTwoReg:
1820 case Mips::SDivMacro:
1821 case Mips::UDivMacro:
1822 case Mips::DSDivMacro:
1823 case Mips::DUDivMacro:
1832 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1833 SmallVectorImpl<MCInst> &Instructions) {
1834 switch (Inst.getOpcode()) {
1835 default: llvm_unreachable("unimplemented expansion");
1836 case Mips::LoadImm32:
1837 return expandLoadImm(Inst, true, IDLoc, Instructions);
1838 case Mips::LoadImm64:
1839 return expandLoadImm(Inst, false, IDLoc, Instructions);
1840 case Mips::LoadAddrImm32:
1841 case Mips::LoadAddrImm64:
1842 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1843 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1844 "expected immediate operand kind");
1846 return expandLoadAddress(
1847 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1848 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1849 case Mips::LoadAddrReg32:
1850 case Mips::LoadAddrReg64:
1851 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1852 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1853 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1854 "expected immediate operand kind");
1856 return expandLoadAddress(
1857 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1858 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1859 case Mips::B_MM_Pseudo:
1860 case Mips::B_MMR6_Pseudo:
1861 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1864 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1865 case Mips::JalOneReg:
1866 case Mips::JalTwoReg:
1867 return expandJalWithRegs(Inst, IDLoc, Instructions);
1870 return expandBranchImm(Inst, IDLoc, Instructions);
1879 return expandCondBranches(Inst, IDLoc, Instructions);
1880 case Mips::SDivMacro:
1881 return expandDiv(Inst, IDLoc, Instructions, false, true);
1882 case Mips::DSDivMacro:
1883 return expandDiv(Inst, IDLoc, Instructions, true, true);
1884 case Mips::UDivMacro:
1885 return expandDiv(Inst, IDLoc, Instructions, false, false);
1886 case Mips::DUDivMacro:
1887 return expandDiv(Inst, IDLoc, Instructions, true, false);
1889 return expandUlhu(Inst, IDLoc, Instructions);
1891 return expandUlw(Inst, IDLoc, Instructions);
1896 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1897 SmallVectorImpl<MCInst> &Instructions) {
1899 tmpInst.setOpcode(Opcode);
1900 tmpInst.addOperand(MCOperand::createReg(Reg0));
1901 tmpInst.addOperand(Op1);
1902 tmpInst.setLoc(IDLoc);
1903 Instructions.push_back(tmpInst);
1906 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1907 SmallVectorImpl<MCInst> &Instructions) {
1908 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1911 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1912 SmallVectorImpl<MCInst> &Instructions) {
1913 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1916 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1917 SmallVectorImpl<MCInst> &Instructions) {
1919 tmpInst.setOpcode(Opcode);
1920 tmpInst.addOperand(MCOperand::createImm(Imm1));
1921 tmpInst.addOperand(MCOperand::createImm(Imm2));
1922 tmpInst.setLoc(IDLoc);
1923 Instructions.push_back(tmpInst);
1926 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1927 SmallVectorImpl<MCInst> &Instructions) {
1929 tmpInst.setOpcode(Opcode);
1930 tmpInst.addOperand(MCOperand::createReg(Reg0));
1931 tmpInst.setLoc(IDLoc);
1932 Instructions.push_back(tmpInst);
1935 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1936 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1938 tmpInst.setOpcode(Opcode);
1939 tmpInst.addOperand(MCOperand::createReg(Reg0));
1940 tmpInst.addOperand(MCOperand::createReg(Reg1));
1941 tmpInst.addOperand(Op2);
1942 tmpInst.setLoc(IDLoc);
1943 Instructions.push_back(tmpInst);
1946 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1947 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1948 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1952 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1953 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1954 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1958 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1959 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1960 if (ShiftAmount >= 32) {
1961 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1966 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1968 } // end anonymous namespace.
1970 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1971 SmallVectorImpl<MCInst> &Instructions) {
1972 // Create a JALR instruction which is going to replace the pseudo-JAL.
1974 JalrInst.setLoc(IDLoc);
1975 const MCOperand FirstRegOp = Inst.getOperand(0);
1976 const unsigned Opcode = Inst.getOpcode();
1978 if (Opcode == Mips::JalOneReg) {
1979 // jal $rs => jalr $rs
1980 if (inMicroMipsMode()) {
1981 JalrInst.setOpcode(Mips::JALR16_MM);
1982 JalrInst.addOperand(FirstRegOp);
1984 JalrInst.setOpcode(Mips::JALR);
1985 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1986 JalrInst.addOperand(FirstRegOp);
1988 } else if (Opcode == Mips::JalTwoReg) {
1989 // jal $rd, $rs => jalr $rd, $rs
1990 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1991 JalrInst.addOperand(FirstRegOp);
1992 const MCOperand SecondRegOp = Inst.getOperand(1);
1993 JalrInst.addOperand(SecondRegOp);
1995 Instructions.push_back(JalrInst);
1997 // If .set reorder is active, emit a NOP after it.
1998 if (AssemblerOptions.back()->isReorder()) {
1999 // This is a 32-bit NOP because these 2 pseudo-instructions
2000 // do not have a short delay slot.
2002 NopInst.setOpcode(Mips::SLL);
2003 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2004 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2005 NopInst.addOperand(MCOperand::createImm(0));
2006 Instructions.push_back(NopInst);
2012 /// Can the value be represented by a unsigned N-bit value and a shift left?
2013 template<unsigned N>
2014 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2015 unsigned BitNum = findFirstSet(x);
2017 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2020 /// Load (or add) an immediate into a register.
2022 /// @param ImmValue The immediate to load.
2023 /// @param DstReg The register that will hold the immediate.
2024 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2025 /// for a simple initialization.
2026 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2027 /// @param IsAddress True if the immediate represents an address. False if it
2029 /// @param IDLoc Location of the immediate in the source file.
2030 /// @param Instructions The instructions emitted by this expansion.
2031 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2032 unsigned SrcReg, bool Is32BitImm,
2033 bool IsAddress, SMLoc IDLoc,
2034 SmallVectorImpl<MCInst> &Instructions) {
2035 if (!Is32BitImm && !isGP64bit()) {
2036 Error(IDLoc, "instruction requires a 64-bit architecture");
2041 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2042 // Sign extend up to 64-bit so that the predicates match the hardware
2043 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2045 ImmValue = SignExtend64<32>(ImmValue);
2047 Error(IDLoc, "instruction requires a 32-bit immediate");
2052 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2053 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2055 bool UseSrcReg = false;
2056 if (SrcReg != Mips::NoRegister)
2059 unsigned TmpReg = DstReg;
2060 if (UseSrcReg && (DstReg == SrcReg)) {
2061 // At this point we need AT to perform the expansions and we exit if it is
2063 unsigned ATReg = getATReg(IDLoc);
2069 if (isInt<16>(ImmValue)) {
2073 // This doesn't quite follow the usual ABI expectations for N32 but matches
2074 // traditional assembler behaviour. N32 would normally use addiu for both
2075 // integers and addresses.
2076 if (IsAddress && !Is32BitImm) {
2077 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2081 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2085 if (isUInt<16>(ImmValue)) {
2086 unsigned TmpReg = DstReg;
2087 if (SrcReg == DstReg) {
2088 TmpReg = getATReg(IDLoc);
2093 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2095 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2099 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2100 warnIfNoMacro(IDLoc);
2102 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2103 uint16_t Bits15To0 = ImmValue & 0xffff;
2105 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2106 // Traditional behaviour seems to special case this particular value. It's
2107 // not clear why other masks are handled differently.
2108 if (ImmValue == 0xffffffff) {
2109 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2110 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2112 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2116 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2118 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2119 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2121 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2123 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2127 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2129 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2131 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2135 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2137 Error(IDLoc, "instruction requires a 32-bit immediate");
2141 // Traditionally, these immediates are shifted as little as possible and as
2142 // such we align the most significant bit to bit 15 of our temporary.
2143 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2144 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2145 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2146 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2147 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2148 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2151 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2156 warnIfNoMacro(IDLoc);
2158 // The remaining case is packed with a sequence of dsll and ori with zeros
2159 // being omitted and any neighbouring dsll's being coalesced.
2160 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2162 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2163 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2164 IDLoc, Instructions))
2167 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2168 // skip it and defer the shift to the next chunk.
2169 unsigned ShiftCarriedForwards = 16;
2170 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2171 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2173 if (ImmChunk != 0) {
2174 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2176 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2177 ShiftCarriedForwards = 0;
2180 ShiftCarriedForwards += 16;
2182 ShiftCarriedForwards -= 16;
2184 // Finish any remaining shifts left by trailing zeros.
2185 if (ShiftCarriedForwards)
2186 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2190 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2195 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2196 SmallVectorImpl<MCInst> &Instructions) {
2197 const MCOperand &ImmOp = Inst.getOperand(1);
2198 assert(ImmOp.isImm() && "expected immediate operand kind");
2199 const MCOperand &DstRegOp = Inst.getOperand(0);
2200 assert(DstRegOp.isReg() && "expected register operand kind");
2202 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2203 Is32BitImm, false, IDLoc, Instructions))
2209 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2210 const MCOperand &Offset,
2211 bool Is32BitAddress, SMLoc IDLoc,
2212 SmallVectorImpl<MCInst> &Instructions) {
2213 // la can't produce a usable address when addresses are 64-bit.
2214 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2215 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2216 // We currently can't do this because we depend on the equality
2217 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2218 Error(IDLoc, "la used to load 64-bit address");
2219 // Continue as if we had 'dla' instead.
2220 Is32BitAddress = false;
2223 // dla requires 64-bit addresses.
2224 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2225 Error(IDLoc, "instruction requires a 64-bit architecture");
2229 if (!Offset.isImm())
2230 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2231 Is32BitAddress, IDLoc, Instructions);
2233 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2234 IDLoc, Instructions);
2237 bool MipsAsmParser::loadAndAddSymbolAddress(
2238 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2239 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2240 warnIfNoMacro(IDLoc);
2242 // FIXME: The way we're handling symbols right now prevents simple expressions
2243 // like foo+8. We'll be able to fix this once our unary operators (%hi
2244 // and similar) are treated as operators rather than as fixup types.
2245 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2246 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2247 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2248 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2249 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2251 bool UseSrcReg = SrcReg != Mips::NoRegister;
2253 // This is the 64-bit symbol address expansion.
2254 if (ABI.ArePtrs64bit() && isGP64bit()) {
2255 // We always need AT for the 64-bit expansion.
2256 // If it is not available we exit.
2257 unsigned ATReg = getATReg(IDLoc);
2261 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2262 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2263 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2264 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2266 if (UseSrcReg && (DstReg == SrcReg)) {
2267 // If $rs is the same as $rd:
2268 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2269 // daddiu $at, $at, %higher(sym)
2270 // dsll $at, $at, 16
2271 // daddiu $at, $at, %hi(sym)
2272 // dsll $at, $at, 16
2273 // daddiu $at, $at, %lo(sym)
2274 // daddu $rd, $at, $rd
2275 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2277 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2278 IDLoc, Instructions);
2279 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2280 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2282 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2283 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2285 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2290 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2291 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2292 // lui $at, %hi(sym)
2293 // daddiu $rd, $rd, %higher(sym)
2294 // daddiu $at, $at, %lo(sym)
2295 // dsll32 $rd, $rd, 0
2296 // daddu $rd, $rd, $at
2297 // (daddu $rd, $rd, $rs)
2298 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2300 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2302 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2303 IDLoc, Instructions);
2304 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2306 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2307 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2309 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2314 // And now, the 32-bit symbol address expansion:
2315 // If $rs is the same as $rd:
2316 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2317 // ori $at, $at, %lo(sym)
2318 // addu $rd, $at, $rd
2319 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2320 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2321 // ori $rd, $rd, %lo(sym)
2322 // (addu $rd, $rd, $rs)
2323 unsigned TmpReg = DstReg;
2324 if (UseSrcReg && (DstReg == SrcReg)) {
2325 // If $rs is the same as $rd, we need to use AT.
2326 // If it is not available we exit.
2327 unsigned ATReg = getATReg(IDLoc);
2333 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2334 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2338 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2340 assert(DstReg == TmpReg);
2345 bool MipsAsmParser::expandUncondBranchMMPseudo(
2346 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2347 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2348 "unexpected number of operands");
2350 MCOperand Offset = Inst.getOperand(0);
2351 if (Offset.isExpr()) {
2353 Inst.setOpcode(Mips::BEQ_MM);
2354 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2355 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2356 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2358 assert(Offset.isImm() && "expected immediate operand kind");
2359 if (isIntN(11, Offset.getImm())) {
2360 // If offset fits into 11 bits then this instruction becomes microMIPS
2361 // 16-bit unconditional branch instruction.
2362 if (inMicroMipsMode())
2363 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2365 if (!isIntN(17, Offset.getImm()))
2366 Error(IDLoc, "branch target out of range");
2367 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2368 Error(IDLoc, "branch to misaligned address");
2370 Inst.setOpcode(Mips::BEQ_MM);
2371 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2372 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2373 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2376 Instructions.push_back(Inst);
2378 // If .set reorder is active and branch instruction has a delay slot,
2379 // emit a NOP after it.
2380 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2381 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2382 createNop(true, IDLoc, Instructions);
2387 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2388 SmallVectorImpl<MCInst> &Instructions) {
2389 const MCOperand &DstRegOp = Inst.getOperand(0);
2390 assert(DstRegOp.isReg() && "expected register operand kind");
2392 const MCOperand &ImmOp = Inst.getOperand(1);
2393 assert(ImmOp.isImm() && "expected immediate operand kind");
2395 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2396 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2398 unsigned OpCode = 0;
2399 switch(Inst.getOpcode()) {
2407 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2411 int64_t ImmValue = ImmOp.getImm();
2412 if (ImmValue == 0) {
2414 BranchInst.setOpcode(OpCode);
2415 BranchInst.addOperand(DstRegOp);
2416 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2417 BranchInst.addOperand(MemOffsetOp);
2418 Instructions.push_back(BranchInst);
2420 warnIfNoMacro(IDLoc);
2422 unsigned ATReg = getATReg(IDLoc);
2426 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2427 IDLoc, Instructions))
2431 BranchInst.setOpcode(OpCode);
2432 BranchInst.addOperand(DstRegOp);
2433 BranchInst.addOperand(MCOperand::createReg(ATReg));
2434 BranchInst.addOperand(MemOffsetOp);
2435 Instructions.push_back(BranchInst);
2440 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2441 SmallVectorImpl<MCInst> &Instructions,
2442 bool isLoad, bool isImmOpnd) {
2444 unsigned ImmOffset, HiOffset, LoOffset;
2445 const MCExpr *ExprOffset;
2447 // 1st operand is either the source or destination register.
2448 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2449 unsigned RegOpNum = Inst.getOperand(0).getReg();
2450 // 2nd operand is the base register.
2451 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2452 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2453 // 3rd operand is either an immediate or expression.
2455 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2456 ImmOffset = Inst.getOperand(2).getImm();
2457 LoOffset = ImmOffset & 0x0000ffff;
2458 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2459 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2460 if (LoOffset & 0x8000)
2463 ExprOffset = Inst.getOperand(2).getExpr();
2464 // All instructions will have the same location.
2465 TempInst.setLoc(IDLoc);
2466 // These are some of the types of expansions we perform here:
2467 // 1) lw $8, sym => lui $8, %hi(sym)
2468 // lw $8, %lo(sym)($8)
2469 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2471 // lw $8, %lo(offset)($9)
2472 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2474 // lw $8, %lo(offset)($at)
2475 // 4) sw $8, sym => lui $at, %hi(sym)
2476 // sw $8, %lo(sym)($at)
2477 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2479 // sw $8, %lo(offset)($at)
2480 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2481 // ldc1 $f0, %lo(sym)($at)
2483 // For load instructions we can use the destination register as a temporary
2484 // if base and dst are different (examples 1 and 2) and if the base register
2485 // is general purpose otherwise we must use $at (example 6) and error if it's
2486 // not available. For stores we must use $at (examples 4 and 5) because we
2487 // must not clobber the source register setting up the offset.
2488 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2489 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2490 unsigned RegClassIDOp0 =
2491 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2492 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2493 (RegClassIDOp0 == Mips::GPR64RegClassID);
2494 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2495 TmpRegNum = RegOpNum;
2497 // At this point we need AT to perform the expansions and we exit if it is
2499 TmpRegNum = getATReg(IDLoc);
2504 TempInst.setOpcode(Mips::LUi);
2505 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2507 TempInst.addOperand(MCOperand::createImm(HiOffset));
2509 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2510 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2512 // Add the instruction to the list.
2513 Instructions.push_back(TempInst);
2514 // Prepare TempInst for next instruction.
2516 // Add temp register to base.
2517 if (BaseRegNum != Mips::ZERO) {
2518 TempInst.setOpcode(Mips::ADDu);
2519 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2520 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2521 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2522 Instructions.push_back(TempInst);
2525 // And finally, create original instruction with low part
2526 // of offset and new base.
2527 TempInst.setOpcode(Inst.getOpcode());
2528 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2529 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2531 TempInst.addOperand(MCOperand::createImm(LoOffset));
2533 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2534 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2536 Instructions.push_back(TempInst);
2541 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2542 SmallVectorImpl<MCInst> &Instructions) {
2543 unsigned OpNum = Inst.getNumOperands();
2544 unsigned Opcode = Inst.getOpcode();
2545 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2547 assert (Inst.getOperand(OpNum - 1).isImm() &&
2548 Inst.getOperand(OpNum - 2).isReg() &&
2549 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2551 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2552 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2553 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2554 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2555 // It can be implemented as SWM16 or LWM16 instruction.
2556 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2558 Inst.setOpcode(NewOpcode);
2559 Instructions.push_back(Inst);
2563 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2564 SmallVectorImpl<MCInst> &Instructions) {
2565 unsigned PseudoOpcode = Inst.getOpcode();
2566 unsigned SrcReg = Inst.getOperand(0).getReg();
2567 unsigned TrgReg = Inst.getOperand(1).getReg();
2568 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2570 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2571 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2573 switch (PseudoOpcode) {
2576 AcceptsEquality = false;
2577 ReverseOrderSLT = false;
2578 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2579 ZeroSrcOpcode = Mips::BGTZ;
2580 ZeroTrgOpcode = Mips::BLTZ;
2584 AcceptsEquality = true;
2585 ReverseOrderSLT = true;
2586 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2587 ZeroSrcOpcode = Mips::BGEZ;
2588 ZeroTrgOpcode = Mips::BLEZ;
2592 AcceptsEquality = true;
2593 ReverseOrderSLT = false;
2594 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2595 ZeroSrcOpcode = Mips::BLEZ;
2596 ZeroTrgOpcode = Mips::BGEZ;
2600 AcceptsEquality = false;
2601 ReverseOrderSLT = true;
2602 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2603 ZeroSrcOpcode = Mips::BLTZ;
2604 ZeroTrgOpcode = Mips::BGTZ;
2607 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2611 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2612 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2613 if (IsSrcRegZero && IsTrgRegZero) {
2614 // FIXME: All of these Opcode-specific if's are needed for compatibility
2615 // with GAS' behaviour. However, they may not generate the most efficient
2616 // code in some circumstances.
2617 if (PseudoOpcode == Mips::BLT) {
2618 BranchInst.setOpcode(Mips::BLTZ);
2619 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2620 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2621 Instructions.push_back(BranchInst);
2624 if (PseudoOpcode == Mips::BLE) {
2625 BranchInst.setOpcode(Mips::BLEZ);
2626 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2627 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2628 Instructions.push_back(BranchInst);
2629 Warning(IDLoc, "branch is always taken");
2632 if (PseudoOpcode == Mips::BGE) {
2633 BranchInst.setOpcode(Mips::BGEZ);
2634 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2635 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2636 Instructions.push_back(BranchInst);
2637 Warning(IDLoc, "branch is always taken");
2640 if (PseudoOpcode == Mips::BGT) {
2641 BranchInst.setOpcode(Mips::BGTZ);
2642 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2643 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2644 Instructions.push_back(BranchInst);
2647 if (PseudoOpcode == Mips::BGTU) {
2648 BranchInst.setOpcode(Mips::BNE);
2649 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2650 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2651 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2652 Instructions.push_back(BranchInst);
2655 if (AcceptsEquality) {
2656 // If both registers are $0 and the pseudo-branch accepts equality, it
2657 // will always be taken, so we emit an unconditional branch.
2658 BranchInst.setOpcode(Mips::BEQ);
2659 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2660 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2661 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2662 Instructions.push_back(BranchInst);
2663 Warning(IDLoc, "branch is always taken");
2666 // If both registers are $0 and the pseudo-branch does not accept
2667 // equality, it will never be taken, so we don't have to emit anything.
2670 if (IsSrcRegZero || IsTrgRegZero) {
2671 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2672 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2673 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2674 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2675 // the pseudo-branch will never be taken, so we don't emit anything.
2676 // This only applies to unsigned pseudo-branches.
2679 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2680 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2681 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2682 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2683 // the pseudo-branch will always be taken, so we emit an unconditional
2685 // This only applies to unsigned pseudo-branches.
2686 BranchInst.setOpcode(Mips::BEQ);
2687 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2688 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2689 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2690 Instructions.push_back(BranchInst);
2691 Warning(IDLoc, "branch is always taken");
2695 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2696 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2697 // the pseudo-branch will be taken only when the non-zero register is
2698 // different from 0, so we emit a BNEZ.
2700 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2701 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2702 // the pseudo-branch will be taken only when the non-zero register is
2703 // equal to 0, so we emit a BEQZ.
2705 // Because only BLEU and BGEU branch on equality, we can use the
2706 // AcceptsEquality variable to decide when to emit the BEQZ.
2707 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2708 BranchInst.addOperand(
2709 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2710 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2711 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2712 Instructions.push_back(BranchInst);
2715 // If we have a signed pseudo-branch and one of the registers is $0,
2716 // we can use an appropriate compare-to-zero branch. We select which one
2717 // to use in the switch statement above.
2718 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2719 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2720 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2721 Instructions.push_back(BranchInst);
2725 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2726 // expansions. If it is not available, we return.
2727 unsigned ATRegNum = getATReg(IDLoc);
2731 warnIfNoMacro(IDLoc);
2733 // SLT fits well with 2 of our 4 pseudo-branches:
2734 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2735 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2736 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2737 // This is accomplished by using a BNEZ with the result of the SLT.
2739 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2740 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2741 // Because only BGE and BLE branch on equality, we can use the
2742 // AcceptsEquality variable to decide when to emit the BEQZ.
2743 // Note that the order of the SLT arguments doesn't change between
2746 // The same applies to the unsigned variants, except that SLTu is used
2749 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2750 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2751 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2752 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2753 Instructions.push_back(SetInst);
2755 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2756 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2757 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2758 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2759 Instructions.push_back(BranchInst);
2763 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2764 SmallVectorImpl<MCInst> &Instructions,
2765 const bool IsMips64, const bool Signed) {
2766 if (hasMips32r6()) {
2767 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2771 warnIfNoMacro(IDLoc);
2773 const MCOperand &RsRegOp = Inst.getOperand(0);
2774 assert(RsRegOp.isReg() && "expected register operand kind");
2775 unsigned RsReg = RsRegOp.getReg();
2777 const MCOperand &RtRegOp = Inst.getOperand(1);
2778 assert(RtRegOp.isReg() && "expected register operand kind");
2779 unsigned RtReg = RtRegOp.getReg();
2784 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2785 ZeroReg = Mips::ZERO_64;
2787 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2788 ZeroReg = Mips::ZERO;
2791 bool UseTraps = useTraps();
2793 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2794 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2795 Warning(IDLoc, "dividing zero by zero");
2797 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2799 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2803 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2807 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2812 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2813 Warning(IDLoc, "division by zero");
2816 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2820 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2825 // FIXME: The values for these two BranchTarget variables may be different in
2826 // micromips. These magic numbers need to be removed.
2827 unsigned BranchTargetNoTraps;
2828 unsigned BranchTarget;
2831 BranchTarget = IsMips64 ? 12 : 8;
2832 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2834 BranchTarget = IsMips64 ? 20 : 16;
2835 BranchTargetNoTraps = 8;
2836 // Branch to the li instruction.
2837 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2841 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2844 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2847 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2851 unsigned ATReg = getATReg(IDLoc);
2855 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2857 // Branch to the mflo instruction.
2858 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2859 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2860 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2862 // Branch to the mflo instruction.
2863 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2864 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2868 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2870 // Branch to the mflo instruction.
2871 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2872 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2873 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2875 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2879 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2880 SmallVectorImpl<MCInst> &Instructions) {
2881 if (hasMips32r6() || hasMips64r6()) {
2882 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2886 warnIfNoMacro(IDLoc);
2888 const MCOperand &DstRegOp = Inst.getOperand(0);
2889 assert(DstRegOp.isReg() && "expected register operand kind");
2891 const MCOperand &SrcRegOp = Inst.getOperand(1);
2892 assert(SrcRegOp.isReg() && "expected register operand kind");
2894 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2895 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2897 unsigned DstReg = DstRegOp.getReg();
2898 unsigned SrcReg = SrcRegOp.getReg();
2899 int64_t OffsetValue = OffsetImmOp.getImm();
2901 // NOTE: We always need AT for ULHU, as it is always used as the source
2902 // register for one of the LBu's.
2903 unsigned ATReg = getATReg(IDLoc);
2907 // When the value of offset+1 does not fit in 16 bits, we have to load the
2908 // offset in AT, (D)ADDu the original source register (if there was one), and
2909 // then use AT as the source register for the 2 generated LBu's.
2910 bool LoadedOffsetInAT = false;
2911 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2912 LoadedOffsetInAT = true;
2914 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2915 true, IDLoc, Instructions))
2918 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2919 // because it will make our output more similar to GAS'. For example,
2920 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2921 // instead of just an "ori $1, $9, 32768".
2922 // NOTE: If there is no source register specified in the ULHU, the parser
2923 // will interpret it as $0.
2924 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2925 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2928 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2929 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2930 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2932 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2934 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2935 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2937 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2938 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2941 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2944 TmpInst.setOpcode(Mips::LBu);
2945 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2946 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2947 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2948 Instructions.push_back(TmpInst);
2951 TmpInst.setOpcode(Mips::LBu);
2952 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2953 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2954 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2955 Instructions.push_back(TmpInst);
2958 TmpInst.setOpcode(Mips::SLL);
2959 TmpInst.addOperand(MCOperand::createReg(SllReg));
2960 TmpInst.addOperand(MCOperand::createReg(SllReg));
2961 TmpInst.addOperand(MCOperand::createImm(8));
2962 Instructions.push_back(TmpInst);
2965 TmpInst.setOpcode(Mips::OR);
2966 TmpInst.addOperand(MCOperand::createReg(DstReg));
2967 TmpInst.addOperand(MCOperand::createReg(DstReg));
2968 TmpInst.addOperand(MCOperand::createReg(ATReg));
2969 Instructions.push_back(TmpInst);
2974 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2975 SmallVectorImpl<MCInst> &Instructions) {
2976 if (hasMips32r6() || hasMips64r6()) {
2977 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2981 const MCOperand &DstRegOp = Inst.getOperand(0);
2982 assert(DstRegOp.isReg() && "expected register operand kind");
2984 const MCOperand &SrcRegOp = Inst.getOperand(1);
2985 assert(SrcRegOp.isReg() && "expected register operand kind");
2987 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2988 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2990 unsigned SrcReg = SrcRegOp.getReg();
2991 int64_t OffsetValue = OffsetImmOp.getImm();
2994 // When the value of offset+3 does not fit in 16 bits, we have to load the
2995 // offset in AT, (D)ADDu the original source register (if there was one), and
2996 // then use AT as the source register for the generated LWL and LWR.
2997 bool LoadedOffsetInAT = false;
2998 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2999 ATReg = getATReg(IDLoc);
3002 LoadedOffsetInAT = true;
3004 warnIfNoMacro(IDLoc);
3006 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3007 true, IDLoc, Instructions))
3010 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3011 // because it will make our output more similar to GAS'. For example,
3012 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3013 // instead of just an "ori $1, $9, 32768".
3014 // NOTE: If there is no source register specified in the ULW, the parser
3015 // will interpret it as $0.
3016 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3017 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3020 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3021 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3023 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3024 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3026 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3027 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3030 MCInst LeftLoadInst;
3031 LeftLoadInst.setOpcode(Mips::LWL);
3032 LeftLoadInst.addOperand(DstRegOp);
3033 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3034 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3035 Instructions.push_back(LeftLoadInst);
3037 MCInst RightLoadInst;
3038 RightLoadInst.setOpcode(Mips::LWR);
3039 RightLoadInst.addOperand(DstRegOp);
3040 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3041 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3042 Instructions.push_back(RightLoadInst);
3047 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3048 SmallVectorImpl<MCInst> &Instructions) {
3050 if (hasShortDelaySlot) {
3051 NopInst.setOpcode(Mips::MOVE16_MM);
3052 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3053 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3055 NopInst.setOpcode(Mips::SLL);
3056 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3057 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3058 NopInst.addOperand(MCOperand::createImm(0));
3060 Instructions.push_back(NopInst);
3063 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3064 unsigned TrgReg, bool Is64Bit,
3065 SmallVectorImpl<MCInst> &Instructions) {
3066 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3070 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3071 // As described by the Mips32r2 spec, the registers Rd and Rs for
3072 // jalr.hb must be different.
3073 unsigned Opcode = Inst.getOpcode();
3075 if (Opcode == Mips::JALR_HB &&
3076 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3077 return Match_RequiresDifferentSrcAndDst;
3079 return Match_Success;
3082 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3083 OperandVector &Operands,
3085 uint64_t &ErrorInfo,
3086 bool MatchingInlineAsm) {
3089 SmallVector<MCInst, 8> Instructions;
3090 unsigned MatchResult =
3091 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3093 switch (MatchResult) {
3094 case Match_Success: {
3095 if (processInstruction(Inst, IDLoc, Instructions))
3097 for (unsigned i = 0; i < Instructions.size(); i++)
3098 Out.EmitInstruction(Instructions[i], STI);
3101 case Match_MissingFeature:
3102 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3104 case Match_InvalidOperand: {
3105 SMLoc ErrorLoc = IDLoc;
3106 if (ErrorInfo != ~0ULL) {
3107 if (ErrorInfo >= Operands.size())
3108 return Error(IDLoc, "too few operands for instruction");
3110 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3111 if (ErrorLoc == SMLoc())
3115 return Error(ErrorLoc, "invalid operand for instruction");
3117 case Match_MnemonicFail:
3118 return Error(IDLoc, "invalid instruction");
3119 case Match_RequiresDifferentSrcAndDst:
3120 return Error(IDLoc, "source and destination must be different");
3123 llvm_unreachable("Implement any new match types added!");
3126 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3127 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3128 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3129 ") without \".set noat\"");
3132 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3133 if (!AssemblerOptions.back()->isMacro())
3134 Warning(Loc, "macro instruction expanded into multiple instructions");
3138 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3139 SMRange Range, bool ShowColors) {
3140 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3141 Range, SMFixIt(Range, FixMsg),
3145 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3148 CC = StringSwitch<unsigned>(Name)
3184 if (!(isABI_N32() || isABI_N64()))
3187 if (12 <= CC && CC <= 15) {
3188 // Name is one of t4-t7
3189 AsmToken RegTok = getLexer().peekTok();
3190 SMRange RegRange = RegTok.getLocRange();
3192 StringRef FixedName = StringSwitch<StringRef>(Name)
3198 assert(FixedName != "" && "Register name is not one of t4-t7.");
3200 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3201 "Did you mean $" + FixedName + "?", RegRange);
3204 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3205 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3206 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3207 if (8 <= CC && CC <= 11)
3211 CC = StringSwitch<unsigned>(Name)
3223 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3226 CC = StringSwitch<unsigned>(Name)
3227 .Case("hwr_cpunum", 0)
3228 .Case("hwr_synci_step", 1)
3230 .Case("hwr_ccres", 3)
3231 .Case("hwr_ulr", 29)
3237 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3239 if (Name[0] == 'f') {
3240 StringRef NumString = Name.substr(1);
3242 if (NumString.getAsInteger(10, IntVal))
3243 return -1; // This is not an integer.
3244 if (IntVal > 31) // Maximum index for fpu register.
3251 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3253 if (Name.startswith("fcc")) {
3254 StringRef NumString = Name.substr(3);
3256 if (NumString.getAsInteger(10, IntVal))
3257 return -1; // This is not an integer.
3258 if (IntVal > 7) // There are only 8 fcc registers.
3265 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3267 if (Name.startswith("ac")) {
3268 StringRef NumString = Name.substr(2);
3270 if (NumString.getAsInteger(10, IntVal))
3271 return -1; // This is not an integer.
3272 if (IntVal > 3) // There are only 3 acc registers.
3279 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3282 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3291 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3294 CC = StringSwitch<unsigned>(Name)
3297 .Case("msaaccess", 2)
3299 .Case("msamodify", 4)
3300 .Case("msarequest", 5)
3302 .Case("msaunmap", 7)
3308 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3309 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3311 reportParseError(Loc,
3312 "pseudo-instruction requires $at, which is not available");
3315 unsigned AT = getReg(
3316 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3320 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3321 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3324 unsigned MipsAsmParser::getGPR(int RegNo) {
3325 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3329 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3331 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3334 return getReg(RegClass, RegNum);
3337 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3338 MCAsmParser &Parser = getParser();
3339 DEBUG(dbgs() << "parseOperand\n");
3341 // Check if the current operand has a custom associated parser, if so, try to
3342 // custom parse the operand, or fallback to the general approach.
3343 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3344 if (ResTy == MatchOperand_Success)
3346 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3347 // there was a match, but an error occurred, in which case, just return that
3348 // the operand parsing failed.
3349 if (ResTy == MatchOperand_ParseFail)
3352 DEBUG(dbgs() << ".. Generic Parser\n");
3354 switch (getLexer().getKind()) {
3356 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3358 case AsmToken::Dollar: {
3359 // Parse the register.
3360 SMLoc S = Parser.getTok().getLoc();
3362 // Almost all registers have been parsed by custom parsers. There is only
3363 // one exception to this. $zero (and it's alias $0) will reach this point
3364 // for div, divu, and similar instructions because it is not an operand
3365 // to the instruction definition but an explicit register. Special case
3366 // this situation for now.
3367 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3370 // Maybe it is a symbol reference.
3371 StringRef Identifier;
3372 if (Parser.parseIdentifier(Identifier))
3375 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3376 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3377 // Otherwise create a symbol reference.
3379 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3381 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3384 // Else drop to expression parsing.
3385 case AsmToken::LParen:
3386 case AsmToken::Minus:
3387 case AsmToken::Plus:
3388 case AsmToken::Integer:
3389 case AsmToken::Tilde:
3390 case AsmToken::String: {
3391 DEBUG(dbgs() << ".. generic integer\n");
3392 OperandMatchResultTy ResTy = parseImm(Operands);
3393 return ResTy != MatchOperand_Success;
3395 case AsmToken::Percent: {
3396 // It is a symbol reference or constant expression.
3397 const MCExpr *IdVal;
3398 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3399 if (parseRelocOperand(IdVal))
3402 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3404 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3406 } // case AsmToken::Percent
3407 } // switch(getLexer().getKind())
3411 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3412 StringRef RelocStr) {
3414 // Check the type of the expression.
3415 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3416 // It's a constant, evaluate reloc value.
3418 switch (getVariantKind(RelocStr)) {
3419 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3420 // Get the 1st 16-bits.
3421 Val = MCE->getValue() & 0xffff;
3423 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3424 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3425 // 16 bits being negative.
3426 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3428 case MCSymbolRefExpr::VK_Mips_HIGHER:
3429 // Get the 3rd 16-bits.
3430 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3432 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3433 // Get the 4th 16-bits.
3434 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3437 report_fatal_error("unsupported reloc value");
3439 return MCConstantExpr::create(Val, getContext());
3442 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3443 // It's a symbol, create a symbolic expression from the symbol.
3444 const MCSymbol *Symbol = &MSRE->getSymbol();
3445 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3446 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3450 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3451 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3453 // Try to create target expression.
3454 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3455 return MipsMCExpr::create(VK, Expr, getContext());
3457 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3458 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3459 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3463 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3464 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3465 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3468 // Just return the original expression.
3472 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3474 switch (Expr->getKind()) {
3475 case MCExpr::Constant:
3477 case MCExpr::SymbolRef:
3478 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3479 case MCExpr::Binary:
3480 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3481 if (!isEvaluated(BE->getLHS()))
3483 return isEvaluated(BE->getRHS());
3486 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3487 case MCExpr::Target:
3493 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3494 MCAsmParser &Parser = getParser();
3495 Parser.Lex(); // Eat the % token.
3496 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3497 if (Tok.isNot(AsmToken::Identifier))
3500 std::string Str = Tok.getIdentifier();
3502 Parser.Lex(); // Eat the identifier.
3503 // Now make an expression from the rest of the operand.
3504 const MCExpr *IdVal;
3507 if (getLexer().getKind() == AsmToken::LParen) {
3509 Parser.Lex(); // Eat the '(' token.
3510 if (getLexer().getKind() == AsmToken::Percent) {
3511 Parser.Lex(); // Eat the % token.
3512 const AsmToken &nextTok = Parser.getTok();
3513 if (nextTok.isNot(AsmToken::Identifier))
3516 Str += nextTok.getIdentifier();
3517 Parser.Lex(); // Eat the identifier.
3518 if (getLexer().getKind() != AsmToken::LParen)
3523 if (getParser().parseParenExpression(IdVal, EndLoc))
3526 while (getLexer().getKind() == AsmToken::RParen)
3527 Parser.Lex(); // Eat the ')' token.
3530 return true; // Parenthesis must follow the relocation operand.
3532 Res = evaluateRelocExpr(IdVal, Str);
3536 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3538 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3539 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3540 if (ResTy == MatchOperand_Success) {
3541 assert(Operands.size() == 1);
3542 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3543 StartLoc = Operand.getStartLoc();
3544 EndLoc = Operand.getEndLoc();
3546 // AFAIK, we only support numeric registers and named GPR's in CFI
3548 // Don't worry about eating tokens before failing. Using an unrecognised
3549 // register is a parse error.
3550 if (Operand.isGPRAsmReg()) {
3551 // Resolve to GPR32 or GPR64 appropriately.
3552 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3555 return (RegNo == (unsigned)-1);
3558 assert(Operands.size() == 0);
3559 return (RegNo == (unsigned)-1);
3562 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3563 MCAsmParser &Parser = getParser();
3566 unsigned NumOfLParen = 0;
3568 while (getLexer().getKind() == AsmToken::LParen) {
3573 switch (getLexer().getKind()) {
3576 case AsmToken::Identifier:
3577 case AsmToken::LParen:
3578 case AsmToken::Integer:
3579 case AsmToken::Minus:
3580 case AsmToken::Plus:
3582 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3584 Result = (getParser().parseExpression(Res));
3585 while (getLexer().getKind() == AsmToken::RParen)
3588 case AsmToken::Percent:
3589 Result = parseRelocOperand(Res);
3594 MipsAsmParser::OperandMatchResultTy
3595 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3596 MCAsmParser &Parser = getParser();
3597 DEBUG(dbgs() << "parseMemOperand\n");
3598 const MCExpr *IdVal = nullptr;
3600 bool isParenExpr = false;
3601 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3602 // First operand is the offset.
3603 S = Parser.getTok().getLoc();
3605 if (getLexer().getKind() == AsmToken::LParen) {
3610 if (getLexer().getKind() != AsmToken::Dollar) {
3611 if (parseMemOffset(IdVal, isParenExpr))
3612 return MatchOperand_ParseFail;
3614 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3615 if (Tok.isNot(AsmToken::LParen)) {
3616 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3617 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3619 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3620 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3621 return MatchOperand_Success;
3623 if (Tok.is(AsmToken::EndOfStatement)) {
3625 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3627 // Zero register assumed, add a memory operand with ZERO as its base.
3628 // "Base" will be managed by k_Memory.
3629 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3632 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3633 return MatchOperand_Success;
3635 Error(Parser.getTok().getLoc(), "'(' expected");
3636 return MatchOperand_ParseFail;
3639 Parser.Lex(); // Eat the '(' token.
3642 Res = parseAnyRegister(Operands);
3643 if (Res != MatchOperand_Success)
3646 if (Parser.getTok().isNot(AsmToken::RParen)) {
3647 Error(Parser.getTok().getLoc(), "')' expected");
3648 return MatchOperand_ParseFail;
3651 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3653 Parser.Lex(); // Eat the ')' token.
3656 IdVal = MCConstantExpr::create(0, getContext());
3658 // Replace the register operand with the memory operand.
3659 std::unique_ptr<MipsOperand> op(
3660 static_cast<MipsOperand *>(Operands.back().release()));
3661 // Remove the register from the operands.
3662 // "op" will be managed by k_Memory.
3663 Operands.pop_back();
3664 // Add the memory operand.
3665 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3667 if (IdVal->evaluateAsAbsolute(Imm))
3668 IdVal = MCConstantExpr::create(Imm, getContext());
3669 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3670 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3674 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3675 return MatchOperand_Success;
3678 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3679 MCAsmParser &Parser = getParser();
3680 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3682 SMLoc S = Parser.getTok().getLoc();
3684 if (Sym->isVariable())
3685 Expr = Sym->getVariableValue();
3688 if (Expr->getKind() == MCExpr::SymbolRef) {
3689 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3690 StringRef DefSymbol = Ref->getSymbol().getName();
3691 if (DefSymbol.startswith("$")) {
3692 OperandMatchResultTy ResTy =
3693 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3694 if (ResTy == MatchOperand_Success) {
3697 } else if (ResTy == MatchOperand_ParseFail)
3698 llvm_unreachable("Should never ParseFail");
3701 } else if (Expr->getKind() == MCExpr::Constant) {
3703 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3705 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3712 MipsAsmParser::OperandMatchResultTy
3713 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3714 StringRef Identifier,
3716 int Index = matchCPURegisterName(Identifier);
3718 Operands.push_back(MipsOperand::createGPRReg(
3719 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3720 return MatchOperand_Success;
3723 Index = matchHWRegsRegisterName(Identifier);
3725 Operands.push_back(MipsOperand::createHWRegsReg(
3726 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3727 return MatchOperand_Success;
3730 Index = matchFPURegisterName(Identifier);
3732 Operands.push_back(MipsOperand::createFGRReg(
3733 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3734 return MatchOperand_Success;
3737 Index = matchFCCRegisterName(Identifier);
3739 Operands.push_back(MipsOperand::createFCCReg(
3740 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3741 return MatchOperand_Success;
3744 Index = matchACRegisterName(Identifier);
3746 Operands.push_back(MipsOperand::createACCReg(
3747 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3748 return MatchOperand_Success;
3751 Index = matchMSA128RegisterName(Identifier);
3753 Operands.push_back(MipsOperand::createMSA128Reg(
3754 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3755 return MatchOperand_Success;
3758 Index = matchMSA128CtrlRegisterName(Identifier);
3760 Operands.push_back(MipsOperand::createMSACtrlReg(
3761 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3762 return MatchOperand_Success;
3765 return MatchOperand_NoMatch;
3768 MipsAsmParser::OperandMatchResultTy
3769 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3770 MCAsmParser &Parser = getParser();
3771 auto Token = Parser.getLexer().peekTok(false);
3773 if (Token.is(AsmToken::Identifier)) {
3774 DEBUG(dbgs() << ".. identifier\n");
3775 StringRef Identifier = Token.getIdentifier();
3776 OperandMatchResultTy ResTy =
3777 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3779 } else if (Token.is(AsmToken::Integer)) {
3780 DEBUG(dbgs() << ".. integer\n");
3781 Operands.push_back(MipsOperand::createNumericReg(
3782 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3784 return MatchOperand_Success;
3787 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3789 return MatchOperand_NoMatch;
3792 MipsAsmParser::OperandMatchResultTy
3793 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3794 MCAsmParser &Parser = getParser();
3795 DEBUG(dbgs() << "parseAnyRegister\n");
3797 auto Token = Parser.getTok();
3799 SMLoc S = Token.getLoc();
3801 if (Token.isNot(AsmToken::Dollar)) {
3802 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3803 if (Token.is(AsmToken::Identifier)) {
3804 if (searchSymbolAlias(Operands))
3805 return MatchOperand_Success;
3807 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3808 return MatchOperand_NoMatch;
3810 DEBUG(dbgs() << ".. $\n");
3812 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3813 if (ResTy == MatchOperand_Success) {
3815 Parser.Lex(); // identifier
3820 MipsAsmParser::OperandMatchResultTy
3821 MipsAsmParser::parseImm(OperandVector &Operands) {
3822 MCAsmParser &Parser = getParser();
3823 switch (getLexer().getKind()) {
3825 return MatchOperand_NoMatch;
3826 case AsmToken::LParen:
3827 case AsmToken::Minus:
3828 case AsmToken::Plus:
3829 case AsmToken::Integer:
3830 case AsmToken::Tilde:
3831 case AsmToken::String:
3835 const MCExpr *IdVal;
3836 SMLoc S = Parser.getTok().getLoc();
3837 if (getParser().parseExpression(IdVal))
3838 return MatchOperand_ParseFail;
3840 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3841 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3842 return MatchOperand_Success;
3845 MipsAsmParser::OperandMatchResultTy
3846 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3847 MCAsmParser &Parser = getParser();
3848 DEBUG(dbgs() << "parseJumpTarget\n");
3850 SMLoc S = getLexer().getLoc();
3852 // Integers and expressions are acceptable
3853 OperandMatchResultTy ResTy = parseImm(Operands);
3854 if (ResTy != MatchOperand_NoMatch)
3857 // Registers are a valid target and have priority over symbols.
3858 ResTy = parseAnyRegister(Operands);
3859 if (ResTy != MatchOperand_NoMatch)
3862 const MCExpr *Expr = nullptr;
3863 if (Parser.parseExpression(Expr)) {
3864 // We have no way of knowing if a symbol was consumed so we must ParseFail
3865 return MatchOperand_ParseFail;
3868 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3869 return MatchOperand_Success;
3872 MipsAsmParser::OperandMatchResultTy
3873 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3874 MCAsmParser &Parser = getParser();
3875 const MCExpr *IdVal;
3876 // If the first token is '$' we may have register operand.
3877 if (Parser.getTok().is(AsmToken::Dollar))
3878 return MatchOperand_NoMatch;
3879 SMLoc S = Parser.getTok().getLoc();
3880 if (getParser().parseExpression(IdVal))
3881 return MatchOperand_ParseFail;
3882 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3883 assert(MCE && "Unexpected MCExpr type.");
3884 int64_t Val = MCE->getValue();
3885 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3886 Operands.push_back(MipsOperand::CreateImm(
3887 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3888 return MatchOperand_Success;
3891 MipsAsmParser::OperandMatchResultTy
3892 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3893 MCAsmParser &Parser = getParser();
3894 switch (getLexer().getKind()) {
3896 return MatchOperand_NoMatch;
3897 case AsmToken::LParen:
3898 case AsmToken::Plus:
3899 case AsmToken::Minus:
3900 case AsmToken::Integer:
3905 SMLoc S = Parser.getTok().getLoc();
3907 if (getParser().parseExpression(Expr))
3908 return MatchOperand_ParseFail;
3911 if (!Expr->evaluateAsAbsolute(Val)) {
3912 Error(S, "expected immediate value");
3913 return MatchOperand_ParseFail;
3916 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3917 // and because the CPU always adds one to the immediate field, the allowed
3918 // range becomes 1..4. We'll only check the range here and will deal
3919 // with the addition/subtraction when actually decoding/encoding
3921 if (Val < 1 || Val > 4) {
3922 Error(S, "immediate not in range (1..4)");
3923 return MatchOperand_ParseFail;
3927 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3928 return MatchOperand_Success;
3931 MipsAsmParser::OperandMatchResultTy
3932 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3933 MCAsmParser &Parser = getParser();
3934 SmallVector<unsigned, 10> Regs;
3936 unsigned PrevReg = Mips::NoRegister;
3937 bool RegRange = false;
3938 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3940 if (Parser.getTok().isNot(AsmToken::Dollar))
3941 return MatchOperand_ParseFail;
3943 SMLoc S = Parser.getTok().getLoc();
3944 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3945 SMLoc E = getLexer().getLoc();
3946 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3947 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3949 // Remove last register operand because registers from register range
3950 // should be inserted first.
3951 if (RegNo == Mips::RA) {
3952 Regs.push_back(RegNo);
3954 unsigned TmpReg = PrevReg + 1;
3955 while (TmpReg <= RegNo) {
3956 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3957 Error(E, "invalid register operand");
3958 return MatchOperand_ParseFail;
3962 Regs.push_back(TmpReg++);
3968 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3969 (RegNo != Mips::RA)) {
3970 Error(E, "$16 or $31 expected");
3971 return MatchOperand_ParseFail;
3972 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3973 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3974 Error(E, "invalid register operand");
3975 return MatchOperand_ParseFail;
3976 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3977 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3978 Error(E, "consecutive register numbers expected");
3979 return MatchOperand_ParseFail;
3982 Regs.push_back(RegNo);
3985 if (Parser.getTok().is(AsmToken::Minus))
3988 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3989 !Parser.getTok().isNot(AsmToken::Comma)) {
3990 Error(E, "',' or '-' expected");
3991 return MatchOperand_ParseFail;
3994 Lex(); // Consume comma or minus
3995 if (Parser.getTok().isNot(AsmToken::Dollar))
4001 SMLoc E = Parser.getTok().getLoc();
4002 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4003 parseMemOperand(Operands);
4004 return MatchOperand_Success;
4007 MipsAsmParser::OperandMatchResultTy
4008 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4009 MCAsmParser &Parser = getParser();
4011 SMLoc S = Parser.getTok().getLoc();
4012 if (parseAnyRegister(Operands) != MatchOperand_Success)
4013 return MatchOperand_ParseFail;
4015 SMLoc E = Parser.getTok().getLoc();
4016 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4017 unsigned Reg = Op.getGPR32Reg();
4018 Operands.pop_back();
4019 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4020 return MatchOperand_Success;
4023 MipsAsmParser::OperandMatchResultTy
4024 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4025 MCAsmParser &Parser = getParser();
4026 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4027 SmallVector<unsigned, 10> Regs;
4029 if (Parser.getTok().isNot(AsmToken::Dollar))
4030 return MatchOperand_ParseFail;
4032 SMLoc S = Parser.getTok().getLoc();
4034 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4035 return MatchOperand_ParseFail;
4037 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4038 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4039 Regs.push_back(RegNo);
4041 SMLoc E = Parser.getTok().getLoc();
4042 if (Parser.getTok().isNot(AsmToken::Comma)) {
4043 Error(E, "',' expected");
4044 return MatchOperand_ParseFail;
4050 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4051 return MatchOperand_ParseFail;
4053 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4054 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4055 Regs.push_back(RegNo);
4057 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4059 return MatchOperand_Success;
4062 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4064 MCSymbolRefExpr::VariantKind VK =
4065 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4066 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4067 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4068 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4069 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4070 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4071 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4072 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4073 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4074 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4075 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4076 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4077 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4078 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4079 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4080 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4081 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4082 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4083 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4084 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4085 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4086 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4087 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4088 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4089 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4090 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4091 .Default(MCSymbolRefExpr::VK_None);
4093 assert(VK != MCSymbolRefExpr::VK_None);
4098 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4100 /// ::= '(', register, ')'
4101 /// handle it before we iterate so we don't get tripped up by the lack of
4103 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4104 MCAsmParser &Parser = getParser();
4105 if (getLexer().is(AsmToken::LParen)) {
4107 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4109 if (parseOperand(Operands, Name)) {
4110 SMLoc Loc = getLexer().getLoc();
4111 Parser.eatToEndOfStatement();
4112 return Error(Loc, "unexpected token in argument list");
4114 if (Parser.getTok().isNot(AsmToken::RParen)) {
4115 SMLoc Loc = getLexer().getLoc();
4116 Parser.eatToEndOfStatement();
4117 return Error(Loc, "unexpected token, expected ')'");
4120 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4126 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4127 /// either one of these.
4128 /// ::= '[', register, ']'
4129 /// ::= '[', integer, ']'
4130 /// handle it before we iterate so we don't get tripped up by the lack of
4132 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4133 OperandVector &Operands) {
4134 MCAsmParser &Parser = getParser();
4135 if (getLexer().is(AsmToken::LBrac)) {
4137 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4139 if (parseOperand(Operands, Name)) {
4140 SMLoc Loc = getLexer().getLoc();
4141 Parser.eatToEndOfStatement();
4142 return Error(Loc, "unexpected token in argument list");
4144 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4145 SMLoc Loc = getLexer().getLoc();
4146 Parser.eatToEndOfStatement();
4147 return Error(Loc, "unexpected token, expected ']'");
4150 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4156 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4157 SMLoc NameLoc, OperandVector &Operands) {
4158 MCAsmParser &Parser = getParser();
4159 DEBUG(dbgs() << "ParseInstruction\n");
4161 // We have reached first instruction, module directive are now forbidden.
4162 getTargetStreamer().forbidModuleDirective();
4164 // Check if we have valid mnemonic
4165 if (!mnemonicIsValid(Name, 0)) {
4166 Parser.eatToEndOfStatement();
4167 return Error(NameLoc, "unknown instruction");
4169 // First operand in MCInst is instruction mnemonic.
4170 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4172 // Read the remaining operands.
4173 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4174 // Read the first operand.
4175 if (parseOperand(Operands, Name)) {
4176 SMLoc Loc = getLexer().getLoc();
4177 Parser.eatToEndOfStatement();
4178 return Error(Loc, "unexpected token in argument list");
4180 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4182 // AFAIK, parenthesis suffixes are never on the first operand
4184 while (getLexer().is(AsmToken::Comma)) {
4185 Parser.Lex(); // Eat the comma.
4186 // Parse and remember the operand.
4187 if (parseOperand(Operands, Name)) {
4188 SMLoc Loc = getLexer().getLoc();
4189 Parser.eatToEndOfStatement();
4190 return Error(Loc, "unexpected token in argument list");
4192 // Parse bracket and parenthesis suffixes before we iterate
4193 if (getLexer().is(AsmToken::LBrac)) {
4194 if (parseBracketSuffix(Name, Operands))
4196 } else if (getLexer().is(AsmToken::LParen) &&
4197 parseParenSuffix(Name, Operands))
4201 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4202 SMLoc Loc = getLexer().getLoc();
4203 Parser.eatToEndOfStatement();
4204 return Error(Loc, "unexpected token in argument list");
4206 Parser.Lex(); // Consume the EndOfStatement.
4210 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4211 MCAsmParser &Parser = getParser();
4212 SMLoc Loc = getLexer().getLoc();
4213 Parser.eatToEndOfStatement();
4214 return Error(Loc, ErrorMsg);
4217 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4218 return Error(Loc, ErrorMsg);
4221 bool MipsAsmParser::parseSetNoAtDirective() {
4222 MCAsmParser &Parser = getParser();
4223 // Line should look like: ".set noat".
4225 // Set the $at register to $0.
4226 AssemblerOptions.back()->setATRegIndex(0);
4228 Parser.Lex(); // Eat "noat".
4230 // If this is not the end of the statement, report an error.
4231 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4232 reportParseError("unexpected token, expected end of statement");
4236 getTargetStreamer().emitDirectiveSetNoAt();
4237 Parser.Lex(); // Consume the EndOfStatement.
4241 bool MipsAsmParser::parseSetAtDirective() {
4242 // Line can be: ".set at", which sets $at to $1
4243 // or ".set at=$reg", which sets $at to $reg.
4244 MCAsmParser &Parser = getParser();
4245 Parser.Lex(); // Eat "at".
4247 if (getLexer().is(AsmToken::EndOfStatement)) {
4248 // No register was specified, so we set $at to $1.
4249 AssemblerOptions.back()->setATRegIndex(1);
4251 getTargetStreamer().emitDirectiveSetAt();
4252 Parser.Lex(); // Consume the EndOfStatement.
4256 if (getLexer().isNot(AsmToken::Equal)) {
4257 reportParseError("unexpected token, expected equals sign");
4260 Parser.Lex(); // Eat "=".
4262 if (getLexer().isNot(AsmToken::Dollar)) {
4263 if (getLexer().is(AsmToken::EndOfStatement)) {
4264 reportParseError("no register specified");
4267 reportParseError("unexpected token, expected dollar sign '$'");
4271 Parser.Lex(); // Eat "$".
4273 // Find out what "reg" is.
4275 const AsmToken &Reg = Parser.getTok();
4276 if (Reg.is(AsmToken::Identifier)) {
4277 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4278 } else if (Reg.is(AsmToken::Integer)) {
4279 AtRegNo = Reg.getIntVal();
4281 reportParseError("unexpected token, expected identifier or integer");
4285 // Check if $reg is a valid register. If it is, set $at to $reg.
4286 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4287 reportParseError("invalid register");
4290 Parser.Lex(); // Eat "reg".
4292 // If this is not the end of the statement, report an error.
4293 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4294 reportParseError("unexpected token, expected end of statement");
4298 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4300 Parser.Lex(); // Consume the EndOfStatement.
4304 bool MipsAsmParser::parseSetReorderDirective() {
4305 MCAsmParser &Parser = getParser();
4307 // If this is not the end of the statement, report an error.
4308 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4309 reportParseError("unexpected token, expected end of statement");
4312 AssemblerOptions.back()->setReorder();
4313 getTargetStreamer().emitDirectiveSetReorder();
4314 Parser.Lex(); // Consume the EndOfStatement.
4318 bool MipsAsmParser::parseSetNoReorderDirective() {
4319 MCAsmParser &Parser = getParser();
4321 // If this is not the end of the statement, report an error.
4322 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4323 reportParseError("unexpected token, expected end of statement");
4326 AssemblerOptions.back()->setNoReorder();
4327 getTargetStreamer().emitDirectiveSetNoReorder();
4328 Parser.Lex(); // Consume the EndOfStatement.
4332 bool MipsAsmParser::parseSetMacroDirective() {
4333 MCAsmParser &Parser = getParser();
4335 // If this is not the end of the statement, report an error.
4336 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4337 reportParseError("unexpected token, expected end of statement");
4340 AssemblerOptions.back()->setMacro();
4341 getTargetStreamer().emitDirectiveSetMacro();
4342 Parser.Lex(); // Consume the EndOfStatement.
4346 bool MipsAsmParser::parseSetNoMacroDirective() {
4347 MCAsmParser &Parser = getParser();
4349 // If this is not the end of the statement, report an error.
4350 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4351 reportParseError("unexpected token, expected end of statement");
4354 if (AssemblerOptions.back()->isReorder()) {
4355 reportParseError("`noreorder' must be set before `nomacro'");
4358 AssemblerOptions.back()->setNoMacro();
4359 getTargetStreamer().emitDirectiveSetNoMacro();
4360 Parser.Lex(); // Consume the EndOfStatement.
4364 bool MipsAsmParser::parseSetMsaDirective() {
4365 MCAsmParser &Parser = getParser();
4368 // If this is not the end of the statement, report an error.
4369 if (getLexer().isNot(AsmToken::EndOfStatement))
4370 return reportParseError("unexpected token, expected end of statement");
4372 setFeatureBits(Mips::FeatureMSA, "msa");
4373 getTargetStreamer().emitDirectiveSetMsa();
4377 bool MipsAsmParser::parseSetNoMsaDirective() {
4378 MCAsmParser &Parser = getParser();
4381 // If this is not the end of the statement, report an error.
4382 if (getLexer().isNot(AsmToken::EndOfStatement))
4383 return reportParseError("unexpected token, expected end of statement");
4385 clearFeatureBits(Mips::FeatureMSA, "msa");
4386 getTargetStreamer().emitDirectiveSetNoMsa();
4390 bool MipsAsmParser::parseSetNoDspDirective() {
4391 MCAsmParser &Parser = getParser();
4392 Parser.Lex(); // Eat "nodsp".
4394 // If this is not the end of the statement, report an error.
4395 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4396 reportParseError("unexpected token, expected end of statement");
4400 clearFeatureBits(Mips::FeatureDSP, "dsp");
4401 getTargetStreamer().emitDirectiveSetNoDsp();
4405 bool MipsAsmParser::parseSetMips16Directive() {
4406 MCAsmParser &Parser = getParser();
4407 Parser.Lex(); // Eat "mips16".
4409 // If this is not the end of the statement, report an error.
4410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4411 reportParseError("unexpected token, expected end of statement");
4415 setFeatureBits(Mips::FeatureMips16, "mips16");
4416 getTargetStreamer().emitDirectiveSetMips16();
4417 Parser.Lex(); // Consume the EndOfStatement.
4421 bool MipsAsmParser::parseSetNoMips16Directive() {
4422 MCAsmParser &Parser = getParser();
4423 Parser.Lex(); // Eat "nomips16".
4425 // If this is not the end of the statement, report an error.
4426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4427 reportParseError("unexpected token, expected end of statement");
4431 clearFeatureBits(Mips::FeatureMips16, "mips16");
4432 getTargetStreamer().emitDirectiveSetNoMips16();
4433 Parser.Lex(); // Consume the EndOfStatement.
4437 bool MipsAsmParser::parseSetFpDirective() {
4438 MCAsmParser &Parser = getParser();
4439 MipsABIFlagsSection::FpABIKind FpAbiVal;
4440 // Line can be: .set fp=32
4443 Parser.Lex(); // Eat fp token
4444 AsmToken Tok = Parser.getTok();
4445 if (Tok.isNot(AsmToken::Equal)) {
4446 reportParseError("unexpected token, expected equals sign '='");
4449 Parser.Lex(); // Eat '=' token.
4450 Tok = Parser.getTok();
4452 if (!parseFpABIValue(FpAbiVal, ".set"))
4455 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4456 reportParseError("unexpected token, expected end of statement");
4459 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4460 Parser.Lex(); // Consume the EndOfStatement.
4464 bool MipsAsmParser::parseSetOddSPRegDirective() {
4465 MCAsmParser &Parser = getParser();
4467 Parser.Lex(); // Eat "oddspreg".
4468 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4469 reportParseError("unexpected token, expected end of statement");
4473 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4474 getTargetStreamer().emitDirectiveSetOddSPReg();
4478 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4479 MCAsmParser &Parser = getParser();
4481 Parser.Lex(); // Eat "nooddspreg".
4482 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4483 reportParseError("unexpected token, expected end of statement");
4487 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4488 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4492 bool MipsAsmParser::parseSetPopDirective() {
4493 MCAsmParser &Parser = getParser();
4494 SMLoc Loc = getLexer().getLoc();
4497 if (getLexer().isNot(AsmToken::EndOfStatement))
4498 return reportParseError("unexpected token, expected end of statement");
4500 // Always keep an element on the options "stack" to prevent the user
4501 // from changing the initial options. This is how we remember them.
4502 if (AssemblerOptions.size() == 2)
4503 return reportParseError(Loc, ".set pop with no .set push");
4505 AssemblerOptions.pop_back();
4506 setAvailableFeatures(
4507 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4508 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4510 getTargetStreamer().emitDirectiveSetPop();
4514 bool MipsAsmParser::parseSetPushDirective() {
4515 MCAsmParser &Parser = getParser();
4517 if (getLexer().isNot(AsmToken::EndOfStatement))
4518 return reportParseError("unexpected token, expected end of statement");
4520 // Create a copy of the current assembler options environment and push it.
4521 AssemblerOptions.push_back(
4522 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4524 getTargetStreamer().emitDirectiveSetPush();
4528 bool MipsAsmParser::parseSetSoftFloatDirective() {
4529 MCAsmParser &Parser = getParser();
4531 if (getLexer().isNot(AsmToken::EndOfStatement))
4532 return reportParseError("unexpected token, expected end of statement");
4534 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4535 getTargetStreamer().emitDirectiveSetSoftFloat();
4539 bool MipsAsmParser::parseSetHardFloatDirective() {
4540 MCAsmParser &Parser = getParser();
4542 if (getLexer().isNot(AsmToken::EndOfStatement))
4543 return reportParseError("unexpected token, expected end of statement");
4545 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4546 getTargetStreamer().emitDirectiveSetHardFloat();
4550 bool MipsAsmParser::parseSetAssignment() {
4552 const MCExpr *Value;
4553 MCAsmParser &Parser = getParser();
4555 if (Parser.parseIdentifier(Name))
4556 reportParseError("expected identifier after .set");
4558 if (getLexer().isNot(AsmToken::Comma))
4559 return reportParseError("unexpected token, expected comma");
4562 if (Parser.parseExpression(Value))
4563 return reportParseError("expected valid expression after comma");
4565 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4566 Sym->setVariableValue(Value);
4571 bool MipsAsmParser::parseSetMips0Directive() {
4572 MCAsmParser &Parser = getParser();
4574 if (getLexer().isNot(AsmToken::EndOfStatement))
4575 return reportParseError("unexpected token, expected end of statement");
4577 // Reset assembler options to their initial values.
4578 setAvailableFeatures(
4579 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4580 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4581 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4583 getTargetStreamer().emitDirectiveSetMips0();
4587 bool MipsAsmParser::parseSetArchDirective() {
4588 MCAsmParser &Parser = getParser();
4590 if (getLexer().isNot(AsmToken::Equal))
4591 return reportParseError("unexpected token, expected equals sign");
4595 if (Parser.parseIdentifier(Arch))
4596 return reportParseError("expected arch identifier");
4598 StringRef ArchFeatureName =
4599 StringSwitch<StringRef>(Arch)
4600 .Case("mips1", "mips1")
4601 .Case("mips2", "mips2")
4602 .Case("mips3", "mips3")
4603 .Case("mips4", "mips4")
4604 .Case("mips5", "mips5")
4605 .Case("mips32", "mips32")
4606 .Case("mips32r2", "mips32r2")
4607 .Case("mips32r3", "mips32r3")
4608 .Case("mips32r5", "mips32r5")
4609 .Case("mips32r6", "mips32r6")
4610 .Case("mips64", "mips64")
4611 .Case("mips64r2", "mips64r2")
4612 .Case("mips64r3", "mips64r3")
4613 .Case("mips64r5", "mips64r5")
4614 .Case("mips64r6", "mips64r6")
4615 .Case("cnmips", "cnmips")
4616 .Case("r4000", "mips3") // This is an implementation of Mips3.
4619 if (ArchFeatureName.empty())
4620 return reportParseError("unsupported architecture");
4622 selectArch(ArchFeatureName);
4623 getTargetStreamer().emitDirectiveSetArch(Arch);
4627 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4628 MCAsmParser &Parser = getParser();
4630 if (getLexer().isNot(AsmToken::EndOfStatement))
4631 return reportParseError("unexpected token, expected end of statement");
4635 llvm_unreachable("Unimplemented feature");
4636 case Mips::FeatureDSP:
4637 setFeatureBits(Mips::FeatureDSP, "dsp");
4638 getTargetStreamer().emitDirectiveSetDsp();
4640 case Mips::FeatureMicroMips:
4641 getTargetStreamer().emitDirectiveSetMicroMips();
4643 case Mips::FeatureMips1:
4644 selectArch("mips1");
4645 getTargetStreamer().emitDirectiveSetMips1();
4647 case Mips::FeatureMips2:
4648 selectArch("mips2");
4649 getTargetStreamer().emitDirectiveSetMips2();
4651 case Mips::FeatureMips3:
4652 selectArch("mips3");
4653 getTargetStreamer().emitDirectiveSetMips3();
4655 case Mips::FeatureMips4:
4656 selectArch("mips4");
4657 getTargetStreamer().emitDirectiveSetMips4();
4659 case Mips::FeatureMips5:
4660 selectArch("mips5");
4661 getTargetStreamer().emitDirectiveSetMips5();
4663 case Mips::FeatureMips32:
4664 selectArch("mips32");
4665 getTargetStreamer().emitDirectiveSetMips32();
4667 case Mips::FeatureMips32r2:
4668 selectArch("mips32r2");
4669 getTargetStreamer().emitDirectiveSetMips32R2();
4671 case Mips::FeatureMips32r3:
4672 selectArch("mips32r3");
4673 getTargetStreamer().emitDirectiveSetMips32R3();
4675 case Mips::FeatureMips32r5:
4676 selectArch("mips32r5");
4677 getTargetStreamer().emitDirectiveSetMips32R5();
4679 case Mips::FeatureMips32r6:
4680 selectArch("mips32r6");
4681 getTargetStreamer().emitDirectiveSetMips32R6();
4683 case Mips::FeatureMips64:
4684 selectArch("mips64");
4685 getTargetStreamer().emitDirectiveSetMips64();
4687 case Mips::FeatureMips64r2:
4688 selectArch("mips64r2");
4689 getTargetStreamer().emitDirectiveSetMips64R2();
4691 case Mips::FeatureMips64r3:
4692 selectArch("mips64r3");
4693 getTargetStreamer().emitDirectiveSetMips64R3();
4695 case Mips::FeatureMips64r5:
4696 selectArch("mips64r5");
4697 getTargetStreamer().emitDirectiveSetMips64R5();
4699 case Mips::FeatureMips64r6:
4700 selectArch("mips64r6");
4701 getTargetStreamer().emitDirectiveSetMips64R6();
4707 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4708 MCAsmParser &Parser = getParser();
4709 if (getLexer().isNot(AsmToken::Comma)) {
4710 SMLoc Loc = getLexer().getLoc();
4711 Parser.eatToEndOfStatement();
4712 return Error(Loc, ErrorStr);
4715 Parser.Lex(); // Eat the comma.
4719 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4720 if (AssemblerOptions.back()->isReorder())
4721 Warning(Loc, ".cpload should be inside a noreorder section");
4723 if (inMips16Mode()) {
4724 reportParseError(".cpload is not supported in Mips16 mode");
4728 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4729 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4730 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4731 reportParseError("expected register containing function address");
4735 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4736 if (!RegOpnd.isGPRAsmReg()) {
4737 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4741 // If this is not the end of the statement, report an error.
4742 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4743 reportParseError("unexpected token, expected end of statement");
4747 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4751 bool MipsAsmParser::parseDirectiveCPSetup() {
4752 MCAsmParser &Parser = getParser();
4755 bool SaveIsReg = true;
4757 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4758 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4759 if (ResTy == MatchOperand_NoMatch) {
4760 reportParseError("expected register containing function address");
4761 Parser.eatToEndOfStatement();
4765 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4766 if (!FuncRegOpnd.isGPRAsmReg()) {
4767 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4768 Parser.eatToEndOfStatement();
4772 FuncReg = FuncRegOpnd.getGPR32Reg();
4775 if (!eatComma("unexpected token, expected comma"))
4778 ResTy = parseAnyRegister(TmpReg);
4779 if (ResTy == MatchOperand_NoMatch) {
4780 const AsmToken &Tok = Parser.getTok();
4781 if (Tok.is(AsmToken::Integer)) {
4782 Save = Tok.getIntVal();
4786 reportParseError("expected save register or stack offset");
4787 Parser.eatToEndOfStatement();
4791 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4792 if (!SaveOpnd.isGPRAsmReg()) {
4793 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4794 Parser.eatToEndOfStatement();
4797 Save = SaveOpnd.getGPR32Reg();
4800 if (!eatComma("unexpected token, expected comma"))
4804 if (Parser.parseExpression(Expr)) {
4805 reportParseError("expected expression");
4809 if (Expr->getKind() != MCExpr::SymbolRef) {
4810 reportParseError("expected symbol");
4813 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4815 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4820 bool MipsAsmParser::parseDirectiveNaN() {
4821 MCAsmParser &Parser = getParser();
4822 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4823 const AsmToken &Tok = Parser.getTok();
4825 if (Tok.getString() == "2008") {
4827 getTargetStreamer().emitDirectiveNaN2008();
4829 } else if (Tok.getString() == "legacy") {
4831 getTargetStreamer().emitDirectiveNaNLegacy();
4835 // If we don't recognize the option passed to the .nan
4836 // directive (e.g. no option or unknown option), emit an error.
4837 reportParseError("invalid option in .nan directive");
4841 bool MipsAsmParser::parseDirectiveSet() {
4842 MCAsmParser &Parser = getParser();
4843 // Get the next token.
4844 const AsmToken &Tok = Parser.getTok();
4846 if (Tok.getString() == "noat") {
4847 return parseSetNoAtDirective();
4848 } else if (Tok.getString() == "at") {
4849 return parseSetAtDirective();
4850 } else if (Tok.getString() == "arch") {
4851 return parseSetArchDirective();
4852 } else if (Tok.getString() == "fp") {
4853 return parseSetFpDirective();
4854 } else if (Tok.getString() == "oddspreg") {
4855 return parseSetOddSPRegDirective();
4856 } else if (Tok.getString() == "nooddspreg") {
4857 return parseSetNoOddSPRegDirective();
4858 } else if (Tok.getString() == "pop") {
4859 return parseSetPopDirective();
4860 } else if (Tok.getString() == "push") {
4861 return parseSetPushDirective();
4862 } else if (Tok.getString() == "reorder") {
4863 return parseSetReorderDirective();
4864 } else if (Tok.getString() == "noreorder") {
4865 return parseSetNoReorderDirective();
4866 } else if (Tok.getString() == "macro") {
4867 return parseSetMacroDirective();
4868 } else if (Tok.getString() == "nomacro") {
4869 return parseSetNoMacroDirective();
4870 } else if (Tok.getString() == "mips16") {
4871 return parseSetMips16Directive();
4872 } else if (Tok.getString() == "nomips16") {
4873 return parseSetNoMips16Directive();
4874 } else if (Tok.getString() == "nomicromips") {
4875 getTargetStreamer().emitDirectiveSetNoMicroMips();
4876 Parser.eatToEndOfStatement();
4878 } else if (Tok.getString() == "micromips") {
4879 return parseSetFeature(Mips::FeatureMicroMips);
4880 } else if (Tok.getString() == "mips0") {
4881 return parseSetMips0Directive();
4882 } else if (Tok.getString() == "mips1") {
4883 return parseSetFeature(Mips::FeatureMips1);
4884 } else if (Tok.getString() == "mips2") {
4885 return parseSetFeature(Mips::FeatureMips2);
4886 } else if (Tok.getString() == "mips3") {
4887 return parseSetFeature(Mips::FeatureMips3);
4888 } else if (Tok.getString() == "mips4") {
4889 return parseSetFeature(Mips::FeatureMips4);
4890 } else if (Tok.getString() == "mips5") {
4891 return parseSetFeature(Mips::FeatureMips5);
4892 } else if (Tok.getString() == "mips32") {
4893 return parseSetFeature(Mips::FeatureMips32);
4894 } else if (Tok.getString() == "mips32r2") {
4895 return parseSetFeature(Mips::FeatureMips32r2);
4896 } else if (Tok.getString() == "mips32r3") {
4897 return parseSetFeature(Mips::FeatureMips32r3);
4898 } else if (Tok.getString() == "mips32r5") {
4899 return parseSetFeature(Mips::FeatureMips32r5);
4900 } else if (Tok.getString() == "mips32r6") {
4901 return parseSetFeature(Mips::FeatureMips32r6);
4902 } else if (Tok.getString() == "mips64") {
4903 return parseSetFeature(Mips::FeatureMips64);
4904 } else if (Tok.getString() == "mips64r2") {
4905 return parseSetFeature(Mips::FeatureMips64r2);
4906 } else if (Tok.getString() == "mips64r3") {
4907 return parseSetFeature(Mips::FeatureMips64r3);
4908 } else if (Tok.getString() == "mips64r5") {
4909 return parseSetFeature(Mips::FeatureMips64r5);
4910 } else if (Tok.getString() == "mips64r6") {
4911 return parseSetFeature(Mips::FeatureMips64r6);
4912 } else if (Tok.getString() == "dsp") {
4913 return parseSetFeature(Mips::FeatureDSP);
4914 } else if (Tok.getString() == "nodsp") {
4915 return parseSetNoDspDirective();
4916 } else if (Tok.getString() == "msa") {
4917 return parseSetMsaDirective();
4918 } else if (Tok.getString() == "nomsa") {
4919 return parseSetNoMsaDirective();
4920 } else if (Tok.getString() == "softfloat") {
4921 return parseSetSoftFloatDirective();
4922 } else if (Tok.getString() == "hardfloat") {
4923 return parseSetHardFloatDirective();
4925 // It is just an identifier, look for an assignment.
4926 parseSetAssignment();
4933 /// parseDataDirective
4934 /// ::= .word [ expression (, expression)* ]
4935 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4936 MCAsmParser &Parser = getParser();
4937 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4939 const MCExpr *Value;
4940 if (getParser().parseExpression(Value))
4943 getParser().getStreamer().EmitValue(Value, Size);
4945 if (getLexer().is(AsmToken::EndOfStatement))
4948 if (getLexer().isNot(AsmToken::Comma))
4949 return Error(L, "unexpected token, expected comma");
4958 /// parseDirectiveGpWord
4959 /// ::= .gpword local_sym
4960 bool MipsAsmParser::parseDirectiveGpWord() {
4961 MCAsmParser &Parser = getParser();
4962 const MCExpr *Value;
4963 // EmitGPRel32Value requires an expression, so we are using base class
4964 // method to evaluate the expression.
4965 if (getParser().parseExpression(Value))
4967 getParser().getStreamer().EmitGPRel32Value(Value);
4969 if (getLexer().isNot(AsmToken::EndOfStatement))
4970 return Error(getLexer().getLoc(),
4971 "unexpected token, expected end of statement");
4972 Parser.Lex(); // Eat EndOfStatement token.
4976 /// parseDirectiveGpDWord
4977 /// ::= .gpdword local_sym
4978 bool MipsAsmParser::parseDirectiveGpDWord() {
4979 MCAsmParser &Parser = getParser();
4980 const MCExpr *Value;
4981 // EmitGPRel64Value requires an expression, so we are using base class
4982 // method to evaluate the expression.
4983 if (getParser().parseExpression(Value))
4985 getParser().getStreamer().EmitGPRel64Value(Value);
4987 if (getLexer().isNot(AsmToken::EndOfStatement))
4988 return Error(getLexer().getLoc(),
4989 "unexpected token, expected end of statement");
4990 Parser.Lex(); // Eat EndOfStatement token.
4994 bool MipsAsmParser::parseDirectiveOption() {
4995 MCAsmParser &Parser = getParser();
4996 // Get the option token.
4997 AsmToken Tok = Parser.getTok();
4998 // At the moment only identifiers are supported.
4999 if (Tok.isNot(AsmToken::Identifier)) {
5000 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5001 Parser.eatToEndOfStatement();
5005 StringRef Option = Tok.getIdentifier();
5007 if (Option == "pic0") {
5008 // MipsAsmParser needs to know if the current PIC mode changes.
5009 IsPicEnabled = false;
5011 getTargetStreamer().emitDirectiveOptionPic0();
5013 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5014 Error(Parser.getTok().getLoc(),
5015 "unexpected token, expected end of statement");
5016 Parser.eatToEndOfStatement();
5021 if (Option == "pic2") {
5022 // MipsAsmParser needs to know if the current PIC mode changes.
5023 IsPicEnabled = true;
5025 getTargetStreamer().emitDirectiveOptionPic2();
5027 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5028 Error(Parser.getTok().getLoc(),
5029 "unexpected token, expected end of statement");
5030 Parser.eatToEndOfStatement();
5036 Warning(Parser.getTok().getLoc(),
5037 "unknown option, expected 'pic0' or 'pic2'");
5038 Parser.eatToEndOfStatement();
5042 /// parseInsnDirective
5044 bool MipsAsmParser::parseInsnDirective() {
5045 // If this is not the end of the statement, report an error.
5046 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5047 reportParseError("unexpected token, expected end of statement");
5051 // The actual label marking happens in
5052 // MipsELFStreamer::createPendingLabelRelocs().
5053 getTargetStreamer().emitDirectiveInsn();
5055 getParser().Lex(); // Eat EndOfStatement token.
5059 /// parseDirectiveModule
5060 /// ::= .module oddspreg
5061 /// ::= .module nooddspreg
5062 /// ::= .module fp=value
5063 /// ::= .module softfloat
5064 /// ::= .module hardfloat
5065 bool MipsAsmParser::parseDirectiveModule() {
5066 MCAsmParser &Parser = getParser();
5067 MCAsmLexer &Lexer = getLexer();
5068 SMLoc L = Lexer.getLoc();
5070 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5071 // TODO : get a better message.
5072 reportParseError(".module directive must appear before any code");
5077 if (Parser.parseIdentifier(Option)) {
5078 reportParseError("expected .module option identifier");
5082 if (Option == "oddspreg") {
5083 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5085 // Synchronize the abiflags information with the FeatureBits information we
5087 getTargetStreamer().updateABIInfo(*this);
5089 // If printing assembly, use the recently updated abiflags information.
5090 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5091 // emitted at the end).
5092 getTargetStreamer().emitDirectiveModuleOddSPReg();
5094 // If this is not the end of the statement, report an error.
5095 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5096 reportParseError("unexpected token, expected end of statement");
5100 return false; // parseDirectiveModule has finished successfully.
5101 } else if (Option == "nooddspreg") {
5103 Error(L, "'.module nooddspreg' requires the O32 ABI");
5107 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5109 // Synchronize the abiflags information with the FeatureBits information we
5111 getTargetStreamer().updateABIInfo(*this);
5113 // If printing assembly, use the recently updated abiflags information.
5114 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5115 // emitted at the end).
5116 getTargetStreamer().emitDirectiveModuleOddSPReg();
5118 // If this is not the end of the statement, report an error.
5119 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5120 reportParseError("unexpected token, expected end of statement");
5124 return false; // parseDirectiveModule has finished successfully.
5125 } else if (Option == "fp") {
5126 return parseDirectiveModuleFP();
5127 } else if (Option == "softfloat") {
5128 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5130 // Synchronize the ABI Flags information with the FeatureBits information we
5132 getTargetStreamer().updateABIInfo(*this);
5134 // If printing assembly, use the recently updated ABI Flags information.
5135 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5137 getTargetStreamer().emitDirectiveModuleSoftFloat();
5139 // If this is not the end of the statement, report an error.
5140 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5141 reportParseError("unexpected token, expected end of statement");
5145 return false; // parseDirectiveModule has finished successfully.
5146 } else if (Option == "hardfloat") {
5147 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5149 // Synchronize the ABI Flags information with the FeatureBits information we
5151 getTargetStreamer().updateABIInfo(*this);
5153 // If printing assembly, use the recently updated ABI Flags information.
5154 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5156 getTargetStreamer().emitDirectiveModuleHardFloat();
5158 // If this is not the end of the statement, report an error.
5159 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5160 reportParseError("unexpected token, expected end of statement");
5164 return false; // parseDirectiveModule has finished successfully.
5166 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5170 /// parseDirectiveModuleFP
5174 bool MipsAsmParser::parseDirectiveModuleFP() {
5175 MCAsmParser &Parser = getParser();
5176 MCAsmLexer &Lexer = getLexer();
5178 if (Lexer.isNot(AsmToken::Equal)) {
5179 reportParseError("unexpected token, expected equals sign '='");
5182 Parser.Lex(); // Eat '=' token.
5184 MipsABIFlagsSection::FpABIKind FpABI;
5185 if (!parseFpABIValue(FpABI, ".module"))
5188 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5189 reportParseError("unexpected token, expected end of statement");
5193 // Synchronize the abiflags information with the FeatureBits information we
5195 getTargetStreamer().updateABIInfo(*this);
5197 // If printing assembly, use the recently updated abiflags information.
5198 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5199 // emitted at the end).
5200 getTargetStreamer().emitDirectiveModuleFP();
5202 Parser.Lex(); // Consume the EndOfStatement.
5206 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5207 StringRef Directive) {
5208 MCAsmParser &Parser = getParser();
5209 MCAsmLexer &Lexer = getLexer();
5210 bool ModuleLevelOptions = Directive == ".module";
5212 if (Lexer.is(AsmToken::Identifier)) {
5213 StringRef Value = Parser.getTok().getString();
5216 if (Value != "xx") {
5217 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5222 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5226 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5227 if (ModuleLevelOptions) {
5228 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5229 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5231 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5232 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5237 if (Lexer.is(AsmToken::Integer)) {
5238 unsigned Value = Parser.getTok().getIntVal();
5241 if (Value != 32 && Value != 64) {
5242 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5248 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5252 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5253 if (ModuleLevelOptions) {
5254 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5255 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5257 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5258 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5261 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5262 if (ModuleLevelOptions) {
5263 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5264 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5266 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5267 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5277 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5278 MCAsmParser &Parser = getParser();
5279 StringRef IDVal = DirectiveID.getString();
5281 if (IDVal == ".cpload")
5282 return parseDirectiveCpLoad(DirectiveID.getLoc());
5283 if (IDVal == ".dword") {
5284 parseDataDirective(8, DirectiveID.getLoc());
5287 if (IDVal == ".ent") {
5288 StringRef SymbolName;
5290 if (Parser.parseIdentifier(SymbolName)) {
5291 reportParseError("expected identifier after .ent");
5295 // There's an undocumented extension that allows an integer to
5296 // follow the name of the procedure which AFAICS is ignored by GAS.
5297 // Example: .ent foo,2
5298 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5299 if (getLexer().isNot(AsmToken::Comma)) {
5300 // Even though we accept this undocumented extension for compatibility
5301 // reasons, the additional integer argument does not actually change
5302 // the behaviour of the '.ent' directive, so we would like to discourage
5303 // its use. We do this by not referring to the extended version in
5304 // error messages which are not directly related to its use.
5305 reportParseError("unexpected token, expected end of statement");
5308 Parser.Lex(); // Eat the comma.
5309 const MCExpr *DummyNumber;
5310 int64_t DummyNumberVal;
5311 // If the user was explicitly trying to use the extended version,
5312 // we still give helpful extension-related error messages.
5313 if (Parser.parseExpression(DummyNumber)) {
5314 reportParseError("expected number after comma");
5317 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5318 reportParseError("expected an absolute expression after comma");
5323 // If this is not the end of the statement, report an error.
5324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5325 reportParseError("unexpected token, expected end of statement");
5329 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5331 getTargetStreamer().emitDirectiveEnt(*Sym);
5336 if (IDVal == ".end") {
5337 StringRef SymbolName;
5339 if (Parser.parseIdentifier(SymbolName)) {
5340 reportParseError("expected identifier after .end");
5344 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5345 reportParseError("unexpected token, expected end of statement");
5349 if (CurrentFn == nullptr) {
5350 reportParseError(".end used without .ent");
5354 if ((SymbolName != CurrentFn->getName())) {
5355 reportParseError(".end symbol does not match .ent symbol");
5359 getTargetStreamer().emitDirectiveEnd(SymbolName);
5360 CurrentFn = nullptr;
5364 if (IDVal == ".frame") {
5365 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5366 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5367 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5368 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5369 reportParseError("expected stack register");
5373 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5374 if (!StackRegOpnd.isGPRAsmReg()) {
5375 reportParseError(StackRegOpnd.getStartLoc(),
5376 "expected general purpose register");
5379 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5381 if (Parser.getTok().is(AsmToken::Comma))
5384 reportParseError("unexpected token, expected comma");
5388 // Parse the frame size.
5389 const MCExpr *FrameSize;
5390 int64_t FrameSizeVal;
5392 if (Parser.parseExpression(FrameSize)) {
5393 reportParseError("expected frame size value");
5397 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5398 reportParseError("frame size not an absolute expression");
5402 if (Parser.getTok().is(AsmToken::Comma))
5405 reportParseError("unexpected token, expected comma");
5409 // Parse the return register.
5411 ResTy = parseAnyRegister(TmpReg);
5412 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5413 reportParseError("expected return register");
5417 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5418 if (!ReturnRegOpnd.isGPRAsmReg()) {
5419 reportParseError(ReturnRegOpnd.getStartLoc(),
5420 "expected general purpose register");
5424 // If this is not the end of the statement, report an error.
5425 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5426 reportParseError("unexpected token, expected end of statement");
5430 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5431 ReturnRegOpnd.getGPR32Reg());
5435 if (IDVal == ".set") {
5436 return parseDirectiveSet();
5439 if (IDVal == ".mask" || IDVal == ".fmask") {
5440 // .mask bitmask, frame_offset
5441 // bitmask: One bit for each register used.
5442 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5443 // first register is expected to be saved.
5445 // .mask 0x80000000, -4
5446 // .fmask 0x80000000, -4
5449 // Parse the bitmask
5450 const MCExpr *BitMask;
5453 if (Parser.parseExpression(BitMask)) {
5454 reportParseError("expected bitmask value");
5458 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5459 reportParseError("bitmask not an absolute expression");
5463 if (Parser.getTok().is(AsmToken::Comma))
5466 reportParseError("unexpected token, expected comma");
5470 // Parse the frame_offset
5471 const MCExpr *FrameOffset;
5472 int64_t FrameOffsetVal;
5474 if (Parser.parseExpression(FrameOffset)) {
5475 reportParseError("expected frame offset value");
5479 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5480 reportParseError("frame offset not an absolute expression");
5484 // If this is not the end of the statement, report an error.
5485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5486 reportParseError("unexpected token, expected end of statement");
5490 if (IDVal == ".mask")
5491 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5493 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5497 if (IDVal == ".nan")
5498 return parseDirectiveNaN();
5500 if (IDVal == ".gpword") {
5501 parseDirectiveGpWord();
5505 if (IDVal == ".gpdword") {
5506 parseDirectiveGpDWord();
5510 if (IDVal == ".word") {
5511 parseDataDirective(4, DirectiveID.getLoc());
5515 if (IDVal == ".option")
5516 return parseDirectiveOption();
5518 if (IDVal == ".abicalls") {
5519 getTargetStreamer().emitDirectiveAbiCalls();
5520 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5521 Error(Parser.getTok().getLoc(),
5522 "unexpected token, expected end of statement");
5524 Parser.eatToEndOfStatement();
5529 if (IDVal == ".cpsetup")
5530 return parseDirectiveCPSetup();
5532 if (IDVal == ".module")
5533 return parseDirectiveModule();
5535 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5536 return parseInternalDirectiveReallowModule();
5538 if (IDVal == ".insn")
5539 return parseInsnDirective();
5544 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5545 // If this is not the end of the statement, report an error.
5546 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5547 reportParseError("unexpected token, expected end of statement");
5551 getTargetStreamer().reallowModuleDirective();
5553 getParser().Lex(); // Eat EndOfStatement token.
5557 extern "C" void LLVMInitializeMipsAsmParser() {
5558 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5559 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5560 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5561 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5564 #define GET_REGISTER_MATCHER
5565 #define GET_MATCHER_IMPLEMENTATION
5566 #include "MipsGenAsmMatcher.inc"