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/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
25 #include "llvm/MC/MCSectionELF.h"
26 #include "llvm/MC/MCStreamer.h"
27 #include "llvm/MC/MCSubtargetInfo.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/ELF.h"
31 #include "llvm/Support/MathExtras.h"
32 #include "llvm/Support/SourceMgr.h"
33 #include "llvm/Support/TargetRegistry.h"
34 #include "llvm/Support/raw_ostream.h"
39 #define DEBUG_TYPE "mips-asm-parser"
46 class MipsAssemblerOptions {
48 MipsAssemblerOptions(const FeatureBitset &Features_) :
49 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
51 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
52 ATReg = Opts->getATRegIndex();
53 Reorder = Opts->isReorder();
54 Macro = Opts->isMacro();
55 Features = Opts->getFeatures();
58 unsigned getATRegIndex() const { return ATReg; }
59 bool setATRegIndex(unsigned Reg) {
67 bool isReorder() const { return Reorder; }
68 void setReorder() { Reorder = true; }
69 void setNoReorder() { Reorder = false; }
71 bool isMacro() const { return Macro; }
72 void setMacro() { Macro = true; }
73 void setNoMacro() { Macro = false; }
75 const FeatureBitset &getFeatures() const { return Features; }
76 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
78 // Set of features that are either architecture features or referenced
79 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
80 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
81 // The reason we need this mask is explained in the selectArch function.
82 // FIXME: Ideally we would like TableGen to generate this information.
83 static const FeatureBitset AllArchRelatedMask;
89 FeatureBitset Features;
93 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
94 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
95 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
96 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
97 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
98 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
99 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
100 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
101 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
105 class MipsAsmParser : public MCTargetAsmParser {
106 MipsTargetStreamer &getTargetStreamer() {
107 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
108 return static_cast<MipsTargetStreamer &>(TS);
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'
121 unsigned CpSaveLocation;
122 /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123 bool CpSaveLocationIsRegister;
125 // Print a warning along with its fix-it message at the given range.
126 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
127 SMRange Range, bool ShowColors = true);
129 #define GET_ASSEMBLER_HEADER
130 #include "MipsGenAsmMatcher.inc"
132 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
134 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135 OperandVector &Operands, MCStreamer &Out,
137 bool MatchingInlineAsm) override;
139 /// Parse a register as used in CFI directives
140 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
142 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
144 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
146 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147 SMLoc NameLoc, OperandVector &Operands) override;
149 bool ParseDirective(AsmToken DirectiveID) override;
151 OperandMatchResultTy parseMemOperand(OperandVector &Operands);
153 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154 StringRef Identifier, SMLoc S);
155 OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
157 OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158 OperandMatchResultTy parseImm(OperandVector &Operands);
159 OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160 OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
162 OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
163 OperandMatchResultTy parseRegisterList(OperandVector &Operands);
165 bool searchSymbolAlias(OperandVector &Operands);
167 bool parseOperand(OperandVector &, StringRef Mnemonic);
169 enum MacroExpanderResultTy {
175 // Expands assembly pseudo instructions.
176 MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
178 const MCSubtargetInfo *STI);
180 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
181 const MCSubtargetInfo *STI);
183 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
184 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
185 MCStreamer &Out, const MCSubtargetInfo *STI);
187 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
188 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
189 MCStreamer &Out, const MCSubtargetInfo *STI);
191 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
192 MCStreamer &Out, const MCSubtargetInfo *STI);
194 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
195 const MCOperand &Offset, bool Is32BitAddress,
196 SMLoc IDLoc, MCStreamer &Out,
197 const MCSubtargetInfo *STI);
199 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
200 const MCSubtargetInfo *STI);
202 void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
203 const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
205 void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
206 const MCSubtargetInfo *STI, bool IsImmOpnd);
208 void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
209 const MCSubtargetInfo *STI, bool IsImmOpnd);
211 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
212 const MCSubtargetInfo *STI);
214 bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
215 const MCSubtargetInfo *STI);
217 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
218 const MCSubtargetInfo *STI);
220 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
221 const MCSubtargetInfo *STI);
223 bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
224 const MCSubtargetInfo *STI, const bool IsMips64,
227 bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
228 MCStreamer &Out, const MCSubtargetInfo *STI);
230 bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
231 const MCSubtargetInfo *STI);
233 bool expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
234 const MCSubtargetInfo *STI);
236 bool expandRotation(MCInst &Inst, SMLoc IDLoc,
237 MCStreamer &Out, const MCSubtargetInfo *STI);
238 bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
239 const MCSubtargetInfo *STI);
240 bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241 const MCSubtargetInfo *STI);
242 bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
243 const MCSubtargetInfo *STI);
245 bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246 const MCSubtargetInfo *STI);
248 bool reportParseError(Twine ErrorMsg);
249 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
251 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
252 bool parseRelocOperand(const MCExpr *&Res);
254 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
256 bool isEvaluated(const MCExpr *Expr);
257 bool parseSetMips0Directive();
258 bool parseSetArchDirective();
259 bool parseSetFeature(uint64_t Feature);
260 bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
261 bool parseDirectiveCpLoad(SMLoc Loc);
262 bool parseDirectiveCpRestore(SMLoc Loc);
263 bool parseDirectiveCPSetup();
264 bool parseDirectiveCPReturn();
265 bool parseDirectiveNaN();
266 bool parseDirectiveSet();
267 bool parseDirectiveOption();
268 bool parseInsnDirective();
269 bool parseSSectionDirective(StringRef Section, unsigned Type);
271 bool parseSetAtDirective();
272 bool parseSetNoAtDirective();
273 bool parseSetMacroDirective();
274 bool parseSetNoMacroDirective();
275 bool parseSetMsaDirective();
276 bool parseSetNoMsaDirective();
277 bool parseSetNoDspDirective();
278 bool parseSetReorderDirective();
279 bool parseSetNoReorderDirective();
280 bool parseSetMips16Directive();
281 bool parseSetNoMips16Directive();
282 bool parseSetFpDirective();
283 bool parseSetOddSPRegDirective();
284 bool parseSetNoOddSPRegDirective();
285 bool parseSetPopDirective();
286 bool parseSetPushDirective();
287 bool parseSetSoftFloatDirective();
288 bool parseSetHardFloatDirective();
290 bool parseSetAssignment();
292 bool parseDataDirective(unsigned Size, SMLoc L);
293 bool parseDirectiveGpWord();
294 bool parseDirectiveGpDWord();
295 bool parseDirectiveModule();
296 bool parseDirectiveModuleFP();
297 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
298 StringRef Directive);
300 bool parseInternalDirectiveReallowModule();
302 bool eatComma(StringRef ErrorStr);
304 int matchCPURegisterName(StringRef Symbol);
306 int matchHWRegsRegisterName(StringRef Symbol);
308 int matchFPURegisterName(StringRef Name);
310 int matchFCCRegisterName(StringRef Name);
312 int matchACRegisterName(StringRef Name);
314 int matchMSA128RegisterName(StringRef Name);
316 int matchMSA128CtrlRegisterName(StringRef Name);
318 unsigned getReg(int RC, int RegNo);
320 /// Returns the internal register number for the current AT. Also checks if
321 /// the current AT is unavailable (set to $0) and gives an error if it is.
322 /// This should be used in pseudo-instruction expansions which need AT.
323 unsigned getATReg(SMLoc Loc);
325 bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
326 const MCSubtargetInfo *STI);
328 // Helper function that checks if the value of a vector index is within the
329 // boundaries of accepted values for each RegisterKind
330 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
331 bool validateMSAIndex(int Val, int RegKind);
333 // Selects a new architecture by updating the FeatureBits with the necessary
334 // info including implied dependencies.
335 // Internally, it clears all the feature bits related to *any* architecture
336 // and selects the new one using the ToggleFeature functionality of the
337 // MCSubtargetInfo object that handles implied dependencies. The reason we
338 // clear all the arch related bits manually is because ToggleFeature only
339 // clears the features that imply the feature being cleared and not the
340 // features implied by the feature being cleared. This is easier to see
342 // --------------------------------------------------
343 // | Feature | Implies |
344 // | -------------------------------------------------|
345 // | FeatureMips1 | None |
346 // | FeatureMips2 | FeatureMips1 |
347 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
348 // | FeatureMips4 | FeatureMips3 |
350 // --------------------------------------------------
352 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
353 // FeatureMipsGP64 | FeatureMips1)
354 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
355 void selectArch(StringRef ArchFeature) {
356 MCSubtargetInfo &STI = copySTI();
357 FeatureBitset FeatureBits = STI.getFeatureBits();
358 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
359 STI.setFeatureBits(FeatureBits);
360 setAvailableFeatures(
361 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
362 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
365 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
366 if (!(getSTI().getFeatureBits()[Feature])) {
367 MCSubtargetInfo &STI = copySTI();
368 setAvailableFeatures(
369 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
370 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
374 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
375 if (getSTI().getFeatureBits()[Feature]) {
376 MCSubtargetInfo &STI = copySTI();
377 setAvailableFeatures(
378 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
379 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
383 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
384 setFeatureBits(Feature, FeatureString);
385 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
388 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
389 clearFeatureBits(Feature, FeatureString);
390 AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
394 enum MipsMatchResultTy {
395 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
396 Match_RequiresDifferentOperands,
397 Match_RequiresNoZeroRegister,
398 #define GET_OPERAND_DIAGNOSTIC_TYPES
399 #include "MipsGenAsmMatcher.inc"
400 #undef GET_OPERAND_DIAGNOSTIC_TYPES
403 MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
404 const MCInstrInfo &MII, const MCTargetOptions &Options)
405 : MCTargetAsmParser(Options, sti),
406 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
407 sti.getCPU(), Options)) {
408 MCAsmParserExtension::Initialize(parser);
410 parser.addAliasForDirective(".asciiz", ".asciz");
412 // Initialize the set of available features.
413 setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
415 // Remember the initial assembler options. The user can not modify these.
416 AssemblerOptions.push_back(
417 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
419 // Create an assembler options environment for the user to modify.
420 AssemblerOptions.push_back(
421 llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
423 getTargetStreamer().updateABIInfo(*this);
425 if (!isABI_O32() && !useOddSPReg() != 0)
426 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
430 IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
432 IsCpRestoreSet = false;
433 CpRestoreOffset = -1;
435 const Triple &TheTriple = sti.getTargetTriple();
436 if ((TheTriple.getArch() == Triple::mips) ||
437 (TheTriple.getArch() == Triple::mips64))
438 IsLittleEndian = false;
440 IsLittleEndian = true;
443 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
444 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
446 bool isGP64bit() const {
447 return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
449 bool isFP64bit() const {
450 return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
452 const MipsABIInfo &getABI() const { return ABI; }
453 bool isABI_N32() const { return ABI.IsN32(); }
454 bool isABI_N64() const { return ABI.IsN64(); }
455 bool isABI_O32() const { return ABI.IsO32(); }
456 bool isABI_FPXX() const {
457 return getSTI().getFeatureBits()[Mips::FeatureFPXX];
460 bool useOddSPReg() const {
461 return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
464 bool inMicroMipsMode() const {
465 return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
467 bool hasMips1() const {
468 return getSTI().getFeatureBits()[Mips::FeatureMips1];
470 bool hasMips2() const {
471 return getSTI().getFeatureBits()[Mips::FeatureMips2];
473 bool hasMips3() const {
474 return getSTI().getFeatureBits()[Mips::FeatureMips3];
476 bool hasMips4() const {
477 return getSTI().getFeatureBits()[Mips::FeatureMips4];
479 bool hasMips5() const {
480 return getSTI().getFeatureBits()[Mips::FeatureMips5];
482 bool hasMips32() const {
483 return getSTI().getFeatureBits()[Mips::FeatureMips32];
485 bool hasMips64() const {
486 return getSTI().getFeatureBits()[Mips::FeatureMips64];
488 bool hasMips32r2() const {
489 return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
491 bool hasMips64r2() const {
492 return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
494 bool hasMips32r3() const {
495 return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
497 bool hasMips64r3() const {
498 return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
500 bool hasMips32r5() const {
501 return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
503 bool hasMips64r5() const {
504 return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
506 bool hasMips32r6() const {
507 return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
509 bool hasMips64r6() const {
510 return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
513 bool hasDSP() const {
514 return getSTI().getFeatureBits()[Mips::FeatureDSP];
516 bool hasDSPR2() const {
517 return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
519 bool hasDSPR3() const {
520 return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
522 bool hasMSA() const {
523 return getSTI().getFeatureBits()[Mips::FeatureMSA];
525 bool hasCnMips() const {
526 return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
533 bool inMips16Mode() const {
534 return getSTI().getFeatureBits()[Mips::FeatureMips16];
537 bool useTraps() const {
538 return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
541 bool useSoftFloat() const {
542 return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
545 /// Warn if RegIndex is the same as the current AT.
546 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
548 void warnIfNoMacro(SMLoc Loc);
550 bool isLittle() const { return IsLittleEndian; }
556 /// MipsOperand - Instances of this class represent a parsed Mips machine
558 class MipsOperand : public MCParsedAsmOperand {
560 /// Broad categories of register classes
561 /// The exact class is finalized by the render method.
563 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
564 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
566 RegKind_FCC = 4, /// FCC
567 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
568 RegKind_MSACtrl = 16, /// MSA control registers
569 RegKind_COP2 = 32, /// COP2
570 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
572 RegKind_CCR = 128, /// CCR
573 RegKind_HWRegs = 256, /// HWRegs
574 RegKind_COP3 = 512, /// COP3
575 RegKind_COP0 = 1024, /// COP0
576 /// Potentially any (e.g. $1)
577 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
578 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
579 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
584 k_Immediate, /// An immediate (possibly involving symbol references)
585 k_Memory, /// Base + Offset Memory Address
586 k_RegisterIndex, /// A register index in one or more RegKind.
587 k_Token, /// A simple token
588 k_RegList, /// A physical register list
589 k_RegPair /// A pair of physical register
593 MipsOperand(KindTy K, MipsAsmParser &Parser)
594 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
597 /// For diagnostics, and checking the assembler temporary
598 MipsAsmParser &AsmParser;
606 unsigned Index; /// Index into the register class
607 RegKind Kind; /// Bitfield of the kinds it could possibly be
608 const MCRegisterInfo *RegInfo;
621 SmallVector<unsigned, 10> *List;
626 struct RegIdxOp RegIdx;
629 struct RegListOp RegList;
632 SMLoc StartLoc, EndLoc;
634 /// Internal constructor for register kinds
635 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
636 const MCRegisterInfo *RegInfo,
638 MipsAsmParser &Parser) {
639 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
640 Op->RegIdx.Index = Index;
641 Op->RegIdx.RegInfo = RegInfo;
642 Op->RegIdx.Kind = RegKind;
649 /// Coerce the register to GPR32 and return the real register for the current
651 unsigned getGPR32Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
653 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
654 unsigned ClassID = Mips::GPR32RegClassID;
655 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
658 /// Coerce the register to GPR32 and return the real register for the current
660 unsigned getGPRMM16Reg() const {
661 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
662 unsigned ClassID = Mips::GPR32RegClassID;
663 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
666 /// Coerce the register to GPR64 and return the real register for the current
668 unsigned getGPR64Reg() const {
669 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
670 unsigned ClassID = Mips::GPR64RegClassID;
671 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
675 /// Coerce the register to AFGR64 and return the real register for the current
677 unsigned getAFGR64Reg() const {
678 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
679 if (RegIdx.Index % 2 != 0)
680 AsmParser.Warning(StartLoc, "Float register should be even.");
681 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
682 .getRegister(RegIdx.Index / 2);
685 /// Coerce the register to FGR64 and return the real register for the current
687 unsigned getFGR64Reg() const {
688 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
689 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
690 .getRegister(RegIdx.Index);
693 /// Coerce the register to FGR32 and return the real register for the current
695 unsigned getFGR32Reg() const {
696 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
697 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
698 .getRegister(RegIdx.Index);
701 /// Coerce the register to FGRH32 and return the real register for the current
703 unsigned getFGRH32Reg() const {
704 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
705 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
706 .getRegister(RegIdx.Index);
709 /// Coerce the register to FCC and return the real register for the current
711 unsigned getFCCReg() const {
712 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
713 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
714 .getRegister(RegIdx.Index);
717 /// Coerce the register to MSA128 and return the real register for the current
719 unsigned getMSA128Reg() const {
720 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
721 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
723 unsigned ClassID = Mips::MSA128BRegClassID;
724 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
727 /// Coerce the register to MSACtrl and return the real register for the
729 unsigned getMSACtrlReg() const {
730 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
731 unsigned ClassID = Mips::MSACtrlRegClassID;
732 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
735 /// Coerce the register to COP0 and return the real register for the
737 unsigned getCOP0Reg() const {
738 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
739 unsigned ClassID = Mips::COP0RegClassID;
740 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
743 /// Coerce the register to COP2 and return the real register for the
745 unsigned getCOP2Reg() const {
746 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
747 unsigned ClassID = Mips::COP2RegClassID;
748 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
751 /// Coerce the register to COP3 and return the real register for the
753 unsigned getCOP3Reg() const {
754 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
755 unsigned ClassID = Mips::COP3RegClassID;
756 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
759 /// Coerce the register to ACC64DSP and return the real register for the
761 unsigned getACC64DSPReg() const {
762 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
763 unsigned ClassID = Mips::ACC64DSPRegClassID;
764 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
767 /// Coerce the register to HI32DSP and return the real register for the
769 unsigned getHI32DSPReg() const {
770 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
771 unsigned ClassID = Mips::HI32DSPRegClassID;
772 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
775 /// Coerce the register to LO32DSP and return the real register for the
777 unsigned getLO32DSPReg() const {
778 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
779 unsigned ClassID = Mips::LO32DSPRegClassID;
780 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
783 /// Coerce the register to CCR and return the real register for the
785 unsigned getCCRReg() const {
786 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
787 unsigned ClassID = Mips::CCRRegClassID;
788 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
791 /// Coerce the register to HWRegs and return the real register for the
793 unsigned getHWRegsReg() const {
794 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
795 unsigned ClassID = Mips::HWRegsRegClassID;
796 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
800 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
801 // Add as immediate when possible. Null MCExpr = 0.
803 Inst.addOperand(MCOperand::createImm(0));
804 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
805 Inst.addOperand(MCOperand::createImm(CE->getValue()));
807 Inst.addOperand(MCOperand::createExpr(Expr));
810 void addRegOperands(MCInst &Inst, unsigned N) const {
811 llvm_unreachable("Use a custom parser instead");
814 /// Render the operand to an MCInst as a GPR32
815 /// Asserts if the wrong number of operands are requested, or the operand
816 /// is not a k_RegisterIndex compatible with RegKind_GPR
817 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
822 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 1 && "Invalid number of operands!");
824 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
827 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 1 && "Invalid number of operands!");
829 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
832 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 1 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
837 /// Render the operand to an MCInst as a GPR64
838 /// Asserts if the wrong number of operands are requested, or the operand
839 /// is not a k_RegisterIndex compatible with RegKind_GPR
840 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
842 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
845 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 1 && "Invalid number of operands!");
847 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
850 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 1 && "Invalid number of operands!");
852 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
855 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 1 && "Invalid number of operands!");
857 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
858 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
859 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
860 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
864 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
865 assert(N == 1 && "Invalid number of operands!");
866 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
869 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
870 assert(N == 1 && "Invalid number of operands!");
871 Inst.addOperand(MCOperand::createReg(getFCCReg()));
874 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
875 assert(N == 1 && "Invalid number of operands!");
876 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
879 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
880 assert(N == 1 && "Invalid number of operands!");
881 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
884 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
885 assert(N == 1 && "Invalid number of operands!");
886 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
889 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
890 assert(N == 1 && "Invalid number of operands!");
891 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
894 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
895 assert(N == 1 && "Invalid number of operands!");
896 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
899 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
900 assert(N == 1 && "Invalid number of operands!");
901 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
904 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
905 assert(N == 1 && "Invalid number of operands!");
906 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
909 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
910 assert(N == 1 && "Invalid number of operands!");
911 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
914 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
915 assert(N == 1 && "Invalid number of operands!");
916 Inst.addOperand(MCOperand::createReg(getCCRReg()));
919 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
920 assert(N == 1 && "Invalid number of operands!");
921 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
924 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
925 void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
926 assert(N == 1 && "Invalid number of operands!");
927 uint64_t Imm = getConstantImm() - Offset;
928 Imm &= (1 << Bits) - 1;
931 Inst.addOperand(MCOperand::createImm(Imm));
934 template <unsigned Bits>
935 void addSImmOperands(MCInst &Inst, unsigned N) const {
936 if (isImm() && !isConstantImm()) {
937 addExpr(Inst, getImm());
940 addConstantSImmOperands<Bits, 0, 0>(Inst, N);
943 template <unsigned Bits>
944 void addUImmOperands(MCInst &Inst, unsigned N) const {
945 if (isImm() && !isConstantImm()) {
946 addExpr(Inst, getImm());
949 addConstantUImmOperands<Bits, 0, 0>(Inst, N);
952 template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
953 void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
954 assert(N == 1 && "Invalid number of operands!");
955 int64_t Imm = getConstantImm() - Offset;
956 Imm = SignExtend64<Bits>(Imm);
959 Inst.addOperand(MCOperand::createImm(Imm));
962 void addImmOperands(MCInst &Inst, unsigned N) const {
963 assert(N == 1 && "Invalid number of operands!");
964 const MCExpr *Expr = getImm();
968 void addMemOperands(MCInst &Inst, unsigned N) const {
969 assert(N == 2 && "Invalid number of operands!");
971 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
972 ? getMemBase()->getGPR64Reg()
973 : getMemBase()->getGPR32Reg()));
975 const MCExpr *Expr = getMemOff();
979 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
980 assert(N == 2 && "Invalid number of operands!");
982 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
984 const MCExpr *Expr = getMemOff();
988 void addRegListOperands(MCInst &Inst, unsigned N) const {
989 assert(N == 1 && "Invalid number of operands!");
991 for (auto RegNo : getRegList())
992 Inst.addOperand(MCOperand::createReg(RegNo));
995 void addRegPairOperands(MCInst &Inst, unsigned N) const {
996 assert(N == 2 && "Invalid number of operands!");
997 assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
998 unsigned RegNo = getRegPair();
999 AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1000 Inst.addOperand(MCOperand::createReg(
1001 RegIdx.RegInfo->getRegClass(
1002 AsmParser.getABI().AreGprs64bit()
1003 ? Mips::GPR64RegClassID
1004 : Mips::GPR32RegClassID).getRegister(RegNo++)));
1005 Inst.addOperand(MCOperand::createReg(
1006 RegIdx.RegInfo->getRegClass(
1007 AsmParser.getABI().AreGprs64bit()
1008 ? Mips::GPR64RegClassID
1009 : Mips::GPR32RegClassID).getRegister(RegNo)));
1012 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1013 assert(N == 2 && "Invalid number of operands!");
1014 for (auto RegNo : getRegList())
1015 Inst.addOperand(MCOperand::createReg(RegNo));
1018 bool isReg() const override {
1019 // As a special case until we sort out the definition of div/divu, accept
1020 // $0/$zero here so that MCK_ZERO works correctly.
1021 return isGPRAsmReg() && RegIdx.Index == 0;
1023 bool isRegIdx() const { return Kind == k_RegisterIndex; }
1024 bool isImm() const override { return Kind == k_Immediate; }
1025 bool isConstantImm() const {
1026 return isImm() && isa<MCConstantExpr>(getImm());
1028 bool isConstantImmz() const {
1029 return isConstantImm() && getConstantImm() == 0;
1031 template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1032 return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1034 template <unsigned Bits> bool isSImm() const {
1035 return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1037 template <unsigned Bits> bool isUImm() const {
1038 return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1040 template <unsigned Bits> bool isAnyImm() const {
1041 return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1042 isUInt<Bits>(getConstantImm()))
1045 template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1046 return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1048 template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1049 return isConstantImm() && getConstantImm() >= Bottom &&
1050 getConstantImm() <= Top;
1052 bool isToken() const override {
1053 // Note: It's not possible to pretend that other operand kinds are tokens.
1054 // The matcher emitter checks tokens first.
1055 return Kind == k_Token;
1057 bool isMem() const override { return Kind == k_Memory; }
1058 bool isConstantMemOff() const {
1059 return isMem() && isa<MCConstantExpr>(getMemOff());
1061 // Allow relocation operators.
1062 // FIXME: This predicate and others need to look through binary expressions
1063 // and determine whether a Value is a constant or not.
1064 template <unsigned Bits, unsigned ShiftAmount = 0>
1065 bool isMemWithSimmOffset() const {
1068 if (!getMemBase()->isGPRAsmReg())
1070 if (isa<MCTargetExpr>(getMemOff()) ||
1071 (isConstantMemOff() &&
1072 isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1075 bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1076 return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1078 bool isMemWithGRPMM16Base() const {
1079 return isMem() && getMemBase()->isMM16AsmReg();
1081 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1082 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1083 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1085 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1086 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1087 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1088 && (getMemBase()->getGPR32Reg() == Mips::SP);
1090 template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1091 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1092 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1093 && (getMemBase()->getGPR32Reg() == Mips::GP);
1095 template <unsigned Bits, unsigned ShiftLeftAmount>
1096 bool isScaledUImm() const {
1097 return isConstantImm() &&
1098 isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1100 template <unsigned Bits, unsigned ShiftLeftAmount>
1101 bool isScaledSImm() const {
1102 return isConstantImm() &&
1103 isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm());
1105 bool isRegList16() const {
1109 int Size = RegList.List->size();
1110 if (Size < 2 || Size > 5)
1113 unsigned R0 = RegList.List->front();
1114 unsigned R1 = RegList.List->back();
1115 if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1116 (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1119 int PrevReg = *RegList.List->begin();
1120 for (int i = 1; i < Size - 1; i++) {
1121 int Reg = (*(RegList.List))[i];
1122 if ( Reg != PrevReg + 1)
1129 bool isInvNum() const { return Kind == k_Immediate; }
1130 bool isLSAImm() const {
1131 if (!isConstantImm())
1133 int64_t Val = getConstantImm();
1134 return 1 <= Val && Val <= 4;
1136 bool isRegList() const { return Kind == k_RegList; }
1137 bool isMovePRegPair() const {
1138 if (Kind != k_RegList || RegList.List->size() != 2)
1141 unsigned R0 = RegList.List->front();
1142 unsigned R1 = RegList.List->back();
1144 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1145 (R0 == Mips::A1 && R1 == Mips::A3) ||
1146 (R0 == Mips::A2 && R1 == Mips::A3) ||
1147 (R0 == Mips::A0 && R1 == Mips::S5) ||
1148 (R0 == Mips::A0 && R1 == Mips::S6) ||
1149 (R0 == Mips::A0 && R1 == Mips::A1) ||
1150 (R0 == Mips::A0 && R1 == Mips::A2) ||
1151 (R0 == Mips::A0 && R1 == Mips::A3) ||
1152 (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1153 (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1154 (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1155 (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1156 (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1157 (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1158 (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1159 (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1165 StringRef getToken() const {
1166 assert(Kind == k_Token && "Invalid access!");
1167 return StringRef(Tok.Data, Tok.Length);
1169 bool isRegPair() const {
1170 return Kind == k_RegPair && RegIdx.Index <= 30;
1173 unsigned getReg() const override {
1174 // As a special case until we sort out the definition of div/divu, accept
1175 // $0/$zero here so that MCK_ZERO works correctly.
1176 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1177 RegIdx.Kind & RegKind_GPR)
1178 return getGPR32Reg(); // FIXME: GPR64 too
1180 llvm_unreachable("Invalid access!");
1184 const MCExpr *getImm() const {
1185 assert((Kind == k_Immediate) && "Invalid access!");
1189 int64_t getConstantImm() const {
1190 const MCExpr *Val = getImm();
1191 return static_cast<const MCConstantExpr *>(Val)->getValue();
1194 MipsOperand *getMemBase() const {
1195 assert((Kind == k_Memory) && "Invalid access!");
1199 const MCExpr *getMemOff() const {
1200 assert((Kind == k_Memory) && "Invalid access!");
1204 int64_t getConstantMemOff() const {
1205 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1208 const SmallVectorImpl<unsigned> &getRegList() const {
1209 assert((Kind == k_RegList) && "Invalid access!");
1210 return *(RegList.List);
1213 unsigned getRegPair() const {
1214 assert((Kind == k_RegPair) && "Invalid access!");
1215 return RegIdx.Index;
1218 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1219 MipsAsmParser &Parser) {
1220 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1221 Op->Tok.Data = Str.data();
1222 Op->Tok.Length = Str.size();
1228 /// Create a numeric register (e.g. $1). The exact register remains
1229 /// unresolved until an instruction successfully matches
1230 static std::unique_ptr<MipsOperand>
1231 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1232 SMLoc E, MipsAsmParser &Parser) {
1233 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1234 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1237 /// Create a register that is definitely a GPR.
1238 /// This is typically only used for named registers such as $gp.
1239 static std::unique_ptr<MipsOperand>
1240 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1241 MipsAsmParser &Parser) {
1242 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1245 /// Create a register that is definitely a FGR.
1246 /// This is typically only used for named registers such as $f0.
1247 static std::unique_ptr<MipsOperand>
1248 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1249 MipsAsmParser &Parser) {
1250 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1253 /// Create a register that is definitely a HWReg.
1254 /// This is typically only used for named registers such as $hwr_cpunum.
1255 static std::unique_ptr<MipsOperand>
1256 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1257 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1258 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1261 /// Create a register that is definitely an FCC.
1262 /// This is typically only used for named registers such as $fcc0.
1263 static std::unique_ptr<MipsOperand>
1264 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1265 MipsAsmParser &Parser) {
1266 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1269 /// Create a register that is definitely an ACC.
1270 /// This is typically only used for named registers such as $ac0.
1271 static std::unique_ptr<MipsOperand>
1272 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1273 MipsAsmParser &Parser) {
1274 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1277 /// Create a register that is definitely an MSA128.
1278 /// This is typically only used for named registers such as $w0.
1279 static std::unique_ptr<MipsOperand>
1280 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1281 SMLoc E, MipsAsmParser &Parser) {
1282 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1285 /// Create a register that is definitely an MSACtrl.
1286 /// This is typically only used for named registers such as $msaaccess.
1287 static std::unique_ptr<MipsOperand>
1288 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1289 SMLoc E, MipsAsmParser &Parser) {
1290 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1293 static std::unique_ptr<MipsOperand>
1294 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1295 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1302 static std::unique_ptr<MipsOperand>
1303 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1304 SMLoc E, MipsAsmParser &Parser) {
1305 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1306 Op->Mem.Base = Base.release();
1313 static std::unique_ptr<MipsOperand>
1314 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1315 MipsAsmParser &Parser) {
1316 assert (Regs.size() > 0 && "Empty list not allowed");
1318 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1319 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1320 Op->StartLoc = StartLoc;
1321 Op->EndLoc = EndLoc;
1325 static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1327 MipsAsmParser &Parser) {
1328 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1329 Op->RegIdx.Index = MOP.RegIdx.Index;
1330 Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1331 Op->RegIdx.Kind = MOP.RegIdx.Kind;
1337 bool isGPRAsmReg() const {
1338 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1340 bool isMM16AsmReg() const {
1341 if (!(isRegIdx() && RegIdx.Kind))
1343 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1344 || RegIdx.Index == 16 || RegIdx.Index == 17);
1346 bool isMM16AsmRegZero() const {
1347 if (!(isRegIdx() && RegIdx.Kind))
1349 return (RegIdx.Index == 0 ||
1350 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1351 RegIdx.Index == 17);
1353 bool isMM16AsmRegMoveP() const {
1354 if (!(isRegIdx() && RegIdx.Kind))
1356 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1357 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1359 bool isFGRAsmReg() const {
1360 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1361 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1363 bool isHWRegsAsmReg() const {
1364 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1366 bool isCCRAsmReg() const {
1367 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1369 bool isFCCAsmReg() const {
1370 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1372 if (!AsmParser.hasEightFccRegisters())
1373 return RegIdx.Index == 0;
1374 return RegIdx.Index <= 7;
1376 bool isACCAsmReg() const {
1377 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1379 bool isCOP0AsmReg() const {
1380 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1382 bool isCOP2AsmReg() const {
1383 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1385 bool isCOP3AsmReg() const {
1386 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1388 bool isMSA128AsmReg() const {
1389 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1391 bool isMSACtrlAsmReg() const {
1392 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1395 /// getStartLoc - Get the location of the first token of this operand.
1396 SMLoc getStartLoc() const override { return StartLoc; }
1397 /// getEndLoc - Get the location of the last token of this operand.
1398 SMLoc getEndLoc() const override { return EndLoc; }
1400 virtual ~MipsOperand() {
1408 delete RegList.List;
1409 case k_RegisterIndex:
1416 void print(raw_ostream &OS) const override {
1425 Mem.Base->print(OS);
1430 case k_RegisterIndex:
1431 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1438 for (auto Reg : (*RegList.List))
1443 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1447 }; // class MipsOperand
1451 extern const MCInstrDesc MipsInsts[];
1453 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1454 return MipsInsts[Opcode];
1457 static bool hasShortDelaySlot(unsigned Opcode) {
1460 case Mips::JALRS_MM:
1461 case Mips::JALRS16_MM:
1462 case Mips::BGEZALS_MM:
1463 case Mips::BLTZALS_MM:
1470 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1471 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1472 return &SRExpr->getSymbol();
1475 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1476 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1477 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1488 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1489 return getSingleMCSymbol(UExpr->getSubExpr());
1494 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1495 if (isa<MCSymbolRefExpr>(Expr))
1498 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1499 return countMCSymbolRefExpr(BExpr->getLHS()) +
1500 countMCSymbolRefExpr(BExpr->getRHS());
1502 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1503 return countMCSymbolRefExpr(UExpr->getSubExpr());
1508 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1510 const MCSubtargetInfo *STI) {
1511 MipsTargetStreamer &TOut = getTargetStreamer();
1512 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1513 bool ExpandedJalSym = false;
1517 if (MCID.isBranch() || MCID.isCall()) {
1518 const unsigned Opcode = Inst.getOpcode();
1528 assert(hasCnMips() && "instruction only valid for octeon cpus");
1535 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1536 Offset = Inst.getOperand(2);
1537 if (!Offset.isImm())
1538 break; // We'll deal with this situation later on when applying fixups.
1539 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1540 return Error(IDLoc, "branch target out of range");
1541 if (OffsetToAlignment(Offset.getImm(),
1542 1LL << (inMicroMipsMode() ? 1 : 2)))
1543 return Error(IDLoc, "branch to misaligned address");
1557 case Mips::BGEZAL_MM:
1558 case Mips::BLTZAL_MM:
1561 case Mips::BC1EQZC_MMR6:
1562 case Mips::BC1NEZC_MMR6:
1563 case Mips::BC2EQZC_MMR6:
1564 case Mips::BC2NEZC_MMR6:
1565 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1566 Offset = Inst.getOperand(1);
1567 if (!Offset.isImm())
1568 break; // We'll deal with this situation later on when applying fixups.
1569 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1570 return Error(IDLoc, "branch target out of range");
1571 if (OffsetToAlignment(Offset.getImm(),
1572 1LL << (inMicroMipsMode() ? 1 : 2)))
1573 return Error(IDLoc, "branch to misaligned address");
1575 case Mips::BEQZ16_MM:
1576 case Mips::BEQZC16_MMR6:
1577 case Mips::BNEZ16_MM:
1578 case Mips::BNEZC16_MMR6:
1579 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1580 Offset = Inst.getOperand(1);
1581 if (!Offset.isImm())
1582 break; // We'll deal with this situation later on when applying fixups.
1583 if (!isInt<8>(Offset.getImm()))
1584 return Error(IDLoc, "branch target out of range");
1585 if (OffsetToAlignment(Offset.getImm(), 2LL))
1586 return Error(IDLoc, "branch to misaligned address");
1591 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1592 // We still accept it but it is a normal nop.
1593 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1594 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1595 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1600 const unsigned Opcode = Inst.getOpcode();
1612 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1613 // The offset is handled above
1614 Opnd = Inst.getOperand(1);
1616 return Error(IDLoc, "expected immediate operand kind");
1617 Imm = Opnd.getImm();
1618 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1619 Opcode == Mips::BBIT1 ? 63 : 31))
1620 return Error(IDLoc, "immediate operand value out of range");
1622 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1624 Inst.getOperand(1).setImm(Imm - 32);
1630 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1631 Opnd = Inst.getOperand(2);
1633 return Error(IDLoc, "expected immediate operand kind");
1634 Imm = Opnd.getImm();
1635 if (!isInt<10>(Imm))
1636 return Error(IDLoc, "immediate operand value out of range");
1641 // This expansion is not in a function called by tryExpandInstruction()
1642 // because the pseudo-instruction doesn't have a distinct opcode.
1643 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1645 warnIfNoMacro(IDLoc);
1647 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1649 // We can do this expansion if there's only 1 symbol in the argument
1651 if (countMCSymbolRefExpr(JalExpr) > 1)
1652 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1654 // FIXME: This is checking the expression can be handled by the later stages
1655 // of the assembler. We ought to leave it to those later stages.
1656 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1658 // FIXME: Add support for label+offset operands (currently causes an error).
1659 // FIXME: Add support for forward-declared local symbols.
1660 // FIXME: Add expansion for when the LargeGOT option is enabled.
1661 if (JalSym->isInSection() || JalSym->isTemporary()) {
1663 // If it's a local symbol and the O32 ABI is being used, we expand to:
1665 // R_(MICRO)MIPS_GOT16 label
1666 // addiu $25, $25, 0
1667 // R_(MICRO)MIPS_LO16 label
1669 const MCExpr *Got16RelocExpr =
1670 MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
1671 const MCExpr *Lo16RelocExpr =
1672 MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
1674 TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
1675 MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
1676 TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1677 MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
1678 } else if (isABI_N32() || isABI_N64()) {
1679 // If it's a local symbol and the N32/N64 ABIs are being used,
1681 // lw/ld $25, 0($gp)
1682 // R_(MICRO)MIPS_GOT_DISP label
1684 const MCExpr *GotDispRelocExpr =
1685 MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
1687 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
1688 Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
1692 // If it's an external/weak symbol, we expand to:
1693 // lw/ld $25, 0($gp)
1694 // R_(MICRO)MIPS_CALL16 label
1696 const MCExpr *Call16RelocExpr =
1697 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
1699 TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1700 MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
1704 if (IsCpRestoreSet && inMicroMipsMode())
1705 JalrInst.setOpcode(Mips::JALRS_MM);
1707 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1708 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1709 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1711 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1712 // This relocation is supposed to be an optimization hint for the linker
1713 // and is not necessary for correctness.
1716 ExpandedJalSym = true;
1719 if (MCID.mayLoad() || MCID.mayStore()) {
1720 // Check the offset of memory operand, if it is a symbol
1721 // reference or immediate we may have to expand instructions.
1722 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1723 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1724 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1725 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1726 MCOperand &Op = Inst.getOperand(i);
1728 int MemOffset = Op.getImm();
1729 if (MemOffset < -32768 || MemOffset > 32767) {
1730 // Offset can't exceed 16bit value.
1731 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
1734 } else if (Op.isExpr()) {
1735 const MCExpr *Expr = Op.getExpr();
1736 if (Expr->getKind() == MCExpr::SymbolRef) {
1737 const MCSymbolRefExpr *SR =
1738 static_cast<const MCSymbolRefExpr *>(Expr);
1739 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1741 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1744 } else if (!isEvaluated(Expr)) {
1745 expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
1753 if (inMicroMipsMode()) {
1754 if (MCID.mayLoad()) {
1755 // Try to create 16-bit GP relative load instruction.
1756 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1757 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1758 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1759 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1760 MCOperand &Op = Inst.getOperand(i);
1762 int MemOffset = Op.getImm();
1763 MCOperand &DstReg = Inst.getOperand(0);
1764 MCOperand &BaseReg = Inst.getOperand(1);
1765 if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1766 getContext().getRegisterInfo()->getRegClass(
1767 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1768 (BaseReg.getReg() == Mips::GP ||
1769 BaseReg.getReg() == Mips::GP_64)) {
1771 TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1780 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1785 switch (Inst.getOpcode()) {
1788 case Mips::ADDIUSP_MM:
1789 Opnd = Inst.getOperand(0);
1791 return Error(IDLoc, "expected immediate operand kind");
1792 Imm = Opnd.getImm();
1793 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1795 return Error(IDLoc, "immediate operand value out of range");
1797 case Mips::SLL16_MM:
1798 case Mips::SRL16_MM:
1799 Opnd = Inst.getOperand(2);
1801 return Error(IDLoc, "expected immediate operand kind");
1802 Imm = Opnd.getImm();
1803 if (Imm < 1 || Imm > 8)
1804 return Error(IDLoc, "immediate operand value out of range");
1807 Opnd = Inst.getOperand(1);
1809 return Error(IDLoc, "expected immediate operand kind");
1810 Imm = Opnd.getImm();
1811 if (Imm < -1 || Imm > 126)
1812 return Error(IDLoc, "immediate operand value out of range");
1814 case Mips::ADDIUR2_MM:
1815 Opnd = Inst.getOperand(2);
1817 return Error(IDLoc, "expected immediate operand kind");
1818 Imm = Opnd.getImm();
1819 if (!(Imm == 1 || Imm == -1 ||
1820 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1821 return Error(IDLoc, "immediate operand value out of range");
1823 case Mips::ANDI16_MM:
1824 Opnd = Inst.getOperand(2);
1826 return Error(IDLoc, "expected immediate operand kind");
1827 Imm = Opnd.getImm();
1828 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1829 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1830 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1831 return Error(IDLoc, "immediate operand value out of range");
1833 case Mips::LBU16_MM:
1834 Opnd = Inst.getOperand(2);
1836 return Error(IDLoc, "expected immediate operand kind");
1837 Imm = Opnd.getImm();
1838 if (Imm < -1 || Imm > 14)
1839 return Error(IDLoc, "immediate operand value out of range");
1842 case Mips::SB16_MMR6:
1843 Opnd = Inst.getOperand(2);
1845 return Error(IDLoc, "expected immediate operand kind");
1846 Imm = Opnd.getImm();
1847 if (Imm < 0 || Imm > 15)
1848 return Error(IDLoc, "immediate operand value out of range");
1850 case Mips::LHU16_MM:
1852 case Mips::SH16_MMR6:
1853 Opnd = Inst.getOperand(2);
1855 return Error(IDLoc, "expected immediate operand kind");
1856 Imm = Opnd.getImm();
1857 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1858 return Error(IDLoc, "immediate operand value out of range");
1862 case Mips::SW16_MMR6:
1863 Opnd = Inst.getOperand(2);
1865 return Error(IDLoc, "expected immediate operand kind");
1866 Imm = Opnd.getImm();
1867 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1868 return Error(IDLoc, "immediate operand value out of range");
1870 case Mips::ADDIUPC_MM:
1871 MCOperand Opnd = Inst.getOperand(1);
1873 return Error(IDLoc, "expected immediate operand kind");
1874 int Imm = Opnd.getImm();
1875 if ((Imm % 4 != 0) || !isInt<25>(Imm))
1876 return Error(IDLoc, "immediate operand value out of range");
1881 bool FillDelaySlot =
1882 MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
1884 TOut.emitDirectiveSetNoReorder();
1886 MacroExpanderResultTy ExpandResult =
1887 tryExpandInstruction(Inst, IDLoc, Out, STI);
1888 switch (ExpandResult) {
1890 Out.EmitInstruction(Inst, *STI);
1898 // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
1899 // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
1900 if (inMicroMipsMode())
1901 TOut.setUsesMicroMips();
1903 // If this instruction has a delay slot and .set reorder is active,
1904 // emit a NOP after it.
1905 if (FillDelaySlot) {
1906 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
1907 TOut.emitDirectiveSetReorder();
1910 if ((Inst.getOpcode() == Mips::JalOneReg ||
1911 Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1912 isPicAndNotNxxAbi()) {
1913 if (IsCpRestoreSet) {
1914 // We need a NOP between the JALR and the LW:
1915 // If .set reorder has been used, we've already emitted a NOP.
1916 // If .set noreorder has been used, we need to emit a NOP at this point.
1917 if (!AssemblerOptions.back()->isReorder())
1918 TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
1921 // Load the $gp from the stack.
1922 TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
1924 Warning(IDLoc, "no .cprestore used in PIC mode");
1930 MipsAsmParser::MacroExpanderResultTy
1931 MipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
1932 const MCSubtargetInfo *STI) {
1933 switch (Inst.getOpcode()) {
1935 return MER_NotAMacro;
1936 case Mips::LoadImm32:
1937 return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
1938 case Mips::LoadImm64:
1939 return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
1940 case Mips::LoadAddrImm32:
1941 case Mips::LoadAddrImm64:
1942 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1943 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1944 "expected immediate operand kind");
1946 return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1948 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1952 case Mips::LoadAddrReg32:
1953 case Mips::LoadAddrReg64:
1954 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1955 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1956 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1957 "expected immediate operand kind");
1959 return expandLoadAddress(Inst.getOperand(0).getReg(),
1960 Inst.getOperand(1).getReg(), Inst.getOperand(2),
1961 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1965 case Mips::B_MM_Pseudo:
1966 case Mips::B_MMR6_Pseudo:
1967 return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
1971 return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
1973 case Mips::JalOneReg:
1974 case Mips::JalTwoReg:
1975 return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
1978 return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
1995 case Mips::BLTImmMacro:
1996 case Mips::BLEImmMacro:
1997 case Mips::BGEImmMacro:
1998 case Mips::BGTImmMacro:
1999 case Mips::BLTUImmMacro:
2000 case Mips::BLEUImmMacro:
2001 case Mips::BGEUImmMacro:
2002 case Mips::BGTUImmMacro:
2003 case Mips::BLTLImmMacro:
2004 case Mips::BLELImmMacro:
2005 case Mips::BGELImmMacro:
2006 case Mips::BGTLImmMacro:
2007 case Mips::BLTULImmMacro:
2008 case Mips::BLEULImmMacro:
2009 case Mips::BGEULImmMacro:
2010 case Mips::BGTULImmMacro:
2011 return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2012 case Mips::SDivMacro:
2013 return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2015 case Mips::DSDivMacro:
2016 return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2018 case Mips::UDivMacro:
2019 return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2021 case Mips::DUDivMacro:
2022 return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2024 case Mips::PseudoTRUNC_W_S:
2025 return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2027 case Mips::PseudoTRUNC_W_D32:
2028 return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2030 case Mips::PseudoTRUNC_W_D:
2031 return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2034 return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2036 return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2038 return expandUlw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2040 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2045 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2046 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2047 int64_t ImmValue = Inst.getOperand(2).getImm();
2048 if (isInt<16>(ImmValue))
2049 return MER_NotAMacro;
2050 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2053 return MER_NotAMacro;
2057 if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2058 Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2059 int64_t ImmValue = Inst.getOperand(2).getImm();
2060 if (isUInt<16>(ImmValue))
2061 return MER_NotAMacro;
2062 return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2065 return MER_NotAMacro;
2068 return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2071 return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2074 return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2077 return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2078 case Mips::ABSMacro:
2079 return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2083 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2085 const MCSubtargetInfo *STI) {
2086 MipsTargetStreamer &TOut = getTargetStreamer();
2088 // Create a JALR instruction which is going to replace the pseudo-JAL.
2090 JalrInst.setLoc(IDLoc);
2091 const MCOperand FirstRegOp = Inst.getOperand(0);
2092 const unsigned Opcode = Inst.getOpcode();
2094 if (Opcode == Mips::JalOneReg) {
2095 // jal $rs => jalr $rs
2096 if (IsCpRestoreSet && inMicroMipsMode()) {
2097 JalrInst.setOpcode(Mips::JALRS16_MM);
2098 JalrInst.addOperand(FirstRegOp);
2099 } else if (inMicroMipsMode()) {
2100 JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2101 JalrInst.addOperand(FirstRegOp);
2103 JalrInst.setOpcode(Mips::JALR);
2104 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2105 JalrInst.addOperand(FirstRegOp);
2107 } else if (Opcode == Mips::JalTwoReg) {
2108 // jal $rd, $rs => jalr $rd, $rs
2109 if (IsCpRestoreSet && inMicroMipsMode())
2110 JalrInst.setOpcode(Mips::JALRS_MM);
2112 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2113 JalrInst.addOperand(FirstRegOp);
2114 const MCOperand SecondRegOp = Inst.getOperand(1);
2115 JalrInst.addOperand(SecondRegOp);
2117 Out.EmitInstruction(JalrInst, *STI);
2119 // If .set reorder is active and branch instruction has a delay slot,
2120 // emit a NOP after it.
2121 const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2122 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2123 TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2129 /// Can the value be represented by a unsigned N-bit value and a shift left?
2130 template <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2131 unsigned BitNum = findFirstSet(x);
2133 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2136 /// Load (or add) an immediate into a register.
2138 /// @param ImmValue The immediate to load.
2139 /// @param DstReg The register that will hold the immediate.
2140 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2141 /// for a simple initialization.
2142 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2143 /// @param IsAddress True if the immediate represents an address. False if it
2145 /// @param IDLoc Location of the immediate in the source file.
2146 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2147 unsigned SrcReg, bool Is32BitImm,
2148 bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2149 const MCSubtargetInfo *STI) {
2150 MipsTargetStreamer &TOut = getTargetStreamer();
2152 if (!Is32BitImm && !isGP64bit()) {
2153 Error(IDLoc, "instruction requires a 64-bit architecture");
2158 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2159 // Sign extend up to 64-bit so that the predicates match the hardware
2160 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2162 ImmValue = SignExtend64<32>(ImmValue);
2164 Error(IDLoc, "instruction requires a 32-bit immediate");
2169 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2170 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2172 bool UseSrcReg = false;
2173 if (SrcReg != Mips::NoRegister)
2176 unsigned TmpReg = DstReg;
2178 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2179 // At this point we need AT to perform the expansions and we exit if it is
2181 unsigned ATReg = getATReg(IDLoc);
2187 if (isInt<16>(ImmValue)) {
2191 // This doesn't quite follow the usual ABI expectations for N32 but matches
2192 // traditional assembler behaviour. N32 would normally use addiu for both
2193 // integers and addresses.
2194 if (IsAddress && !Is32BitImm) {
2195 TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2199 TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2203 if (isUInt<16>(ImmValue)) {
2204 unsigned TmpReg = DstReg;
2205 if (SrcReg == DstReg) {
2206 TmpReg = getATReg(IDLoc);
2211 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2213 TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2217 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2218 warnIfNoMacro(IDLoc);
2220 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2221 uint16_t Bits15To0 = ImmValue & 0xffff;
2223 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2224 // Traditional behaviour seems to special case this particular value. It's
2225 // not clear why other masks are handled differently.
2226 if (ImmValue == 0xffffffff) {
2227 TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2228 TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2230 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2234 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2236 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2237 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2239 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2241 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2245 TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2247 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2249 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2253 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2255 Error(IDLoc, "instruction requires a 32-bit immediate");
2259 // Traditionally, these immediates are shifted as little as possible and as
2260 // such we align the most significant bit to bit 15 of our temporary.
2261 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2262 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2263 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2264 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2265 TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2266 TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
2269 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2274 warnIfNoMacro(IDLoc);
2276 // The remaining case is packed with a sequence of dsll and ori with zeros
2277 // being omitted and any neighbouring dsll's being coalesced.
2278 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2280 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2281 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2285 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2286 // skip it and defer the shift to the next chunk.
2287 unsigned ShiftCarriedForwards = 16;
2288 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2289 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2291 if (ImmChunk != 0) {
2292 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2293 TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2294 ShiftCarriedForwards = 0;
2297 ShiftCarriedForwards += 16;
2299 ShiftCarriedForwards -= 16;
2301 // Finish any remaining shifts left by trailing zeros.
2302 if (ShiftCarriedForwards)
2303 TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2306 TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2311 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2312 MCStreamer &Out, const MCSubtargetInfo *STI) {
2313 const MCOperand &ImmOp = Inst.getOperand(1);
2314 assert(ImmOp.isImm() && "expected immediate operand kind");
2315 const MCOperand &DstRegOp = Inst.getOperand(0);
2316 assert(DstRegOp.isReg() && "expected register operand kind");
2318 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2319 Is32BitImm, false, IDLoc, Out, STI))
2325 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2326 const MCOperand &Offset,
2327 bool Is32BitAddress, SMLoc IDLoc,
2329 const MCSubtargetInfo *STI) {
2330 // la can't produce a usable address when addresses are 64-bit.
2331 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2332 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2333 // We currently can't do this because we depend on the equality
2334 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2335 Error(IDLoc, "la used to load 64-bit address");
2336 // Continue as if we had 'dla' instead.
2337 Is32BitAddress = false;
2340 // dla requires 64-bit addresses.
2341 if (!Is32BitAddress && !hasMips3()) {
2342 Error(IDLoc, "instruction requires a 64-bit architecture");
2346 if (!Offset.isImm())
2347 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2348 Is32BitAddress, IDLoc, Out, STI);
2350 if (!ABI.ArePtrs64bit()) {
2351 // Continue as if we had 'la' whether we had 'la' or 'dla'.
2352 Is32BitAddress = true;
2355 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2359 bool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2360 unsigned DstReg, unsigned SrcReg,
2361 bool Is32BitSym, SMLoc IDLoc,
2363 const MCSubtargetInfo *STI) {
2364 MipsTargetStreamer &TOut = getTargetStreamer();
2365 bool UseSrcReg = SrcReg != Mips::NoRegister;
2366 warnIfNoMacro(IDLoc);
2368 if (inPicMode() && ABI.IsO32()) {
2370 if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2371 Error(IDLoc, "expected relocatable expression");
2374 if (Res.getSymB() != nullptr) {
2375 Error(IDLoc, "expected relocatable expression with only one symbol");
2379 // The case where the result register is $25 is somewhat special. If the
2380 // symbol in the final relocation is external and not modified with a
2381 // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2382 if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2383 Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
2384 !Res.getSymA()->getSymbol().isTemporary()) {
2385 const MCExpr *CallExpr =
2386 MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2387 TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2388 MCOperand::createExpr(CallExpr), IDLoc, STI);
2392 // The remaining cases are:
2393 // External GOT: lw $tmp, %got(symbol+offset)($gp)
2394 // >addiu $tmp, $tmp, %lo(offset)
2395 // >addiu $rd, $tmp, $rs
2396 // Local GOT: lw $tmp, %got(symbol+offset)($gp)
2397 // addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2398 // >addiu $rd, $tmp, $rs
2399 // The addiu's marked with a '>' may be omitted if they are redundant. If
2400 // this happens then the last instruction must use $rd as the result
2402 const MipsMCExpr *GotExpr =
2403 MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2404 const MCExpr *LoExpr = nullptr;
2405 if (Res.getSymA()->getSymbol().isInSection() ||
2406 Res.getSymA()->getSymbol().isTemporary())
2407 LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2408 else if (Res.getConstant() != 0) {
2409 // External symbols fully resolve the symbol with just the %got(symbol)
2410 // but we must still account for any offset to the symbol for expressions
2412 LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2415 unsigned TmpReg = DstReg;
2417 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2419 // If $rs is the same as $rd, we need to use AT.
2420 // If it is not available we exit.
2421 unsigned ATReg = getATReg(IDLoc);
2427 TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2428 MCOperand::createExpr(GotExpr), IDLoc, STI);
2431 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2435 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2440 const MipsMCExpr *HiExpr =
2441 MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2442 const MipsMCExpr *LoExpr =
2443 MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2445 // This is the 64-bit symbol address expansion.
2446 if (ABI.ArePtrs64bit() && isGP64bit()) {
2447 // We always need AT for the 64-bit expansion.
2448 // If it is not available we exit.
2449 unsigned ATReg = getATReg(IDLoc);
2453 const MipsMCExpr *HighestExpr =
2454 MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2455 const MipsMCExpr *HigherExpr =
2456 MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2459 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2461 // If $rs is the same as $rd:
2462 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2463 // daddiu $at, $at, %higher(sym)
2464 // dsll $at, $at, 16
2465 // daddiu $at, $at, %hi(sym)
2466 // dsll $at, $at, 16
2467 // daddiu $at, $at, %lo(sym)
2468 // daddu $rd, $at, $rd
2469 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2471 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2472 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2473 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2474 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2476 TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2477 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2479 TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2484 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2485 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2486 // lui $at, %hi(sym)
2487 // daddiu $rd, $rd, %higher(sym)
2488 // daddiu $at, $at, %lo(sym)
2489 // dsll32 $rd, $rd, 0
2490 // daddu $rd, $rd, $at
2491 // (daddu $rd, $rd, $rs)
2492 TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2494 TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2495 TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2496 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2497 TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2499 TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2500 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2502 TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
2507 // And now, the 32-bit symbol address expansion:
2508 // If $rs is the same as $rd:
2509 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2510 // ori $at, $at, %lo(sym)
2511 // addu $rd, $at, $rd
2512 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2513 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2514 // ori $rd, $rd, %lo(sym)
2515 // (addu $rd, $rd, $rs)
2516 unsigned TmpReg = DstReg;
2518 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2519 // If $rs is the same as $rd, we need to use AT.
2520 // If it is not available we exit.
2521 unsigned ATReg = getATReg(IDLoc);
2527 TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2528 TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2532 TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2535 getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2540 bool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
2542 const MCSubtargetInfo *STI) {
2543 MipsTargetStreamer &TOut = getTargetStreamer();
2545 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2546 "unexpected number of operands");
2548 MCOperand Offset = Inst.getOperand(0);
2549 if (Offset.isExpr()) {
2551 Inst.setOpcode(Mips::BEQ_MM);
2552 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2553 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2554 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2556 assert(Offset.isImm() && "expected immediate operand kind");
2557 if (isInt<11>(Offset.getImm())) {
2558 // If offset fits into 11 bits then this instruction becomes microMIPS
2559 // 16-bit unconditional branch instruction.
2560 if (inMicroMipsMode())
2561 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2563 if (!isInt<17>(Offset.getImm()))
2564 Error(IDLoc, "branch target out of range");
2565 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2566 Error(IDLoc, "branch to misaligned address");
2568 Inst.setOpcode(Mips::BEQ_MM);
2569 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2570 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2571 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2574 Out.EmitInstruction(Inst, *STI);
2576 // If .set reorder is active and branch instruction has a delay slot,
2577 // emit a NOP after it.
2578 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2579 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2580 TOut.emitEmptyDelaySlot(true, IDLoc, STI);
2585 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2586 const MCSubtargetInfo *STI) {
2587 MipsTargetStreamer &TOut = getTargetStreamer();
2588 const MCOperand &DstRegOp = Inst.getOperand(0);
2589 assert(DstRegOp.isReg() && "expected register operand kind");
2591 const MCOperand &ImmOp = Inst.getOperand(1);
2592 assert(ImmOp.isImm() && "expected immediate operand kind");
2594 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2595 assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
2596 "expected immediate or expression operand");
2598 unsigned OpCode = 0;
2599 switch(Inst.getOpcode()) {
2607 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2611 int64_t ImmValue = ImmOp.getImm();
2613 TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2616 warnIfNoMacro(IDLoc);
2618 unsigned ATReg = getATReg(IDLoc);
2622 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2626 TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
2631 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2632 const MCSubtargetInfo *STI, bool IsLoad,
2635 expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2638 expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2641 void MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2642 const MCSubtargetInfo *STI, bool IsImmOpnd) {
2643 MipsTargetStreamer &TOut = getTargetStreamer();
2645 unsigned DstReg = Inst.getOperand(0).getReg();
2646 unsigned BaseReg = Inst.getOperand(1).getReg();
2648 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2649 int16_t DstRegClass = Desc.OpInfo[0].RegClass;
2650 unsigned DstRegClassID =
2651 getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
2652 bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
2653 (DstRegClassID == Mips::GPR64RegClassID);
2656 // Try to use DstReg as the temporary.
2657 if (IsGPR && (BaseReg != DstReg)) {
2658 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2659 Inst.getOperand(2).getImm(), DstReg, IDLoc,
2664 // At this point we need AT to perform the expansions and we exit if it is
2666 unsigned ATReg = getATReg(IDLoc);
2670 TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2671 Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
2675 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2676 MCOperand LoOperand = MCOperand::createExpr(
2677 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2678 MCOperand HiOperand = MCOperand::createExpr(
2679 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2681 // Try to use DstReg as the temporary.
2682 if (IsGPR && (BaseReg != DstReg)) {
2683 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2684 LoOperand, DstReg, IDLoc, STI);
2688 // At this point we need AT to perform the expansions and we exit if it is
2690 unsigned ATReg = getATReg(IDLoc);
2694 TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2695 LoOperand, ATReg, IDLoc, STI);
2698 void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2699 const MCSubtargetInfo *STI,
2701 MipsTargetStreamer &TOut = getTargetStreamer();
2703 unsigned SrcReg = Inst.getOperand(0).getReg();
2704 unsigned BaseReg = Inst.getOperand(1).getReg();
2707 TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
2708 Inst.getOperand(2).getImm(),
2709 [&]() { return getATReg(IDLoc); }, IDLoc, STI);
2713 unsigned ATReg = getATReg(IDLoc);
2717 const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2718 MCOperand LoOperand = MCOperand::createExpr(
2719 MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2720 MCOperand HiOperand = MCOperand::createExpr(
2721 MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2722 TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
2723 LoOperand, ATReg, IDLoc, STI);
2726 bool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2728 const MCSubtargetInfo *STI) {
2729 unsigned OpNum = Inst.getNumOperands();
2730 unsigned Opcode = Inst.getOpcode();
2731 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2733 assert (Inst.getOperand(OpNum - 1).isImm() &&
2734 Inst.getOperand(OpNum - 2).isReg() &&
2735 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2737 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2738 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2739 (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2740 Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2741 (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2742 Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2743 // It can be implemented as SWM16 or LWM16 instruction.
2744 if (inMicroMipsMode() && hasMips32r6())
2745 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2747 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2750 Inst.setOpcode(NewOpcode);
2751 Out.EmitInstruction(Inst, *STI);
2755 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2757 const MCSubtargetInfo *STI) {
2758 MipsTargetStreamer &TOut = getTargetStreamer();
2759 bool EmittedNoMacroWarning = false;
2760 unsigned PseudoOpcode = Inst.getOpcode();
2761 unsigned SrcReg = Inst.getOperand(0).getReg();
2762 const MCOperand &TrgOp = Inst.getOperand(1);
2763 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2765 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2766 bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2770 TrgReg = TrgOp.getReg();
2771 else if (TrgOp.isImm()) {
2772 warnIfNoMacro(IDLoc);
2773 EmittedNoMacroWarning = true;
2775 TrgReg = getATReg(IDLoc);
2779 switch(PseudoOpcode) {
2781 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2782 case Mips::BLTImmMacro:
2783 PseudoOpcode = Mips::BLT;
2785 case Mips::BLEImmMacro:
2786 PseudoOpcode = Mips::BLE;
2788 case Mips::BGEImmMacro:
2789 PseudoOpcode = Mips::BGE;
2791 case Mips::BGTImmMacro:
2792 PseudoOpcode = Mips::BGT;
2794 case Mips::BLTUImmMacro:
2795 PseudoOpcode = Mips::BLTU;
2797 case Mips::BLEUImmMacro:
2798 PseudoOpcode = Mips::BLEU;
2800 case Mips::BGEUImmMacro:
2801 PseudoOpcode = Mips::BGEU;
2803 case Mips::BGTUImmMacro:
2804 PseudoOpcode = Mips::BGTU;
2806 case Mips::BLTLImmMacro:
2807 PseudoOpcode = Mips::BLTL;
2809 case Mips::BLELImmMacro:
2810 PseudoOpcode = Mips::BLEL;
2812 case Mips::BGELImmMacro:
2813 PseudoOpcode = Mips::BGEL;
2815 case Mips::BGTLImmMacro:
2816 PseudoOpcode = Mips::BGTL;
2818 case Mips::BLTULImmMacro:
2819 PseudoOpcode = Mips::BLTUL;
2821 case Mips::BLEULImmMacro:
2822 PseudoOpcode = Mips::BLEUL;
2824 case Mips::BGEULImmMacro:
2825 PseudoOpcode = Mips::BGEUL;
2827 case Mips::BGTULImmMacro:
2828 PseudoOpcode = Mips::BGTUL;
2832 if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2833 false, IDLoc, Out, STI))
2837 switch (PseudoOpcode) {
2842 AcceptsEquality = false;
2843 ReverseOrderSLT = false;
2844 IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2845 IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2846 ZeroSrcOpcode = Mips::BGTZ;
2847 ZeroTrgOpcode = Mips::BLTZ;
2853 AcceptsEquality = true;
2854 ReverseOrderSLT = true;
2855 IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2856 IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2857 ZeroSrcOpcode = Mips::BGEZ;
2858 ZeroTrgOpcode = Mips::BLEZ;
2864 AcceptsEquality = true;
2865 ReverseOrderSLT = false;
2866 IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2867 IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2868 ZeroSrcOpcode = Mips::BLEZ;
2869 ZeroTrgOpcode = Mips::BGEZ;
2875 AcceptsEquality = false;
2876 ReverseOrderSLT = true;
2877 IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2878 IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2879 ZeroSrcOpcode = Mips::BLTZ;
2880 ZeroTrgOpcode = Mips::BGTZ;
2883 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2886 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2887 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2888 if (IsSrcRegZero && IsTrgRegZero) {
2889 // FIXME: All of these Opcode-specific if's are needed for compatibility
2890 // with GAS' behaviour. However, they may not generate the most efficient
2891 // code in some circumstances.
2892 if (PseudoOpcode == Mips::BLT) {
2893 TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2897 if (PseudoOpcode == Mips::BLE) {
2898 TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2900 Warning(IDLoc, "branch is always taken");
2903 if (PseudoOpcode == Mips::BGE) {
2904 TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2906 Warning(IDLoc, "branch is always taken");
2909 if (PseudoOpcode == Mips::BGT) {
2910 TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2914 if (PseudoOpcode == Mips::BGTU) {
2915 TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2916 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2919 if (AcceptsEquality) {
2920 // If both registers are $0 and the pseudo-branch accepts equality, it
2921 // will always be taken, so we emit an unconditional branch.
2922 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2923 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2924 Warning(IDLoc, "branch is always taken");
2927 // If both registers are $0 and the pseudo-branch does not accept
2928 // equality, it will never be taken, so we don't have to emit anything.
2931 if (IsSrcRegZero || IsTrgRegZero) {
2932 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2933 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2934 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2935 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2936 // the pseudo-branch will never be taken, so we don't emit anything.
2937 // This only applies to unsigned pseudo-branches.
2940 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2941 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2942 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2943 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2944 // the pseudo-branch will always be taken, so we emit an unconditional
2946 // This only applies to unsigned pseudo-branches.
2947 TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2948 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2949 Warning(IDLoc, "branch is always taken");
2953 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2954 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2955 // the pseudo-branch will be taken only when the non-zero register is
2956 // different from 0, so we emit a BNEZ.
2958 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2959 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2960 // the pseudo-branch will be taken only when the non-zero register is
2961 // equal to 0, so we emit a BEQZ.
2963 // Because only BLEU and BGEU branch on equality, we can use the
2964 // AcceptsEquality variable to decide when to emit the BEQZ.
2965 TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2966 IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2967 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2970 // If we have a signed pseudo-branch and one of the registers is $0,
2971 // we can use an appropriate compare-to-zero branch. We select which one
2972 // to use in the switch statement above.
2973 TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2974 IsSrcRegZero ? TrgReg : SrcReg,
2975 MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2979 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2980 // expansions. If it is not available, we return.
2981 unsigned ATRegNum = getATReg(IDLoc);
2985 if (!EmittedNoMacroWarning)
2986 warnIfNoMacro(IDLoc);
2988 // SLT fits well with 2 of our 4 pseudo-branches:
2989 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2990 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2991 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2992 // This is accomplished by using a BNEZ with the result of the SLT.
2994 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2995 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2996 // Because only BGE and BLE branch on equality, we can use the
2997 // AcceptsEquality variable to decide when to emit the BEQZ.
2998 // Note that the order of the SLT arguments doesn't change between
3001 // The same applies to the unsigned variants, except that SLTu is used
3003 TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3004 ReverseOrderSLT ? TrgReg : SrcReg,
3005 ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3007 TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3008 : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3009 ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3014 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3015 const MCSubtargetInfo *STI, const bool IsMips64,
3016 const bool Signed) {
3017 MipsTargetStreamer &TOut = getTargetStreamer();
3019 warnIfNoMacro(IDLoc);
3021 const MCOperand &RdRegOp = Inst.getOperand(0);
3022 assert(RdRegOp.isReg() && "expected register operand kind");
3023 unsigned RdReg = RdRegOp.getReg();
3025 const MCOperand &RsRegOp = Inst.getOperand(1);
3026 assert(RsRegOp.isReg() && "expected register operand kind");
3027 unsigned RsReg = RsRegOp.getReg();
3029 const MCOperand &RtRegOp = Inst.getOperand(2);
3030 assert(RtRegOp.isReg() && "expected register operand kind");
3031 unsigned RtReg = RtRegOp.getReg();
3036 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3037 ZeroReg = Mips::ZERO_64;
3039 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3040 ZeroReg = Mips::ZERO;
3043 bool UseTraps = useTraps();
3045 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3046 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
3047 Warning(IDLoc, "dividing zero by zero");
3049 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3051 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3055 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3059 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3064 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3065 Warning(IDLoc, "division by zero");
3068 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3072 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3077 // FIXME: The values for these two BranchTarget variables may be different in
3078 // micromips. These magic numbers need to be removed.
3079 unsigned BranchTargetNoTraps;
3080 unsigned BranchTarget;
3083 BranchTarget = IsMips64 ? 12 : 8;
3084 TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3086 BranchTarget = IsMips64 ? 20 : 16;
3087 BranchTargetNoTraps = 8;
3088 // Branch to the li instruction.
3089 TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI);
3092 TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3095 TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3098 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3102 unsigned ATReg = getATReg(IDLoc);
3106 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3108 // Branch to the mflo instruction.
3109 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3110 TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3111 TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3113 // Branch to the mflo instruction.
3114 TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3115 TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3119 TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3121 // Branch to the mflo instruction.
3122 TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI);
3123 TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3124 TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3126 TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3130 bool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3131 SMLoc IDLoc, MCStreamer &Out,
3132 const MCSubtargetInfo *STI) {
3133 MipsTargetStreamer &TOut = getTargetStreamer();
3135 assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3136 assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
3137 Inst.getOperand(2).isReg() && "Invalid instruction operand.");
3139 unsigned FirstReg = Inst.getOperand(0).getReg();
3140 unsigned SecondReg = Inst.getOperand(1).getReg();
3141 unsigned ThirdReg = Inst.getOperand(2).getReg();
3143 if (hasMips1() && !hasMips2()) {
3144 unsigned ATReg = getATReg(IDLoc);
3147 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3148 TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3149 TOut.emitNop(IDLoc, STI);
3150 TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3151 TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3152 TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3153 TOut.emitNop(IDLoc, STI);
3154 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3156 FirstReg, SecondReg, IDLoc, STI);
3157 TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3158 TOut.emitNop(IDLoc, STI);
3162 TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3164 FirstReg, SecondReg, IDLoc, STI);
3169 bool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3170 MCStreamer &Out, const MCSubtargetInfo *STI) {
3171 MipsTargetStreamer &TOut = getTargetStreamer();
3173 if (hasMips32r6() || hasMips64r6()) {
3174 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3178 warnIfNoMacro(IDLoc);
3180 const MCOperand &DstRegOp = Inst.getOperand(0);
3181 assert(DstRegOp.isReg() && "expected register operand kind");
3183 const MCOperand &SrcRegOp = Inst.getOperand(1);
3184 assert(SrcRegOp.isReg() && "expected register operand kind");
3186 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3187 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3189 unsigned DstReg = DstRegOp.getReg();
3190 unsigned SrcReg = SrcRegOp.getReg();
3191 int64_t OffsetValue = OffsetImmOp.getImm();
3193 // NOTE: We always need AT for ULHU, as it is always used as the source
3194 // register for one of the LBu's.
3195 unsigned ATReg = getATReg(IDLoc);
3199 // When the value of offset+1 does not fit in 16 bits, we have to load the
3200 // offset in AT, (D)ADDu the original source register (if there was one), and
3201 // then use AT as the source register for the 2 generated LBu's.
3202 bool LoadedOffsetInAT = false;
3203 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3204 LoadedOffsetInAT = true;
3206 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3207 true, IDLoc, Out, STI))
3210 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3211 // because it will make our output more similar to GAS'. For example,
3212 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3213 // instead of just an "ori $1, $9, 32768".
3214 // NOTE: If there is no source register specified in the ULHU, the parser
3215 // will interpret it as $0.
3216 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3217 TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI);
3220 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3221 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3222 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3224 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3226 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3227 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3229 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3230 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3233 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3235 TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3236 FirstLbuOffset, IDLoc, STI);
3238 TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3241 TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
3243 TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3248 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3249 const MCSubtargetInfo *STI) {
3250 MipsTargetStreamer &TOut = getTargetStreamer();
3252 if (hasMips32r6() || hasMips64r6()) {
3253 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3257 const MCOperand &DstRegOp = Inst.getOperand(0);
3258 assert(DstRegOp.isReg() && "expected register operand kind");
3260 const MCOperand &SrcRegOp = Inst.getOperand(1);
3261 assert(SrcRegOp.isReg() && "expected register operand kind");
3263 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3264 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3266 unsigned SrcReg = SrcRegOp.getReg();
3267 int64_t OffsetValue = OffsetImmOp.getImm();
3270 // When the value of offset+3 does not fit in 16 bits, we have to load the
3271 // offset in AT, (D)ADDu the original source register (if there was one), and
3272 // then use AT as the source register for the generated LWL and LWR.
3273 bool LoadedOffsetInAT = false;
3274 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3275 ATReg = getATReg(IDLoc);
3278 LoadedOffsetInAT = true;
3280 warnIfNoMacro(IDLoc);
3282 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3283 true, IDLoc, Out, STI))
3286 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3287 // because it will make our output more similar to GAS'. For example,
3288 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3289 // instead of just an "ori $1, $9, 32768".
3290 // NOTE: If there is no source register specified in the ULW, the parser
3291 // will interpret it as $0.
3292 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3293 TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI);
3296 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3297 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3299 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3300 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3302 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3303 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3306 TOut.emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3309 TOut.emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset,
3315 bool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3317 const MCSubtargetInfo *STI) {
3318 MipsTargetStreamer &TOut = getTargetStreamer();
3320 assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3321 assert (Inst.getOperand(0).isReg() &&
3322 Inst.getOperand(1).isReg() &&
3323 Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3325 unsigned ATReg = Mips::NoRegister;
3326 unsigned FinalDstReg = Mips::NoRegister;
3327 unsigned DstReg = Inst.getOperand(0).getReg();
3328 unsigned SrcReg = Inst.getOperand(1).getReg();
3329 int64_t ImmValue = Inst.getOperand(2).getImm();
3331 bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3333 unsigned FinalOpcode = Inst.getOpcode();
3335 if (DstReg == SrcReg) {
3336 ATReg = getATReg(Inst.getLoc());
3339 FinalDstReg = DstReg;
3343 if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
3344 switch (FinalOpcode) {
3346 llvm_unreachable("unimplemented expansion");
3348 FinalOpcode = Mips::ADD;
3351 FinalOpcode = Mips::ADDu;
3354 FinalOpcode = Mips::AND;
3356 case (Mips::NORImm):
3357 FinalOpcode = Mips::NOR;
3360 FinalOpcode = Mips::OR;
3363 FinalOpcode = Mips::SLT;
3366 FinalOpcode = Mips::SLTu;
3369 FinalOpcode = Mips::XOR;
3373 if (FinalDstReg == Mips::NoRegister)
3374 TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
3376 TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
3382 bool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3383 const MCSubtargetInfo *STI) {
3384 MipsTargetStreamer &TOut = getTargetStreamer();
3385 unsigned ATReg = Mips::NoRegister;
3386 unsigned DReg = Inst.getOperand(0).getReg();
3387 unsigned SReg = Inst.getOperand(1).getReg();
3388 unsigned TReg = Inst.getOperand(2).getReg();
3389 unsigned TmpReg = DReg;
3391 unsigned FirstShift = Mips::NOP;
3392 unsigned SecondShift = Mips::NOP;
3394 if (hasMips32r2()) {
3397 TmpReg = getATReg(Inst.getLoc());
3402 if (Inst.getOpcode() == Mips::ROL) {
3403 TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3404 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3408 if (Inst.getOpcode() == Mips::ROR) {
3409 TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3418 switch (Inst.getOpcode()) {
3420 llvm_unreachable("unexpected instruction opcode");
3422 FirstShift = Mips::SRLV;
3423 SecondShift = Mips::SLLV;
3426 FirstShift = Mips::SLLV;
3427 SecondShift = Mips::SRLV;
3431 ATReg = getATReg(Inst.getLoc());
3435 TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3436 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3437 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3438 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3446 bool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3448 const MCSubtargetInfo *STI) {
3449 MipsTargetStreamer &TOut = getTargetStreamer();
3450 unsigned ATReg = Mips::NoRegister;
3451 unsigned DReg = Inst.getOperand(0).getReg();
3452 unsigned SReg = Inst.getOperand(1).getReg();
3453 int64_t ImmValue = Inst.getOperand(2).getImm();
3455 unsigned FirstShift = Mips::NOP;
3456 unsigned SecondShift = Mips::NOP;
3458 if (hasMips32r2()) {
3460 if (Inst.getOpcode() == Mips::ROLImm) {
3461 uint64_t MaxShift = 32;
3462 uint64_t ShiftValue = ImmValue;
3464 ShiftValue = MaxShift - ImmValue;
3465 TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3469 if (Inst.getOpcode() == Mips::RORImm) {
3470 TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
3479 if (ImmValue == 0) {
3480 TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
3484 switch (Inst.getOpcode()) {
3486 llvm_unreachable("unexpected instruction opcode");
3488 FirstShift = Mips::SLL;
3489 SecondShift = Mips::SRL;
3492 FirstShift = Mips::SRL;
3493 SecondShift = Mips::SLL;
3497 ATReg = getATReg(Inst.getLoc());
3501 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
3502 TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
3503 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3511 bool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3512 const MCSubtargetInfo *STI) {
3513 MipsTargetStreamer &TOut = getTargetStreamer();
3514 unsigned ATReg = Mips::NoRegister;
3515 unsigned DReg = Inst.getOperand(0).getReg();
3516 unsigned SReg = Inst.getOperand(1).getReg();
3517 unsigned TReg = Inst.getOperand(2).getReg();
3518 unsigned TmpReg = DReg;
3520 unsigned FirstShift = Mips::NOP;
3521 unsigned SecondShift = Mips::NOP;
3523 if (hasMips64r2()) {
3525 if (TmpReg == SReg) {
3526 TmpReg = getATReg(Inst.getLoc());
3531 if (Inst.getOpcode() == Mips::DROL) {
3532 TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3533 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3537 if (Inst.getOpcode() == Mips::DROR) {
3538 TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3547 switch (Inst.getOpcode()) {
3549 llvm_unreachable("unexpected instruction opcode");
3551 FirstShift = Mips::DSRLV;
3552 SecondShift = Mips::DSLLV;
3555 FirstShift = Mips::DSLLV;
3556 SecondShift = Mips::DSRLV;
3560 ATReg = getATReg(Inst.getLoc());
3564 TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3565 TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3566 TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3567 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3575 bool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3577 const MCSubtargetInfo *STI) {
3578 MipsTargetStreamer &TOut = getTargetStreamer();
3579 unsigned ATReg = Mips::NoRegister;
3580 unsigned DReg = Inst.getOperand(0).getReg();
3581 unsigned SReg = Inst.getOperand(1).getReg();
3582 int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3584 unsigned FirstShift = Mips::NOP;
3585 unsigned SecondShift = Mips::NOP;
3589 if (hasMips64r2()) {
3591 unsigned FinalOpcode = Mips::NOP;
3593 FinalOpcode = Mips::DROTR;
3594 else if (ImmValue % 32 == 0)
3595 FinalOpcode = Mips::DROTR32;
3596 else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3597 if (Inst.getOpcode() == Mips::DROLImm)
3598 FinalOpcode = Mips::DROTR32;
3600 FinalOpcode = Mips::DROTR;
3601 } else if (ImmValue >= 33) {
3602 if (Inst.getOpcode() == Mips::DROLImm)
3603 FinalOpcode = Mips::DROTR;
3605 FinalOpcode = Mips::DROTR32;
3608 uint64_t ShiftValue = ImmValue % 32;
3609 if (Inst.getOpcode() == Mips::DROLImm)
3610 ShiftValue = (32 - ImmValue % 32) % 32;
3612 TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3619 if (ImmValue == 0) {
3620 TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
3624 switch (Inst.getOpcode()) {
3626 llvm_unreachable("unexpected instruction opcode");
3628 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3629 FirstShift = Mips::DSLL;
3630 SecondShift = Mips::DSRL32;
3632 if (ImmValue == 32) {
3633 FirstShift = Mips::DSLL32;
3634 SecondShift = Mips::DSRL32;
3636 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3637 FirstShift = Mips::DSLL32;
3638 SecondShift = Mips::DSRL;
3642 if ((ImmValue >= 1) && (ImmValue <= 31)) {
3643 FirstShift = Mips::DSRL;
3644 SecondShift = Mips::DSLL32;
3646 if (ImmValue == 32) {
3647 FirstShift = Mips::DSRL32;
3648 SecondShift = Mips::DSLL32;
3650 if ((ImmValue >= 33) && (ImmValue <= 63)) {
3651 FirstShift = Mips::DSRL32;
3652 SecondShift = Mips::DSLL;
3657 ATReg = getATReg(Inst.getLoc());
3661 TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
3662 TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
3663 Inst.getLoc(), STI);
3664 TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3672 bool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3673 const MCSubtargetInfo *STI) {
3674 MipsTargetStreamer &TOut = getTargetStreamer();
3675 unsigned FirstRegOp = Inst.getOperand(0).getReg();
3676 unsigned SecondRegOp = Inst.getOperand(1).getReg();
3678 TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
3679 if (FirstRegOp != SecondRegOp)
3680 TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
3682 TOut.emitEmptyDelaySlot(false, IDLoc, STI);
3683 TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
3688 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3689 switch (Inst.getOpcode()) {
3690 // As described by the Mips32r2 spec, the registers Rd and Rs for
3691 // jalr.hb must be different.
3692 // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
3693 // and registers Rd and Base for microMIPS lwp instruction
3695 case Mips::JALRC_HB_MMR6:
3696 case Mips::JALRC_MMR6:
3697 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
3698 return Match_RequiresDifferentSrcAndDst;
3699 return Match_Success;
3701 case Mips::LWP_MMR6:
3702 if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
3703 return Match_RequiresDifferentSrcAndDst;
3704 return Match_Success;
3705 // As described the MIPSR6 spec, the compact branches that compare registers
3707 // a) Not use the zero register.
3708 // b) Not use the same register twice.
3709 // c) rs < rt for bnec, beqc.
3710 // NB: For this case, the encoding will swap the operands as their
3711 // ordering doesn't matter. GAS performs this transformation too.
3712 // Hence, that constraint does not have to be enforced.
3714 // The compact branches that branch iff the signed addition of two registers
3715 // would overflow must have rs >= rt. That can be handled like beqc/bnec with
3716 // operand swapping. They do not have restriction of using the zero register.
3723 if (Inst.getOperand(0).getReg() == Mips::ZERO)
3724 return Match_RequiresNoZeroRegister;
3725 return Match_Success;
3732 if (Inst.getOperand(0).getReg() == Mips::ZERO)
3733 return Match_RequiresNoZeroRegister;
3734 if (Inst.getOperand(1).getReg() == Mips::ZERO)
3735 return Match_RequiresNoZeroRegister;
3736 if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
3737 return Match_RequiresDifferentOperands;
3738 return Match_Success;
3740 return Match_Success;
3744 static SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3745 uint64_t ErrorInfo) {
3746 if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3747 SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3748 if (ErrorLoc == SMLoc())
3755 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3756 OperandVector &Operands,
3758 uint64_t &ErrorInfo,
3759 bool MatchingInlineAsm) {
3762 unsigned MatchResult =
3763 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3765 switch (MatchResult) {
3766 case Match_Success: {
3767 if (processInstruction(Inst, IDLoc, Out, STI))
3771 case Match_MissingFeature:
3772 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3774 case Match_InvalidOperand: {
3775 SMLoc ErrorLoc = IDLoc;
3776 if (ErrorInfo != ~0ULL) {
3777 if (ErrorInfo >= Operands.size())
3778 return Error(IDLoc, "too few operands for instruction");
3780 ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3781 if (ErrorLoc == SMLoc())
3785 return Error(ErrorLoc, "invalid operand for instruction");
3787 case Match_MnemonicFail:
3788 return Error(IDLoc, "invalid instruction");
3789 case Match_RequiresDifferentSrcAndDst:
3790 return Error(IDLoc, "source and destination must be different");
3791 case Match_RequiresDifferentOperands:
3792 return Error(IDLoc, "registers must be different");
3793 case Match_RequiresNoZeroRegister:
3794 return Error(IDLoc, "invalid operand ($zero) for instruction");
3796 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3798 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3799 "expected 1-bit unsigned immediate");
3801 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3802 "expected 2-bit unsigned immediate");
3804 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3805 "expected immediate in range 1 .. 4");
3807 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3808 "expected 3-bit unsigned immediate");
3810 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3811 "expected 4-bit unsigned immediate");
3813 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3814 "expected 4-bit signed immediate");
3816 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3817 "expected 5-bit unsigned immediate");
3819 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3820 "expected 5-bit signed immediate");
3822 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3823 "expected immediate in range 1 .. 32");
3824 case Match_UImm5_32:
3825 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3826 "expected immediate in range 32 .. 63");
3827 case Match_UImm5_33:
3828 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3829 "expected immediate in range 33 .. 64");
3830 case Match_UImm5_0_Report_UImm6:
3831 // This is used on UImm5 operands that have a corresponding UImm5_32
3832 // operand to avoid confusing the user.
3833 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3834 "expected 6-bit unsigned immediate");
3835 case Match_UImm5_Lsl2:
3836 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3837 "expected both 7-bit unsigned immediate and multiple of 4");
3838 case Match_UImmRange2_64:
3839 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3840 "expected immediate in range 2 .. 64");
3842 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3843 "expected 6-bit unsigned immediate");
3844 case Match_UImm6_Lsl2:
3845 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3846 "expected both 8-bit unsigned immediate and multiple of 4");
3848 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3849 "expected 6-bit signed immediate");
3851 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3852 "expected 7-bit unsigned immediate");
3853 case Match_UImm7_N1:
3854 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3855 "expected immediate in range -1 .. 126");
3856 case Match_SImm7_Lsl2:
3857 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3858 "expected both 9-bit signed immediate and multiple of 4");
3860 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3861 "expected 8-bit unsigned immediate");
3862 case Match_UImm10_0:
3863 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3864 "expected 10-bit unsigned immediate");
3865 case Match_SImm10_0:
3866 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3867 "expected 10-bit signed immediate");
3868 case Match_SImm11_0:
3869 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3870 "expected 11-bit signed immediate");
3872 case Match_UImm16_Relaxed:
3873 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3874 "expected 16-bit unsigned immediate");
3876 case Match_SImm16_Relaxed:
3877 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3878 "expected 16-bit signed immediate");
3879 case Match_UImm20_0:
3880 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3881 "expected 20-bit unsigned immediate");
3882 case Match_UImm26_0:
3883 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3884 "expected 26-bit unsigned immediate");
3886 case Match_SImm32_Relaxed:
3887 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3888 "expected 32-bit signed immediate");
3889 case Match_MemSImm9:
3890 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3891 "expected memory with 9-bit signed offset");
3892 case Match_MemSImm10:
3893 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3894 "expected memory with 10-bit signed offset");
3895 case Match_MemSImm10Lsl1:
3896 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3897 "expected memory with 11-bit signed offset and multiple of 2");
3898 case Match_MemSImm10Lsl2:
3899 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3900 "expected memory with 12-bit signed offset and multiple of 4");
3901 case Match_MemSImm10Lsl3:
3902 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3903 "expected memory with 13-bit signed offset and multiple of 8");
3904 case Match_MemSImm11:
3905 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3906 "expected memory with 11-bit signed offset");
3907 case Match_MemSImm12:
3908 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3909 "expected memory with 12-bit signed offset");
3910 case Match_MemSImm16:
3911 return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3912 "expected memory with 16-bit signed offset");
3915 llvm_unreachable("Implement any new match types added!");
3918 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3919 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3920 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3921 ") without \".set noat\"");
3924 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3925 if (!AssemblerOptions.back()->isMacro())
3926 Warning(Loc, "macro instruction expanded into multiple instructions");
3930 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3931 SMRange Range, bool ShowColors) {
3932 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3933 Range, SMFixIt(Range, FixMsg),
3937 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3940 CC = StringSwitch<unsigned>(Name)
3976 if (!(isABI_N32() || isABI_N64()))
3979 if (12 <= CC && CC <= 15) {
3980 // Name is one of t4-t7
3981 AsmToken RegTok = getLexer().peekTok();
3982 SMRange RegRange = RegTok.getLocRange();
3984 StringRef FixedName = StringSwitch<StringRef>(Name)
3990 assert(FixedName != "" && "Register name is not one of t4-t7.");
3992 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3993 "Did you mean $" + FixedName + "?", RegRange);
3996 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3997 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3998 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3999 if (8 <= CC && CC <= 11)
4003 CC = StringSwitch<unsigned>(Name)
4015 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
4018 CC = StringSwitch<unsigned>(Name)
4019 .Case("hwr_cpunum", 0)
4020 .Case("hwr_synci_step", 1)
4022 .Case("hwr_ccres", 3)
4023 .Case("hwr_ulr", 29)
4029 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
4031 if (Name[0] == 'f') {
4032 StringRef NumString = Name.substr(1);
4034 if (NumString.getAsInteger(10, IntVal))
4035 return -1; // This is not an integer.
4036 if (IntVal > 31) // Maximum index for fpu register.
4043 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
4045 if (Name.startswith("fcc")) {
4046 StringRef NumString = Name.substr(3);
4048 if (NumString.getAsInteger(10, IntVal))
4049 return -1; // This is not an integer.
4050 if (IntVal > 7) // There are only 8 fcc registers.
4057 int MipsAsmParser::matchACRegisterName(StringRef Name) {
4059 if (Name.startswith("ac")) {
4060 StringRef NumString = Name.substr(2);
4062 if (NumString.getAsInteger(10, IntVal))
4063 return -1; // This is not an integer.
4064 if (IntVal > 3) // There are only 3 acc registers.
4071 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
4074 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
4083 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4086 CC = StringSwitch<unsigned>(Name)
4089 .Case("msaaccess", 2)
4091 .Case("msamodify", 4)
4092 .Case("msarequest", 5)
4094 .Case("msaunmap", 7)
4100 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
4101 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
4103 reportParseError(Loc,
4104 "pseudo-instruction requires $at, which is not available");
4107 unsigned AT = getReg(
4108 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
4112 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
4113 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4116 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
4117 MCAsmParser &Parser = getParser();
4118 DEBUG(dbgs() << "parseOperand\n");
4120 // Check if the current operand has a custom associated parser, if so, try to
4121 // custom parse the operand, or fallback to the general approach.
4122 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4123 if (ResTy == MatchOperand_Success)
4125 // If there wasn't a custom match, try the generic matcher below. Otherwise,
4126 // there was a match, but an error occurred, in which case, just return that
4127 // the operand parsing failed.
4128 if (ResTy == MatchOperand_ParseFail)
4131 DEBUG(dbgs() << ".. Generic Parser\n");
4133 switch (getLexer().getKind()) {
4135 Error(Parser.getTok().getLoc(), "unexpected token in operand");
4137 case AsmToken::Dollar: {
4138 // Parse the register.
4139 SMLoc S = Parser.getTok().getLoc();
4141 // Almost all registers have been parsed by custom parsers. There is only
4142 // one exception to this. $zero (and it's alias $0) will reach this point
4143 // for div, divu, and similar instructions because it is not an operand
4144 // to the instruction definition but an explicit register. Special case
4145 // this situation for now.
4146 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
4149 // Maybe it is a symbol reference.
4150 StringRef Identifier;
4151 if (Parser.parseIdentifier(Identifier))
4154 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4155 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
4156 // Otherwise create a symbol reference.
4158 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
4160 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
4163 // Else drop to expression parsing.
4164 case AsmToken::LParen:
4165 case AsmToken::Minus:
4166 case AsmToken::Plus:
4167 case AsmToken::Integer:
4168 case AsmToken::Tilde:
4169 case AsmToken::String: {
4170 DEBUG(dbgs() << ".. generic integer\n");
4171 OperandMatchResultTy ResTy = parseImm(Operands);
4172 return ResTy != MatchOperand_Success;
4174 case AsmToken::Percent: {
4175 // It is a symbol reference or constant expression.
4176 const MCExpr *IdVal;
4177 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
4178 if (parseRelocOperand(IdVal))
4181 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4183 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4185 } // case AsmToken::Percent
4186 } // switch(getLexer().getKind())
4190 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
4191 StringRef RelocStr) {
4192 if (RelocStr == "hi(%neg(%gp_rel")
4193 return MipsMCExpr::createGpOff(MipsMCExpr::MEK_HI, Expr, getContext());
4194 else if (RelocStr == "lo(%neg(%gp_rel")
4195 return MipsMCExpr::createGpOff(MipsMCExpr::MEK_LO, Expr, getContext());
4197 MipsMCExpr::MipsExprKind Kind =
4198 StringSwitch<MipsMCExpr::MipsExprKind>(RelocStr)
4199 .Case("call16", MipsMCExpr::MEK_GOT_CALL)
4200 .Case("call_hi", MipsMCExpr::MEK_CALL_HI16)
4201 .Case("call_lo", MipsMCExpr::MEK_CALL_LO16)
4202 .Case("dtprel_hi", MipsMCExpr::MEK_DTPREL_HI)
4203 .Case("dtprel_lo", MipsMCExpr::MEK_DTPREL_LO)
4204 .Case("got", MipsMCExpr::MEK_GOT)
4205 .Case("got_disp", MipsMCExpr::MEK_GOT_DISP)
4206 .Case("got_hi", MipsMCExpr::MEK_GOT_HI16)
4207 .Case("got_lo", MipsMCExpr::MEK_GOT_LO16)
4208 .Case("got_ofst", MipsMCExpr::MEK_GOT_OFST)
4209 .Case("got_page", MipsMCExpr::MEK_GOT_PAGE)
4210 .Case("gottprel", MipsMCExpr::MEK_GOTTPREL)
4211 .Case("gp_rel", MipsMCExpr::MEK_GPREL)
4212 .Case("hi", MipsMCExpr::MEK_HI)
4213 .Case("higher", MipsMCExpr::MEK_HIGHER)
4214 .Case("highest", MipsMCExpr::MEK_HIGHEST)
4215 .Case("lo", MipsMCExpr::MEK_LO)
4216 .Case("neg", MipsMCExpr::MEK_NEG)
4217 .Case("pcrel_hi", MipsMCExpr::MEK_PCREL_HI16)
4218 .Case("pcrel_lo", MipsMCExpr::MEK_PCREL_LO16)
4219 .Case("tlsgd", MipsMCExpr::MEK_TLSGD)
4220 .Case("tlsldm", MipsMCExpr::MEK_TLSLDM)
4221 .Case("tprel_hi", MipsMCExpr::MEK_TPREL_HI)
4222 .Case("tprel_lo", MipsMCExpr::MEK_TPREL_LO)
4223 .Default(MipsMCExpr::MEK_None);
4225 assert(Kind != MipsMCExpr::MEK_None);
4226 return MipsMCExpr::create(Kind, Expr, getContext());
4229 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
4231 switch (Expr->getKind()) {
4232 case MCExpr::Constant:
4234 case MCExpr::SymbolRef:
4235 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
4236 case MCExpr::Binary:
4237 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
4238 if (!isEvaluated(BE->getLHS()))
4240 return isEvaluated(BE->getRHS());
4243 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
4244 case MCExpr::Target:
4250 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
4251 MCAsmParser &Parser = getParser();
4252 Parser.Lex(); // Eat the % token.
4253 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
4254 if (Tok.isNot(AsmToken::Identifier))
4257 std::string Str = Tok.getIdentifier();
4259 Parser.Lex(); // Eat the identifier.
4260 // Now make an expression from the rest of the operand.
4261 const MCExpr *IdVal;
4264 if (getLexer().getKind() == AsmToken::LParen) {
4266 Parser.Lex(); // Eat the '(' token.
4267 if (getLexer().getKind() == AsmToken::Percent) {
4268 Parser.Lex(); // Eat the % token.
4269 const AsmToken &nextTok = Parser.getTok();
4270 if (nextTok.isNot(AsmToken::Identifier))
4273 Str += nextTok.getIdentifier();
4274 Parser.Lex(); // Eat the identifier.
4275 if (getLexer().getKind() != AsmToken::LParen)
4280 if (getParser().parseParenExpression(IdVal, EndLoc))
4283 while (getLexer().getKind() == AsmToken::RParen)
4284 Parser.Lex(); // Eat the ')' token.
4287 return true; // Parenthesis must follow the relocation operand.
4289 Res = evaluateRelocExpr(IdVal, Str);
4293 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4295 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
4296 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
4297 if (ResTy == MatchOperand_Success) {
4298 assert(Operands.size() == 1);
4299 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
4300 StartLoc = Operand.getStartLoc();
4301 EndLoc = Operand.getEndLoc();
4303 // AFAIK, we only support numeric registers and named GPR's in CFI
4305 // Don't worry about eating tokens before failing. Using an unrecognised
4306 // register is a parse error.
4307 if (Operand.isGPRAsmReg()) {
4308 // Resolve to GPR32 or GPR64 appropriately.
4309 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
4312 return (RegNo == (unsigned)-1);
4315 assert(Operands.size() == 0);
4316 return (RegNo == (unsigned)-1);
4319 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
4320 MCAsmParser &Parser = getParser();
4323 unsigned NumOfLParen = 0;
4325 while (getLexer().getKind() == AsmToken::LParen) {
4330 switch (getLexer().getKind()) {
4333 case AsmToken::Identifier:
4334 case AsmToken::LParen:
4335 case AsmToken::Integer:
4336 case AsmToken::Minus:
4337 case AsmToken::Plus:
4339 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
4341 Result = (getParser().parseExpression(Res));
4342 while (getLexer().getKind() == AsmToken::RParen)
4345 case AsmToken::Percent:
4346 Result = parseRelocOperand(Res);
4351 MipsAsmParser::OperandMatchResultTy
4352 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
4353 MCAsmParser &Parser = getParser();
4354 DEBUG(dbgs() << "parseMemOperand\n");
4355 const MCExpr *IdVal = nullptr;
4357 bool isParenExpr = false;
4358 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
4359 // First operand is the offset.
4360 S = Parser.getTok().getLoc();
4362 if (getLexer().getKind() == AsmToken::LParen) {
4367 if (getLexer().getKind() != AsmToken::Dollar) {
4368 if (parseMemOffset(IdVal, isParenExpr))
4369 return MatchOperand_ParseFail;
4371 const AsmToken &Tok = Parser.getTok(); // Get the next token.
4372 if (Tok.isNot(AsmToken::LParen)) {
4373 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4374 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
4376 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4377 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4378 return MatchOperand_Success;
4380 if (Tok.is(AsmToken::EndOfStatement)) {
4382 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4384 // Zero register assumed, add a memory operand with ZERO as its base.
4385 // "Base" will be managed by k_Memory.
4386 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
4389 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
4390 return MatchOperand_Success;
4392 Error(Parser.getTok().getLoc(), "'(' expected");
4393 return MatchOperand_ParseFail;
4396 Parser.Lex(); // Eat the '(' token.
4399 Res = parseAnyRegister(Operands);
4400 if (Res != MatchOperand_Success)
4403 if (Parser.getTok().isNot(AsmToken::RParen)) {
4404 Error(Parser.getTok().getLoc(), "')' expected");
4405 return MatchOperand_ParseFail;
4408 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4410 Parser.Lex(); // Eat the ')' token.
4413 IdVal = MCConstantExpr::create(0, getContext());
4415 // Replace the register operand with the memory operand.
4416 std::unique_ptr<MipsOperand> op(
4417 static_cast<MipsOperand *>(Operands.back().release()));
4418 // Remove the register from the operands.
4419 // "op" will be managed by k_Memory.
4420 Operands.pop_back();
4421 // Add the memory operand.
4422 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
4424 if (IdVal->evaluateAsAbsolute(Imm))
4425 IdVal = MCConstantExpr::create(Imm, getContext());
4426 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
4427 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
4431 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4432 return MatchOperand_Success;
4435 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
4436 MCAsmParser &Parser = getParser();
4437 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
4439 SMLoc S = Parser.getTok().getLoc();
4441 if (Sym->isVariable())
4442 Expr = Sym->getVariableValue();
4445 if (Expr->getKind() == MCExpr::SymbolRef) {
4446 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4447 StringRef DefSymbol = Ref->getSymbol().getName();
4448 if (DefSymbol.startswith("$")) {
4449 OperandMatchResultTy ResTy =
4450 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
4451 if (ResTy == MatchOperand_Success) {
4454 } else if (ResTy == MatchOperand_ParseFail)
4455 llvm_unreachable("Should never ParseFail");
4463 MipsAsmParser::OperandMatchResultTy
4464 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4465 StringRef Identifier,
4467 int Index = matchCPURegisterName(Identifier);
4469 Operands.push_back(MipsOperand::createGPRReg(
4470 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4471 return MatchOperand_Success;
4474 Index = matchHWRegsRegisterName(Identifier);
4476 Operands.push_back(MipsOperand::createHWRegsReg(
4477 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4478 return MatchOperand_Success;
4481 Index = matchFPURegisterName(Identifier);
4483 Operands.push_back(MipsOperand::createFGRReg(
4484 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4485 return MatchOperand_Success;
4488 Index = matchFCCRegisterName(Identifier);
4490 Operands.push_back(MipsOperand::createFCCReg(
4491 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4492 return MatchOperand_Success;
4495 Index = matchACRegisterName(Identifier);
4497 Operands.push_back(MipsOperand::createACCReg(
4498 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4499 return MatchOperand_Success;
4502 Index = matchMSA128RegisterName(Identifier);
4504 Operands.push_back(MipsOperand::createMSA128Reg(
4505 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4506 return MatchOperand_Success;
4509 Index = matchMSA128CtrlRegisterName(Identifier);
4511 Operands.push_back(MipsOperand::createMSACtrlReg(
4512 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4513 return MatchOperand_Success;
4516 return MatchOperand_NoMatch;
4519 MipsAsmParser::OperandMatchResultTy
4520 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
4521 MCAsmParser &Parser = getParser();
4522 auto Token = Parser.getLexer().peekTok(false);
4524 if (Token.is(AsmToken::Identifier)) {
4525 DEBUG(dbgs() << ".. identifier\n");
4526 StringRef Identifier = Token.getIdentifier();
4527 OperandMatchResultTy ResTy =
4528 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
4530 } else if (Token.is(AsmToken::Integer)) {
4531 DEBUG(dbgs() << ".. integer\n");
4532 Operands.push_back(MipsOperand::createNumericReg(
4533 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
4535 return MatchOperand_Success;
4538 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
4540 return MatchOperand_NoMatch;
4543 MipsAsmParser::OperandMatchResultTy
4544 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
4545 MCAsmParser &Parser = getParser();
4546 DEBUG(dbgs() << "parseAnyRegister\n");
4548 auto Token = Parser.getTok();
4550 SMLoc S = Token.getLoc();
4552 if (Token.isNot(AsmToken::Dollar)) {
4553 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
4554 if (Token.is(AsmToken::Identifier)) {
4555 if (searchSymbolAlias(Operands))
4556 return MatchOperand_Success;
4558 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
4559 return MatchOperand_NoMatch;
4561 DEBUG(dbgs() << ".. $\n");
4563 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
4564 if (ResTy == MatchOperand_Success) {
4566 Parser.Lex(); // identifier
4571 MipsAsmParser::OperandMatchResultTy
4572 MipsAsmParser::parseImm(OperandVector &Operands) {
4573 MCAsmParser &Parser = getParser();
4574 switch (getLexer().getKind()) {
4576 return MatchOperand_NoMatch;
4577 case AsmToken::LParen:
4578 case AsmToken::Minus:
4579 case AsmToken::Plus:
4580 case AsmToken::Integer:
4581 case AsmToken::Tilde:
4582 case AsmToken::String:
4586 const MCExpr *IdVal;
4587 SMLoc S = Parser.getTok().getLoc();
4588 if (getParser().parseExpression(IdVal))
4589 return MatchOperand_ParseFail;
4591 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4592 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4593 return MatchOperand_Success;
4596 MipsAsmParser::OperandMatchResultTy
4597 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
4598 MCAsmParser &Parser = getParser();
4599 DEBUG(dbgs() << "parseJumpTarget\n");
4601 SMLoc S = getLexer().getLoc();
4603 // Integers and expressions are acceptable
4604 OperandMatchResultTy ResTy = parseImm(Operands);
4605 if (ResTy != MatchOperand_NoMatch)
4608 // Registers are a valid target and have priority over symbols.
4609 ResTy = parseAnyRegister(Operands);
4610 if (ResTy != MatchOperand_NoMatch)
4613 const MCExpr *Expr = nullptr;
4614 if (Parser.parseExpression(Expr)) {
4615 // We have no way of knowing if a symbol was consumed so we must ParseFail
4616 return MatchOperand_ParseFail;
4619 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
4620 return MatchOperand_Success;
4623 MipsAsmParser::OperandMatchResultTy
4624 MipsAsmParser::parseInvNum(OperandVector &Operands) {
4625 MCAsmParser &Parser = getParser();
4626 const MCExpr *IdVal;
4627 // If the first token is '$' we may have register operand.
4628 if (Parser.getTok().is(AsmToken::Dollar))
4629 return MatchOperand_NoMatch;
4630 SMLoc S = Parser.getTok().getLoc();
4631 if (getParser().parseExpression(IdVal))
4632 return MatchOperand_ParseFail;
4633 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
4634 assert(MCE && "Unexpected MCExpr type.");
4635 int64_t Val = MCE->getValue();
4636 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4637 Operands.push_back(MipsOperand::CreateImm(
4638 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4639 return MatchOperand_Success;
4642 MipsAsmParser::OperandMatchResultTy
4643 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
4644 MCAsmParser &Parser = getParser();
4645 SmallVector<unsigned, 10> Regs;
4647 unsigned PrevReg = Mips::NoRegister;
4648 bool RegRange = false;
4649 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4651 if (Parser.getTok().isNot(AsmToken::Dollar))
4652 return MatchOperand_ParseFail;
4654 SMLoc S = Parser.getTok().getLoc();
4655 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
4656 SMLoc E = getLexer().getLoc();
4657 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
4658 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
4660 // Remove last register operand because registers from register range
4661 // should be inserted first.
4662 if ((isGP64bit() && RegNo == Mips::RA_64) ||
4663 (!isGP64bit() && RegNo == Mips::RA)) {
4664 Regs.push_back(RegNo);
4666 unsigned TmpReg = PrevReg + 1;
4667 while (TmpReg <= RegNo) {
4668 if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4669 (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4671 Error(E, "invalid register operand");
4672 return MatchOperand_ParseFail;
4676 Regs.push_back(TmpReg++);
4682 if ((PrevReg == Mips::NoRegister) &&
4683 ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4684 (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
4685 Error(E, "$16 or $31 expected");
4686 return MatchOperand_ParseFail;
4687 } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4688 (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4690 ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4691 (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4693 Error(E, "invalid register operand");
4694 return MatchOperand_ParseFail;
4695 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4696 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4697 (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4699 Error(E, "consecutive register numbers expected");
4700 return MatchOperand_ParseFail;
4703 Regs.push_back(RegNo);
4706 if (Parser.getTok().is(AsmToken::Minus))
4709 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4710 !Parser.getTok().isNot(AsmToken::Comma)) {
4711 Error(E, "',' or '-' expected");
4712 return MatchOperand_ParseFail;
4715 Lex(); // Consume comma or minus
4716 if (Parser.getTok().isNot(AsmToken::Dollar))
4722 SMLoc E = Parser.getTok().getLoc();
4723 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4724 parseMemOperand(Operands);
4725 return MatchOperand_Success;
4728 MipsAsmParser::OperandMatchResultTy
4729 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4730 MCAsmParser &Parser = getParser();
4732 SMLoc S = Parser.getTok().getLoc();
4733 if (parseAnyRegister(Operands) != MatchOperand_Success)
4734 return MatchOperand_ParseFail;
4736 SMLoc E = Parser.getTok().getLoc();
4737 MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
4739 Operands.pop_back();
4740 Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
4741 return MatchOperand_Success;
4744 MipsAsmParser::OperandMatchResultTy
4745 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4746 MCAsmParser &Parser = getParser();
4747 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4748 SmallVector<unsigned, 10> Regs;
4750 if (Parser.getTok().isNot(AsmToken::Dollar))
4751 return MatchOperand_ParseFail;
4753 SMLoc S = Parser.getTok().getLoc();
4755 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4756 return MatchOperand_ParseFail;
4758 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4759 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4760 Regs.push_back(RegNo);
4762 SMLoc E = Parser.getTok().getLoc();
4763 if (Parser.getTok().isNot(AsmToken::Comma)) {
4764 Error(E, "',' expected");
4765 return MatchOperand_ParseFail;
4771 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4772 return MatchOperand_ParseFail;
4774 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4775 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4776 Regs.push_back(RegNo);
4778 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4780 return MatchOperand_Success;
4783 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4785 /// ::= '(', register, ')'
4786 /// handle it before we iterate so we don't get tripped up by the lack of
4788 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4789 MCAsmParser &Parser = getParser();
4790 if (getLexer().is(AsmToken::LParen)) {
4792 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4794 if (parseOperand(Operands, Name)) {
4795 SMLoc Loc = getLexer().getLoc();
4796 Parser.eatToEndOfStatement();
4797 return Error(Loc, "unexpected token in argument list");
4799 if (Parser.getTok().isNot(AsmToken::RParen)) {
4800 SMLoc Loc = getLexer().getLoc();
4801 Parser.eatToEndOfStatement();
4802 return Error(Loc, "unexpected token, expected ')'");
4805 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4811 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4812 /// either one of these.
4813 /// ::= '[', register, ']'
4814 /// ::= '[', integer, ']'
4815 /// handle it before we iterate so we don't get tripped up by the lack of
4817 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4818 OperandVector &Operands) {
4819 MCAsmParser &Parser = getParser();
4820 if (getLexer().is(AsmToken::LBrac)) {
4822 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4824 if (parseOperand(Operands, Name)) {
4825 SMLoc Loc = getLexer().getLoc();
4826 Parser.eatToEndOfStatement();
4827 return Error(Loc, "unexpected token in argument list");
4829 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4830 SMLoc Loc = getLexer().getLoc();
4831 Parser.eatToEndOfStatement();
4832 return Error(Loc, "unexpected token, expected ']'");
4835 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4841 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4842 SMLoc NameLoc, OperandVector &Operands) {
4843 MCAsmParser &Parser = getParser();
4844 DEBUG(dbgs() << "ParseInstruction\n");
4846 // We have reached first instruction, module directive are now forbidden.
4847 getTargetStreamer().forbidModuleDirective();
4849 // Check if we have valid mnemonic
4850 if (!mnemonicIsValid(Name, 0)) {
4851 Parser.eatToEndOfStatement();
4852 return Error(NameLoc, "unknown instruction");
4854 // First operand in MCInst is instruction mnemonic.
4855 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4857 // Read the remaining operands.
4858 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4859 // Read the first operand.
4860 if (parseOperand(Operands, Name)) {
4861 SMLoc Loc = getLexer().getLoc();
4862 Parser.eatToEndOfStatement();
4863 return Error(Loc, "unexpected token in argument list");
4865 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4867 // AFAIK, parenthesis suffixes are never on the first operand
4869 while (getLexer().is(AsmToken::Comma)) {
4870 Parser.Lex(); // Eat the comma.
4871 // Parse and remember the operand.
4872 if (parseOperand(Operands, Name)) {
4873 SMLoc Loc = getLexer().getLoc();
4874 Parser.eatToEndOfStatement();
4875 return Error(Loc, "unexpected token in argument list");
4877 // Parse bracket and parenthesis suffixes before we iterate
4878 if (getLexer().is(AsmToken::LBrac)) {
4879 if (parseBracketSuffix(Name, Operands))
4881 } else if (getLexer().is(AsmToken::LParen) &&
4882 parseParenSuffix(Name, Operands))
4886 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4887 SMLoc Loc = getLexer().getLoc();
4888 Parser.eatToEndOfStatement();
4889 return Error(Loc, "unexpected token in argument list");
4891 Parser.Lex(); // Consume the EndOfStatement.
4895 // FIXME: Given that these have the same name, these should both be
4896 // consistent on affecting the Parser.
4897 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4898 MCAsmParser &Parser = getParser();
4899 SMLoc Loc = getLexer().getLoc();
4900 Parser.eatToEndOfStatement();
4901 return Error(Loc, ErrorMsg);
4904 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4905 return Error(Loc, ErrorMsg);
4908 bool MipsAsmParser::parseSetNoAtDirective() {
4909 MCAsmParser &Parser = getParser();
4910 // Line should look like: ".set noat".
4912 // Set the $at register to $0.
4913 AssemblerOptions.back()->setATRegIndex(0);
4915 Parser.Lex(); // Eat "noat".
4917 // If this is not the end of the statement, report an error.
4918 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4919 reportParseError("unexpected token, expected end of statement");
4923 getTargetStreamer().emitDirectiveSetNoAt();
4924 Parser.Lex(); // Consume the EndOfStatement.
4928 bool MipsAsmParser::parseSetAtDirective() {
4929 // Line can be: ".set at", which sets $at to $1
4930 // or ".set at=$reg", which sets $at to $reg.
4931 MCAsmParser &Parser = getParser();
4932 Parser.Lex(); // Eat "at".
4934 if (getLexer().is(AsmToken::EndOfStatement)) {
4935 // No register was specified, so we set $at to $1.
4936 AssemblerOptions.back()->setATRegIndex(1);
4938 getTargetStreamer().emitDirectiveSetAt();
4939 Parser.Lex(); // Consume the EndOfStatement.
4943 if (getLexer().isNot(AsmToken::Equal)) {
4944 reportParseError("unexpected token, expected equals sign");
4947 Parser.Lex(); // Eat "=".
4949 if (getLexer().isNot(AsmToken::Dollar)) {
4950 if (getLexer().is(AsmToken::EndOfStatement)) {
4951 reportParseError("no register specified");
4954 reportParseError("unexpected token, expected dollar sign '$'");
4958 Parser.Lex(); // Eat "$".
4960 // Find out what "reg" is.
4962 const AsmToken &Reg = Parser.getTok();
4963 if (Reg.is(AsmToken::Identifier)) {
4964 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4965 } else if (Reg.is(AsmToken::Integer)) {
4966 AtRegNo = Reg.getIntVal();
4968 reportParseError("unexpected token, expected identifier or integer");
4972 // Check if $reg is a valid register. If it is, set $at to $reg.
4973 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4974 reportParseError("invalid register");
4977 Parser.Lex(); // Eat "reg".
4979 // If this is not the end of the statement, report an error.
4980 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4981 reportParseError("unexpected token, expected end of statement");
4985 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4987 Parser.Lex(); // Consume the EndOfStatement.
4991 bool MipsAsmParser::parseSetReorderDirective() {
4992 MCAsmParser &Parser = getParser();
4994 // If this is not the end of the statement, report an error.
4995 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4996 reportParseError("unexpected token, expected end of statement");
4999 AssemblerOptions.back()->setReorder();
5000 getTargetStreamer().emitDirectiveSetReorder();
5001 Parser.Lex(); // Consume the EndOfStatement.
5005 bool MipsAsmParser::parseSetNoReorderDirective() {
5006 MCAsmParser &Parser = getParser();
5008 // If this is not the end of the statement, report an error.
5009 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5010 reportParseError("unexpected token, expected end of statement");
5013 AssemblerOptions.back()->setNoReorder();
5014 getTargetStreamer().emitDirectiveSetNoReorder();
5015 Parser.Lex(); // Consume the EndOfStatement.
5019 bool MipsAsmParser::parseSetMacroDirective() {
5020 MCAsmParser &Parser = getParser();
5022 // If this is not the end of the statement, report an error.
5023 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5024 reportParseError("unexpected token, expected end of statement");
5027 AssemblerOptions.back()->setMacro();
5028 getTargetStreamer().emitDirectiveSetMacro();
5029 Parser.Lex(); // Consume the EndOfStatement.
5033 bool MipsAsmParser::parseSetNoMacroDirective() {
5034 MCAsmParser &Parser = getParser();
5036 // If this is not the end of the statement, report an error.
5037 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5038 reportParseError("unexpected token, expected end of statement");
5041 if (AssemblerOptions.back()->isReorder()) {
5042 reportParseError("`noreorder' must be set before `nomacro'");
5045 AssemblerOptions.back()->setNoMacro();
5046 getTargetStreamer().emitDirectiveSetNoMacro();
5047 Parser.Lex(); // Consume the EndOfStatement.
5051 bool MipsAsmParser::parseSetMsaDirective() {
5052 MCAsmParser &Parser = getParser();
5055 // If this is not the end of the statement, report an error.
5056 if (getLexer().isNot(AsmToken::EndOfStatement))
5057 return reportParseError("unexpected token, expected end of statement");
5059 setFeatureBits(Mips::FeatureMSA, "msa");
5060 getTargetStreamer().emitDirectiveSetMsa();
5064 bool MipsAsmParser::parseSetNoMsaDirective() {
5065 MCAsmParser &Parser = getParser();
5068 // If this is not the end of the statement, report an error.
5069 if (getLexer().isNot(AsmToken::EndOfStatement))
5070 return reportParseError("unexpected token, expected end of statement");
5072 clearFeatureBits(Mips::FeatureMSA, "msa");
5073 getTargetStreamer().emitDirectiveSetNoMsa();
5077 bool MipsAsmParser::parseSetNoDspDirective() {
5078 MCAsmParser &Parser = getParser();
5079 Parser.Lex(); // Eat "nodsp".
5081 // If this is not the end of the statement, report an error.
5082 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5083 reportParseError("unexpected token, expected end of statement");
5087 clearFeatureBits(Mips::FeatureDSP, "dsp");
5088 getTargetStreamer().emitDirectiveSetNoDsp();
5092 bool MipsAsmParser::parseSetMips16Directive() {
5093 MCAsmParser &Parser = getParser();
5094 Parser.Lex(); // Eat "mips16".
5096 // If this is not the end of the statement, report an error.
5097 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5098 reportParseError("unexpected token, expected end of statement");
5102 setFeatureBits(Mips::FeatureMips16, "mips16");
5103 getTargetStreamer().emitDirectiveSetMips16();
5104 Parser.Lex(); // Consume the EndOfStatement.
5108 bool MipsAsmParser::parseSetNoMips16Directive() {
5109 MCAsmParser &Parser = getParser();
5110 Parser.Lex(); // Eat "nomips16".
5112 // If this is not the end of the statement, report an error.
5113 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5114 reportParseError("unexpected token, expected end of statement");
5118 clearFeatureBits(Mips::FeatureMips16, "mips16");
5119 getTargetStreamer().emitDirectiveSetNoMips16();
5120 Parser.Lex(); // Consume the EndOfStatement.
5124 bool MipsAsmParser::parseSetFpDirective() {
5125 MCAsmParser &Parser = getParser();
5126 MipsABIFlagsSection::FpABIKind FpAbiVal;
5127 // Line can be: .set fp=32
5130 Parser.Lex(); // Eat fp token
5131 AsmToken Tok = Parser.getTok();
5132 if (Tok.isNot(AsmToken::Equal)) {
5133 reportParseError("unexpected token, expected equals sign '='");
5136 Parser.Lex(); // Eat '=' token.
5137 Tok = Parser.getTok();
5139 if (!parseFpABIValue(FpAbiVal, ".set"))
5142 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5143 reportParseError("unexpected token, expected end of statement");
5146 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5147 Parser.Lex(); // Consume the EndOfStatement.
5151 bool MipsAsmParser::parseSetOddSPRegDirective() {
5152 MCAsmParser &Parser = getParser();
5154 Parser.Lex(); // Eat "oddspreg".
5155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5156 reportParseError("unexpected token, expected end of statement");
5160 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5161 getTargetStreamer().emitDirectiveSetOddSPReg();
5165 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
5166 MCAsmParser &Parser = getParser();
5168 Parser.Lex(); // Eat "nooddspreg".
5169 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5170 reportParseError("unexpected token, expected end of statement");
5174 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5175 getTargetStreamer().emitDirectiveSetNoOddSPReg();
5179 bool MipsAsmParser::parseSetPopDirective() {
5180 MCAsmParser &Parser = getParser();
5181 SMLoc Loc = getLexer().getLoc();
5184 if (getLexer().isNot(AsmToken::EndOfStatement))
5185 return reportParseError("unexpected token, expected end of statement");
5187 // Always keep an element on the options "stack" to prevent the user
5188 // from changing the initial options. This is how we remember them.
5189 if (AssemblerOptions.size() == 2)
5190 return reportParseError(Loc, ".set pop with no .set push");
5192 MCSubtargetInfo &STI = copySTI();
5193 AssemblerOptions.pop_back();
5194 setAvailableFeatures(
5195 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
5196 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
5198 getTargetStreamer().emitDirectiveSetPop();
5202 bool MipsAsmParser::parseSetPushDirective() {
5203 MCAsmParser &Parser = getParser();
5205 if (getLexer().isNot(AsmToken::EndOfStatement))
5206 return reportParseError("unexpected token, expected end of statement");
5208 // Create a copy of the current assembler options environment and push it.
5209 AssemblerOptions.push_back(
5210 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
5212 getTargetStreamer().emitDirectiveSetPush();
5216 bool MipsAsmParser::parseSetSoftFloatDirective() {
5217 MCAsmParser &Parser = getParser();
5219 if (getLexer().isNot(AsmToken::EndOfStatement))
5220 return reportParseError("unexpected token, expected end of statement");
5222 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5223 getTargetStreamer().emitDirectiveSetSoftFloat();
5227 bool MipsAsmParser::parseSetHardFloatDirective() {
5228 MCAsmParser &Parser = getParser();
5230 if (getLexer().isNot(AsmToken::EndOfStatement))
5231 return reportParseError("unexpected token, expected end of statement");
5233 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5234 getTargetStreamer().emitDirectiveSetHardFloat();
5238 bool MipsAsmParser::parseSetAssignment() {
5240 const MCExpr *Value;
5241 MCAsmParser &Parser = getParser();
5243 if (Parser.parseIdentifier(Name))
5244 reportParseError("expected identifier after .set");
5246 if (getLexer().isNot(AsmToken::Comma))
5247 return reportParseError("unexpected token, expected comma");
5250 if (Parser.parseExpression(Value))
5251 return reportParseError("expected valid expression after comma");
5253 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5254 Sym->setVariableValue(Value);
5259 bool MipsAsmParser::parseSetMips0Directive() {
5260 MCAsmParser &Parser = getParser();
5262 if (getLexer().isNot(AsmToken::EndOfStatement))
5263 return reportParseError("unexpected token, expected end of statement");
5265 // Reset assembler options to their initial values.
5266 MCSubtargetInfo &STI = copySTI();
5267 setAvailableFeatures(
5268 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
5269 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
5270 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
5272 getTargetStreamer().emitDirectiveSetMips0();
5276 bool MipsAsmParser::parseSetArchDirective() {
5277 MCAsmParser &Parser = getParser();
5279 if (getLexer().isNot(AsmToken::Equal))
5280 return reportParseError("unexpected token, expected equals sign");
5284 if (Parser.parseIdentifier(Arch))
5285 return reportParseError("expected arch identifier");
5287 StringRef ArchFeatureName =
5288 StringSwitch<StringRef>(Arch)
5289 .Case("mips1", "mips1")
5290 .Case("mips2", "mips2")
5291 .Case("mips3", "mips3")
5292 .Case("mips4", "mips4")
5293 .Case("mips5", "mips5")
5294 .Case("mips32", "mips32")
5295 .Case("mips32r2", "mips32r2")
5296 .Case("mips32r3", "mips32r3")
5297 .Case("mips32r5", "mips32r5")
5298 .Case("mips32r6", "mips32r6")
5299 .Case("mips64", "mips64")
5300 .Case("mips64r2", "mips64r2")
5301 .Case("mips64r3", "mips64r3")
5302 .Case("mips64r5", "mips64r5")
5303 .Case("mips64r6", "mips64r6")
5304 .Case("octeon", "cnmips")
5305 .Case("r4000", "mips3") // This is an implementation of Mips3.
5308 if (ArchFeatureName.empty())
5309 return reportParseError("unsupported architecture");
5311 selectArch(ArchFeatureName);
5312 getTargetStreamer().emitDirectiveSetArch(Arch);
5316 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
5317 MCAsmParser &Parser = getParser();
5319 if (getLexer().isNot(AsmToken::EndOfStatement))
5320 return reportParseError("unexpected token, expected end of statement");
5324 llvm_unreachable("Unimplemented feature");
5325 case Mips::FeatureDSP:
5326 setFeatureBits(Mips::FeatureDSP, "dsp");
5327 getTargetStreamer().emitDirectiveSetDsp();
5329 case Mips::FeatureMicroMips:
5330 setFeatureBits(Mips::FeatureMicroMips, "micromips");
5331 getTargetStreamer().emitDirectiveSetMicroMips();
5333 case Mips::FeatureMips1:
5334 selectArch("mips1");
5335 getTargetStreamer().emitDirectiveSetMips1();
5337 case Mips::FeatureMips2:
5338 selectArch("mips2");
5339 getTargetStreamer().emitDirectiveSetMips2();
5341 case Mips::FeatureMips3:
5342 selectArch("mips3");
5343 getTargetStreamer().emitDirectiveSetMips3();
5345 case Mips::FeatureMips4:
5346 selectArch("mips4");
5347 getTargetStreamer().emitDirectiveSetMips4();
5349 case Mips::FeatureMips5:
5350 selectArch("mips5");
5351 getTargetStreamer().emitDirectiveSetMips5();
5353 case Mips::FeatureMips32:
5354 selectArch("mips32");
5355 getTargetStreamer().emitDirectiveSetMips32();
5357 case Mips::FeatureMips32r2:
5358 selectArch("mips32r2");
5359 getTargetStreamer().emitDirectiveSetMips32R2();
5361 case Mips::FeatureMips32r3:
5362 selectArch("mips32r3");
5363 getTargetStreamer().emitDirectiveSetMips32R3();
5365 case Mips::FeatureMips32r5:
5366 selectArch("mips32r5");
5367 getTargetStreamer().emitDirectiveSetMips32R5();
5369 case Mips::FeatureMips32r6:
5370 selectArch("mips32r6");
5371 getTargetStreamer().emitDirectiveSetMips32R6();
5373 case Mips::FeatureMips64:
5374 selectArch("mips64");
5375 getTargetStreamer().emitDirectiveSetMips64();
5377 case Mips::FeatureMips64r2:
5378 selectArch("mips64r2");
5379 getTargetStreamer().emitDirectiveSetMips64R2();
5381 case Mips::FeatureMips64r3:
5382 selectArch("mips64r3");
5383 getTargetStreamer().emitDirectiveSetMips64R3();
5385 case Mips::FeatureMips64r5:
5386 selectArch("mips64r5");
5387 getTargetStreamer().emitDirectiveSetMips64R5();
5389 case Mips::FeatureMips64r6:
5390 selectArch("mips64r6");
5391 getTargetStreamer().emitDirectiveSetMips64R6();
5397 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
5398 MCAsmParser &Parser = getParser();
5399 if (getLexer().isNot(AsmToken::Comma)) {
5400 SMLoc Loc = getLexer().getLoc();
5401 Parser.eatToEndOfStatement();
5402 return Error(Loc, ErrorStr);
5405 Parser.Lex(); // Eat the comma.
5409 // Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5410 // In this class, it is only used for .cprestore.
5411 // FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5412 // MipsTargetELFStreamer and MipsAsmParser.
5413 bool MipsAsmParser::isPicAndNotNxxAbi() {
5414 return inPicMode() && !(isABI_N32() || isABI_N64());
5417 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
5418 if (AssemblerOptions.back()->isReorder())
5419 Warning(Loc, ".cpload should be inside a noreorder section");
5421 if (inMips16Mode()) {
5422 reportParseError(".cpload is not supported in Mips16 mode");
5426 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
5427 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5428 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5429 reportParseError("expected register containing function address");
5433 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5434 if (!RegOpnd.isGPRAsmReg()) {
5435 reportParseError(RegOpnd.getStartLoc(), "invalid register");
5439 // If this is not the end of the statement, report an error.
5440 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5441 reportParseError("unexpected token, expected end of statement");
5445 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5449 bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5450 MCAsmParser &Parser = getParser();
5452 // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5453 // is used in non-PIC mode.
5455 if (inMips16Mode()) {
5456 reportParseError(".cprestore is not supported in Mips16 mode");
5460 // Get the stack offset value.
5461 const MCExpr *StackOffset;
5462 int64_t StackOffsetVal;
5463 if (Parser.parseExpression(StackOffset)) {
5464 reportParseError("expected stack offset value");
5468 if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5469 reportParseError("stack offset is not an absolute expression");
5473 if (StackOffsetVal < 0) {
5474 Warning(Loc, ".cprestore with negative stack offset has no effect");
5475 IsCpRestoreSet = false;
5477 IsCpRestoreSet = true;
5478 CpRestoreOffset = StackOffsetVal;
5481 // If this is not the end of the statement, report an error.
5482 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5483 reportParseError("unexpected token, expected end of statement");
5487 if (!getTargetStreamer().emitDirectiveCpRestore(
5488 CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
5490 Parser.Lex(); // Consume the EndOfStatement.
5494 bool MipsAsmParser::parseDirectiveCPSetup() {
5495 MCAsmParser &Parser = getParser();
5498 bool SaveIsReg = true;
5500 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5501 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5502 if (ResTy == MatchOperand_NoMatch) {
5503 reportParseError("expected register containing function address");
5507 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5508 if (!FuncRegOpnd.isGPRAsmReg()) {
5509 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5510 Parser.eatToEndOfStatement();
5514 FuncReg = FuncRegOpnd.getGPR32Reg();
5517 if (!eatComma("unexpected token, expected comma"))
5520 ResTy = parseAnyRegister(TmpReg);
5521 if (ResTy == MatchOperand_NoMatch) {
5522 const MCExpr *OffsetExpr;
5524 SMLoc ExprLoc = getLexer().getLoc();
5526 if (Parser.parseExpression(OffsetExpr) ||
5527 !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5528 reportParseError(ExprLoc, "expected save register or stack offset");
5529 Parser.eatToEndOfStatement();
5536 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5537 if (!SaveOpnd.isGPRAsmReg()) {
5538 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5539 Parser.eatToEndOfStatement();
5542 Save = SaveOpnd.getGPR32Reg();
5545 if (!eatComma("unexpected token, expected comma"))
5549 if (Parser.parseExpression(Expr)) {
5550 reportParseError("expected expression");
5554 if (Expr->getKind() != MCExpr::SymbolRef) {
5555 reportParseError("expected symbol");
5558 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5560 CpSaveLocation = Save;
5561 CpSaveLocationIsRegister = SaveIsReg;
5563 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5568 bool MipsAsmParser::parseDirectiveCPReturn() {
5569 getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5570 CpSaveLocationIsRegister);
5574 bool MipsAsmParser::parseDirectiveNaN() {
5575 MCAsmParser &Parser = getParser();
5576 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5577 const AsmToken &Tok = Parser.getTok();
5579 if (Tok.getString() == "2008") {
5581 getTargetStreamer().emitDirectiveNaN2008();
5583 } else if (Tok.getString() == "legacy") {
5585 getTargetStreamer().emitDirectiveNaNLegacy();
5589 // If we don't recognize the option passed to the .nan
5590 // directive (e.g. no option or unknown option), emit an error.
5591 reportParseError("invalid option in .nan directive");
5595 bool MipsAsmParser::parseDirectiveSet() {
5596 MCAsmParser &Parser = getParser();
5597 // Get the next token.
5598 const AsmToken &Tok = Parser.getTok();
5600 if (Tok.getString() == "noat") {
5601 return parseSetNoAtDirective();
5602 } else if (Tok.getString() == "at") {
5603 return parseSetAtDirective();
5604 } else if (Tok.getString() == "arch") {
5605 return parseSetArchDirective();
5606 } else if (Tok.getString() == "fp") {
5607 return parseSetFpDirective();
5608 } else if (Tok.getString() == "oddspreg") {
5609 return parseSetOddSPRegDirective();
5610 } else if (Tok.getString() == "nooddspreg") {
5611 return parseSetNoOddSPRegDirective();
5612 } else if (Tok.getString() == "pop") {
5613 return parseSetPopDirective();
5614 } else if (Tok.getString() == "push") {
5615 return parseSetPushDirective();
5616 } else if (Tok.getString() == "reorder") {
5617 return parseSetReorderDirective();
5618 } else if (Tok.getString() == "noreorder") {
5619 return parseSetNoReorderDirective();
5620 } else if (Tok.getString() == "macro") {
5621 return parseSetMacroDirective();
5622 } else if (Tok.getString() == "nomacro") {
5623 return parseSetNoMacroDirective();
5624 } else if (Tok.getString() == "mips16") {
5625 return parseSetMips16Directive();
5626 } else if (Tok.getString() == "nomips16") {
5627 return parseSetNoMips16Directive();
5628 } else if (Tok.getString() == "nomicromips") {
5629 clearFeatureBits(Mips::FeatureMicroMips, "micromips");
5630 getTargetStreamer().emitDirectiveSetNoMicroMips();
5631 Parser.eatToEndOfStatement();
5633 } else if (Tok.getString() == "micromips") {
5634 return parseSetFeature(Mips::FeatureMicroMips);
5635 } else if (Tok.getString() == "mips0") {
5636 return parseSetMips0Directive();
5637 } else if (Tok.getString() == "mips1") {
5638 return parseSetFeature(Mips::FeatureMips1);
5639 } else if (Tok.getString() == "mips2") {
5640 return parseSetFeature(Mips::FeatureMips2);
5641 } else if (Tok.getString() == "mips3") {
5642 return parseSetFeature(Mips::FeatureMips3);
5643 } else if (Tok.getString() == "mips4") {
5644 return parseSetFeature(Mips::FeatureMips4);
5645 } else if (Tok.getString() == "mips5") {
5646 return parseSetFeature(Mips::FeatureMips5);
5647 } else if (Tok.getString() == "mips32") {
5648 return parseSetFeature(Mips::FeatureMips32);
5649 } else if (Tok.getString() == "mips32r2") {
5650 return parseSetFeature(Mips::FeatureMips32r2);
5651 } else if (Tok.getString() == "mips32r3") {
5652 return parseSetFeature(Mips::FeatureMips32r3);
5653 } else if (Tok.getString() == "mips32r5") {
5654 return parseSetFeature(Mips::FeatureMips32r5);
5655 } else if (Tok.getString() == "mips32r6") {
5656 return parseSetFeature(Mips::FeatureMips32r6);
5657 } else if (Tok.getString() == "mips64") {
5658 return parseSetFeature(Mips::FeatureMips64);
5659 } else if (Tok.getString() == "mips64r2") {
5660 return parseSetFeature(Mips::FeatureMips64r2);
5661 } else if (Tok.getString() == "mips64r3") {
5662 return parseSetFeature(Mips::FeatureMips64r3);
5663 } else if (Tok.getString() == "mips64r5") {
5664 return parseSetFeature(Mips::FeatureMips64r5);
5665 } else if (Tok.getString() == "mips64r6") {
5666 return parseSetFeature(Mips::FeatureMips64r6);
5667 } else if (Tok.getString() == "dsp") {
5668 return parseSetFeature(Mips::FeatureDSP);
5669 } else if (Tok.getString() == "nodsp") {
5670 return parseSetNoDspDirective();
5671 } else if (Tok.getString() == "msa") {
5672 return parseSetMsaDirective();
5673 } else if (Tok.getString() == "nomsa") {
5674 return parseSetNoMsaDirective();
5675 } else if (Tok.getString() == "softfloat") {
5676 return parseSetSoftFloatDirective();
5677 } else if (Tok.getString() == "hardfloat") {
5678 return parseSetHardFloatDirective();
5680 // It is just an identifier, look for an assignment.
5681 parseSetAssignment();
5688 /// parseDataDirective
5689 /// ::= .word [ expression (, expression)* ]
5690 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
5691 MCAsmParser &Parser = getParser();
5692 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5694 const MCExpr *Value;
5695 if (getParser().parseExpression(Value))
5698 getParser().getStreamer().EmitValue(Value, Size);
5700 if (getLexer().is(AsmToken::EndOfStatement))
5703 if (getLexer().isNot(AsmToken::Comma))
5704 return Error(L, "unexpected token, expected comma");
5713 /// parseDirectiveGpWord
5714 /// ::= .gpword local_sym
5715 bool MipsAsmParser::parseDirectiveGpWord() {
5716 MCAsmParser &Parser = getParser();
5717 const MCExpr *Value;
5718 // EmitGPRel32Value requires an expression, so we are using base class
5719 // method to evaluate the expression.
5720 if (getParser().parseExpression(Value))
5722 getParser().getStreamer().EmitGPRel32Value(Value);
5724 if (getLexer().isNot(AsmToken::EndOfStatement))
5725 return Error(getLexer().getLoc(),
5726 "unexpected token, expected end of statement");
5727 Parser.Lex(); // Eat EndOfStatement token.
5731 /// parseDirectiveGpDWord
5732 /// ::= .gpdword local_sym
5733 bool MipsAsmParser::parseDirectiveGpDWord() {
5734 MCAsmParser &Parser = getParser();
5735 const MCExpr *Value;
5736 // EmitGPRel64Value requires an expression, so we are using base class
5737 // method to evaluate the expression.
5738 if (getParser().parseExpression(Value))
5740 getParser().getStreamer().EmitGPRel64Value(Value);
5742 if (getLexer().isNot(AsmToken::EndOfStatement))
5743 return Error(getLexer().getLoc(),
5744 "unexpected token, expected end of statement");
5745 Parser.Lex(); // Eat EndOfStatement token.
5749 bool MipsAsmParser::parseDirectiveOption() {
5750 MCAsmParser &Parser = getParser();
5751 // Get the option token.
5752 AsmToken Tok = Parser.getTok();
5753 // At the moment only identifiers are supported.
5754 if (Tok.isNot(AsmToken::Identifier)) {
5755 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5756 Parser.eatToEndOfStatement();
5760 StringRef Option = Tok.getIdentifier();
5762 if (Option == "pic0") {
5763 // MipsAsmParser needs to know if the current PIC mode changes.
5764 IsPicEnabled = false;
5766 getTargetStreamer().emitDirectiveOptionPic0();
5768 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5769 Error(Parser.getTok().getLoc(),
5770 "unexpected token, expected end of statement");
5771 Parser.eatToEndOfStatement();
5776 if (Option == "pic2") {
5777 // MipsAsmParser needs to know if the current PIC mode changes.
5778 IsPicEnabled = true;
5780 getTargetStreamer().emitDirectiveOptionPic2();
5782 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5783 Error(Parser.getTok().getLoc(),
5784 "unexpected token, expected end of statement");
5785 Parser.eatToEndOfStatement();
5791 Warning(Parser.getTok().getLoc(),
5792 "unknown option, expected 'pic0' or 'pic2'");
5793 Parser.eatToEndOfStatement();
5797 /// parseInsnDirective
5799 bool MipsAsmParser::parseInsnDirective() {
5800 // If this is not the end of the statement, report an error.
5801 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5802 reportParseError("unexpected token, expected end of statement");
5806 // The actual label marking happens in
5807 // MipsELFStreamer::createPendingLabelRelocs().
5808 getTargetStreamer().emitDirectiveInsn();
5810 getParser().Lex(); // Eat EndOfStatement token.
5814 /// parseSSectionDirective
5817 bool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
5818 // If this is not the end of the statement, report an error.
5819 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5820 reportParseError("unexpected token, expected end of statement");
5824 MCSection *ELFSection = getContext().getELFSection(
5825 Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
5826 getParser().getStreamer().SwitchSection(ELFSection);
5828 getParser().Lex(); // Eat EndOfStatement token.
5832 /// parseDirectiveModule
5833 /// ::= .module oddspreg
5834 /// ::= .module nooddspreg
5835 /// ::= .module fp=value
5836 /// ::= .module softfloat
5837 /// ::= .module hardfloat
5838 bool MipsAsmParser::parseDirectiveModule() {
5839 MCAsmParser &Parser = getParser();
5840 MCAsmLexer &Lexer = getLexer();
5841 SMLoc L = Lexer.getLoc();
5843 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5844 // TODO : get a better message.
5845 reportParseError(".module directive must appear before any code");
5850 if (Parser.parseIdentifier(Option)) {
5851 reportParseError("expected .module option identifier");
5855 if (Option == "oddspreg") {
5856 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5858 // Synchronize the abiflags information with the FeatureBits information we
5860 getTargetStreamer().updateABIInfo(*this);
5862 // If printing assembly, use the recently updated abiflags information.
5863 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5864 // emitted at the end).
5865 getTargetStreamer().emitDirectiveModuleOddSPReg();
5867 // If this is not the end of the statement, report an error.
5868 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5869 reportParseError("unexpected token, expected end of statement");
5873 return false; // parseDirectiveModule has finished successfully.
5874 } else if (Option == "nooddspreg") {
5876 Error(L, "'.module nooddspreg' requires the O32 ABI");
5880 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5882 // Synchronize the abiflags information with the FeatureBits information we
5884 getTargetStreamer().updateABIInfo(*this);
5886 // If printing assembly, use the recently updated abiflags information.
5887 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5888 // emitted at the end).
5889 getTargetStreamer().emitDirectiveModuleOddSPReg();
5891 // If this is not the end of the statement, report an error.
5892 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5893 reportParseError("unexpected token, expected end of statement");
5897 return false; // parseDirectiveModule has finished successfully.
5898 } else if (Option == "fp") {
5899 return parseDirectiveModuleFP();
5900 } else if (Option == "softfloat") {
5901 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5903 // Synchronize the ABI Flags information with the FeatureBits information we
5905 getTargetStreamer().updateABIInfo(*this);
5907 // If printing assembly, use the recently updated ABI Flags information.
5908 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5910 getTargetStreamer().emitDirectiveModuleSoftFloat();
5912 // If this is not the end of the statement, report an error.
5913 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5914 reportParseError("unexpected token, expected end of statement");
5918 return false; // parseDirectiveModule has finished successfully.
5919 } else if (Option == "hardfloat") {
5920 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5922 // Synchronize the ABI Flags information with the FeatureBits information we
5924 getTargetStreamer().updateABIInfo(*this);
5926 // If printing assembly, use the recently updated ABI Flags information.
5927 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5929 getTargetStreamer().emitDirectiveModuleHardFloat();
5931 // If this is not the end of the statement, report an error.
5932 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5933 reportParseError("unexpected token, expected end of statement");
5937 return false; // parseDirectiveModule has finished successfully.
5939 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5943 /// parseDirectiveModuleFP
5947 bool MipsAsmParser::parseDirectiveModuleFP() {
5948 MCAsmParser &Parser = getParser();
5949 MCAsmLexer &Lexer = getLexer();
5951 if (Lexer.isNot(AsmToken::Equal)) {
5952 reportParseError("unexpected token, expected equals sign '='");
5955 Parser.Lex(); // Eat '=' token.
5957 MipsABIFlagsSection::FpABIKind FpABI;
5958 if (!parseFpABIValue(FpABI, ".module"))
5961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5962 reportParseError("unexpected token, expected end of statement");
5966 // Synchronize the abiflags information with the FeatureBits information we
5968 getTargetStreamer().updateABIInfo(*this);
5970 // If printing assembly, use the recently updated abiflags information.
5971 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5972 // emitted at the end).
5973 getTargetStreamer().emitDirectiveModuleFP();
5975 Parser.Lex(); // Consume the EndOfStatement.
5979 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5980 StringRef Directive) {
5981 MCAsmParser &Parser = getParser();
5982 MCAsmLexer &Lexer = getLexer();
5983 bool ModuleLevelOptions = Directive == ".module";
5985 if (Lexer.is(AsmToken::Identifier)) {
5986 StringRef Value = Parser.getTok().getString();
5989 if (Value != "xx") {
5990 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5995 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5999 FpABI = MipsABIFlagsSection::FpABIKind::XX;
6000 if (ModuleLevelOptions) {
6001 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6002 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6004 setFeatureBits(Mips::FeatureFPXX, "fpxx");
6005 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6010 if (Lexer.is(AsmToken::Integer)) {
6011 unsigned Value = Parser.getTok().getIntVal();
6014 if (Value != 32 && Value != 64) {
6015 reportParseError("unsupported value, expected 'xx', '32' or '64'");
6021 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6025 FpABI = MipsABIFlagsSection::FpABIKind::S32;
6026 if (ModuleLevelOptions) {
6027 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6028 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6030 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6031 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6034 FpABI = MipsABIFlagsSection::FpABIKind::S64;
6035 if (ModuleLevelOptions) {
6036 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6037 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6039 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6040 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6050 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6051 // This returns false if this function recognizes the directive
6052 // regardless of whether it is successfully handles or reports an
6053 // error. Otherwise it returns true to give the generic parser a
6054 // chance at recognizing it.
6056 MCAsmParser &Parser = getParser();
6057 StringRef IDVal = DirectiveID.getString();
6059 if (IDVal == ".cpload") {
6060 parseDirectiveCpLoad(DirectiveID.getLoc());
6063 if (IDVal == ".cprestore") {
6064 parseDirectiveCpRestore(DirectiveID.getLoc());
6067 if (IDVal == ".dword") {
6068 parseDataDirective(8, DirectiveID.getLoc());
6071 if (IDVal == ".ent") {
6072 StringRef SymbolName;
6074 if (Parser.parseIdentifier(SymbolName)) {
6075 reportParseError("expected identifier after .ent");
6079 // There's an undocumented extension that allows an integer to
6080 // follow the name of the procedure which AFAICS is ignored by GAS.
6081 // Example: .ent foo,2
6082 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6083 if (getLexer().isNot(AsmToken::Comma)) {
6084 // Even though we accept this undocumented extension for compatibility
6085 // reasons, the additional integer argument does not actually change
6086 // the behaviour of the '.ent' directive, so we would like to discourage
6087 // its use. We do this by not referring to the extended version in
6088 // error messages which are not directly related to its use.
6089 reportParseError("unexpected token, expected end of statement");
6092 Parser.Lex(); // Eat the comma.
6093 const MCExpr *DummyNumber;
6094 int64_t DummyNumberVal;
6095 // If the user was explicitly trying to use the extended version,
6096 // we still give helpful extension-related error messages.
6097 if (Parser.parseExpression(DummyNumber)) {
6098 reportParseError("expected number after comma");
6101 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
6102 reportParseError("expected an absolute expression after comma");
6107 // If this is not the end of the statement, report an error.
6108 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6109 reportParseError("unexpected token, expected end of statement");
6113 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
6115 getTargetStreamer().emitDirectiveEnt(*Sym);
6117 IsCpRestoreSet = false;
6121 if (IDVal == ".end") {
6122 StringRef SymbolName;
6124 if (Parser.parseIdentifier(SymbolName)) {
6125 reportParseError("expected identifier after .end");
6129 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6130 reportParseError("unexpected token, expected end of statement");
6134 if (CurrentFn == nullptr) {
6135 reportParseError(".end used without .ent");
6139 if ((SymbolName != CurrentFn->getName())) {
6140 reportParseError(".end symbol does not match .ent symbol");
6144 getTargetStreamer().emitDirectiveEnd(SymbolName);
6145 CurrentFn = nullptr;
6146 IsCpRestoreSet = false;
6150 if (IDVal == ".frame") {
6151 // .frame $stack_reg, frame_size_in_bytes, $return_reg
6152 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
6153 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
6154 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6155 reportParseError("expected stack register");
6159 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6160 if (!StackRegOpnd.isGPRAsmReg()) {
6161 reportParseError(StackRegOpnd.getStartLoc(),
6162 "expected general purpose register");
6165 unsigned StackReg = StackRegOpnd.getGPR32Reg();
6167 if (Parser.getTok().is(AsmToken::Comma))
6170 reportParseError("unexpected token, expected comma");
6174 // Parse the frame size.
6175 const MCExpr *FrameSize;
6176 int64_t FrameSizeVal;
6178 if (Parser.parseExpression(FrameSize)) {
6179 reportParseError("expected frame size value");
6183 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
6184 reportParseError("frame size not an absolute expression");
6188 if (Parser.getTok().is(AsmToken::Comma))
6191 reportParseError("unexpected token, expected comma");
6195 // Parse the return register.
6197 ResTy = parseAnyRegister(TmpReg);
6198 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
6199 reportParseError("expected return register");
6203 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
6204 if (!ReturnRegOpnd.isGPRAsmReg()) {
6205 reportParseError(ReturnRegOpnd.getStartLoc(),
6206 "expected general purpose register");
6210 // If this is not the end of the statement, report an error.
6211 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6212 reportParseError("unexpected token, expected end of statement");
6216 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
6217 ReturnRegOpnd.getGPR32Reg());
6218 IsCpRestoreSet = false;
6222 if (IDVal == ".set") {
6223 parseDirectiveSet();
6227 if (IDVal == ".mask" || IDVal == ".fmask") {
6228 // .mask bitmask, frame_offset
6229 // bitmask: One bit for each register used.
6230 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
6231 // first register is expected to be saved.
6233 // .mask 0x80000000, -4
6234 // .fmask 0x80000000, -4
6237 // Parse the bitmask
6238 const MCExpr *BitMask;
6241 if (Parser.parseExpression(BitMask)) {
6242 reportParseError("expected bitmask value");
6246 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
6247 reportParseError("bitmask not an absolute expression");
6251 if (Parser.getTok().is(AsmToken::Comma))
6254 reportParseError("unexpected token, expected comma");
6258 // Parse the frame_offset
6259 const MCExpr *FrameOffset;
6260 int64_t FrameOffsetVal;
6262 if (Parser.parseExpression(FrameOffset)) {
6263 reportParseError("expected frame offset value");
6267 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
6268 reportParseError("frame offset not an absolute expression");
6272 // If this is not the end of the statement, report an error.
6273 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6274 reportParseError("unexpected token, expected end of statement");
6278 if (IDVal == ".mask")
6279 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
6281 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6285 if (IDVal == ".nan")
6286 return parseDirectiveNaN();
6288 if (IDVal == ".gpword") {
6289 parseDirectiveGpWord();
6293 if (IDVal == ".gpdword") {
6294 parseDirectiveGpDWord();
6298 if (IDVal == ".word") {
6299 parseDataDirective(4, DirectiveID.getLoc());
6303 if (IDVal == ".hword") {
6304 parseDataDirective(2, DirectiveID.getLoc());
6308 if (IDVal == ".option") {
6309 parseDirectiveOption();
6313 if (IDVal == ".abicalls") {
6314 getTargetStreamer().emitDirectiveAbiCalls();
6315 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
6316 Error(Parser.getTok().getLoc(),
6317 "unexpected token, expected end of statement");
6319 Parser.eatToEndOfStatement();
6324 if (IDVal == ".cpsetup") {
6325 parseDirectiveCPSetup();
6328 if (IDVal == ".cpreturn") {
6329 parseDirectiveCPReturn();
6332 if (IDVal == ".module") {
6333 parseDirectiveModule();
6336 if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
6337 parseInternalDirectiveReallowModule();
6340 if (IDVal == ".insn") {
6341 parseInsnDirective();
6344 if (IDVal == ".sbss") {
6345 parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
6348 if (IDVal == ".sdata") {
6349 parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
6356 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
6357 // If this is not the end of the statement, report an error.
6358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
6359 reportParseError("unexpected token, expected end of statement");
6363 getTargetStreamer().reallowModuleDirective();
6365 getParser().Lex(); // Eat EndOfStatement token.
6369 extern "C" void LLVMInitializeMipsAsmParser() {
6370 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
6371 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
6372 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
6373 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
6376 #define GET_REGISTER_MATCHER
6377 #define GET_MATCHER_IMPLEMENTATION
6378 #include "MipsGenAsmMatcher.inc"