1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
120 // Print a warning along with its fix-it message at the given range.
121 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
122 SMRange Range, bool ShowColors = true);
124 #define GET_ASSEMBLER_HEADER
125 #include "MipsGenAsmMatcher.inc"
127 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
129 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
130 OperandVector &Operands, MCStreamer &Out,
132 bool MatchingInlineAsm) override;
134 /// Parse a register as used in CFI directives
135 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
137 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
139 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
141 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
142 SMLoc NameLoc, OperandVector &Operands) override;
144 bool ParseDirective(AsmToken DirectiveID) override;
146 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
148 MipsAsmParser::OperandMatchResultTy
149 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
150 StringRef Identifier, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy
153 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
155 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
161 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
163 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterPair (OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseMovePRegPair(OperandVector &Operands);
171 MipsAsmParser::OperandMatchResultTy
172 parseRegisterList (OperandVector &Operands);
174 bool searchSymbolAlias(OperandVector &Operands);
176 bool parseOperand(OperandVector &, StringRef Mnemonic);
178 bool needsExpansion(MCInst &Inst);
180 // Expands assembly pseudo instructions.
181 // Returns false on success, true otherwise.
182 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
189 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
193 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions);
199 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
200 const MCOperand &Offset, bool Is32BitAddress,
201 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
203 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
210 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
211 SmallVectorImpl<MCInst> &Instructions);
213 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
214 SmallVectorImpl<MCInst> &Instructions);
216 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
217 SmallVectorImpl<MCInst> &Instructions);
219 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
220 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
223 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
224 SmallVectorImpl<MCInst> &Instructions);
226 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
227 SmallVectorImpl<MCInst> &Instructions);
229 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
230 SmallVectorImpl<MCInst> &Instructions);
232 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
233 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
235 bool reportParseError(Twine ErrorMsg);
236 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
238 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
239 bool parseRelocOperand(const MCExpr *&Res);
241 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
243 bool isEvaluated(const MCExpr *Expr);
244 bool parseSetMips0Directive();
245 bool parseSetArchDirective();
246 bool parseSetFeature(uint64_t Feature);
247 bool parseDirectiveCpLoad(SMLoc Loc);
248 bool parseDirectiveCPSetup();
249 bool parseDirectiveNaN();
250 bool parseDirectiveSet();
251 bool parseDirectiveOption();
252 bool parseInsnDirective();
254 bool parseSetAtDirective();
255 bool parseSetNoAtDirective();
256 bool parseSetMacroDirective();
257 bool parseSetNoMacroDirective();
258 bool parseSetMsaDirective();
259 bool parseSetNoMsaDirective();
260 bool parseSetNoDspDirective();
261 bool parseSetReorderDirective();
262 bool parseSetNoReorderDirective();
263 bool parseSetMips16Directive();
264 bool parseSetNoMips16Directive();
265 bool parseSetFpDirective();
266 bool parseSetOddSPRegDirective();
267 bool parseSetNoOddSPRegDirective();
268 bool parseSetPopDirective();
269 bool parseSetPushDirective();
270 bool parseSetSoftFloatDirective();
271 bool parseSetHardFloatDirective();
273 bool parseSetAssignment();
275 bool parseDataDirective(unsigned Size, SMLoc L);
276 bool parseDirectiveGpWord();
277 bool parseDirectiveGpDWord();
278 bool parseDirectiveModule();
279 bool parseDirectiveModuleFP();
280 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
281 StringRef Directive);
283 bool parseInternalDirectiveReallowModule();
285 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
287 bool eatComma(StringRef ErrorStr);
289 int matchCPURegisterName(StringRef Symbol);
291 int matchHWRegsRegisterName(StringRef Symbol);
293 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
295 int matchFPURegisterName(StringRef Name);
297 int matchFCCRegisterName(StringRef Name);
299 int matchACRegisterName(StringRef Name);
301 int matchMSA128RegisterName(StringRef Name);
303 int matchMSA128CtrlRegisterName(StringRef Name);
305 unsigned getReg(int RC, int RegNo);
307 unsigned getGPR(int RegNo);
309 /// Returns the internal register number for the current AT. Also checks if
310 /// the current AT is unavailable (set to $0) and gives an error if it is.
311 /// This should be used in pseudo-instruction expansions which need AT.
312 unsigned getATReg(SMLoc Loc);
314 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
315 SmallVectorImpl<MCInst> &Instructions);
317 // Helper function that checks if the value of a vector index is within the
318 // boundaries of accepted values for each RegisterKind
319 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
320 bool validateMSAIndex(int Val, int RegKind);
322 // Selects a new architecture by updating the FeatureBits with the necessary
323 // info including implied dependencies.
324 // Internally, it clears all the feature bits related to *any* architecture
325 // and selects the new one using the ToggleFeature functionality of the
326 // MCSubtargetInfo object that handles implied dependencies. The reason we
327 // clear all the arch related bits manually is because ToggleFeature only
328 // clears the features that imply the feature being cleared and not the
329 // features implied by the feature being cleared. This is easier to see
331 // --------------------------------------------------
332 // | Feature | Implies |
333 // | -------------------------------------------------|
334 // | FeatureMips1 | None |
335 // | FeatureMips2 | FeatureMips1 |
336 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
337 // | FeatureMips4 | FeatureMips3 |
339 // --------------------------------------------------
341 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
342 // FeatureMipsGP64 | FeatureMips1)
343 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
344 void selectArch(StringRef ArchFeature) {
345 FeatureBitset FeatureBits = STI.getFeatureBits();
346 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
347 STI.setFeatureBits(FeatureBits);
348 setAvailableFeatures(
349 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
350 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
353 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
354 if (!(STI.getFeatureBits()[Feature])) {
355 setAvailableFeatures(
356 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
357 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
361 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
362 if (STI.getFeatureBits()[Feature]) {
363 setAvailableFeatures(
364 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
365 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
369 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
370 setFeatureBits(Feature, FeatureString);
371 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
374 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
375 clearFeatureBits(Feature, FeatureString);
376 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
380 enum MipsMatchResultTy {
381 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
382 #define GET_OPERAND_DIAGNOSTIC_TYPES
383 #include "MipsGenAsmMatcher.inc"
384 #undef GET_OPERAND_DIAGNOSTIC_TYPES
388 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
389 const MCInstrInfo &MII, const MCTargetOptions &Options)
390 : MCTargetAsmParser(Options), STI(sti),
391 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
392 sti.getCPU(), Options)) {
393 MCAsmParserExtension::Initialize(parser);
395 parser.addAliasForDirective(".asciiz", ".asciz");
397 // Initialize the set of available features.
398 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
400 // Remember the initial assembler options. The user can not modify these.
401 AssemblerOptions.push_back(
402 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
404 // Create an assembler options environment for the user to modify.
405 AssemblerOptions.push_back(
406 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
408 getTargetStreamer().updateABIInfo(*this);
410 if (!isABI_O32() && !useOddSPReg() != 0)
411 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
416 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
418 Triple TheTriple(sti.getTargetTriple());
419 if ((TheTriple.getArch() == Triple::mips) ||
420 (TheTriple.getArch() == Triple::mips64))
421 IsLittleEndian = false;
423 IsLittleEndian = true;
426 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
427 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
429 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
430 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
431 const MipsABIInfo &getABI() const { return ABI; }
432 bool isABI_N32() const { return ABI.IsN32(); }
433 bool isABI_N64() const { return ABI.IsN64(); }
434 bool isABI_O32() const { return ABI.IsO32(); }
435 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
437 bool useOddSPReg() const {
438 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
441 bool inMicroMipsMode() const {
442 return STI.getFeatureBits()[Mips::FeatureMicroMips];
444 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
445 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
446 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
447 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
448 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
449 bool hasMips32() const {
450 return STI.getFeatureBits()[Mips::FeatureMips32];
452 bool hasMips64() const {
453 return STI.getFeatureBits()[Mips::FeatureMips64];
455 bool hasMips32r2() const {
456 return STI.getFeatureBits()[Mips::FeatureMips32r2];
458 bool hasMips64r2() const {
459 return STI.getFeatureBits()[Mips::FeatureMips64r2];
461 bool hasMips32r3() const {
462 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
464 bool hasMips64r3() const {
465 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
467 bool hasMips32r5() const {
468 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
470 bool hasMips64r5() const {
471 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
473 bool hasMips32r6() const {
474 return STI.getFeatureBits()[Mips::FeatureMips32r6];
476 bool hasMips64r6() const {
477 return STI.getFeatureBits()[Mips::FeatureMips64r6];
480 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
481 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
482 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
483 bool hasCnMips() const {
484 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
491 bool inMips16Mode() const {
492 return STI.getFeatureBits()[Mips::FeatureMips16];
495 bool useTraps() const {
496 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
499 bool useSoftFloat() const {
500 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
503 /// Warn if RegIndex is the same as the current AT.
504 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
506 void warnIfNoMacro(SMLoc Loc);
508 bool isLittle() const { return IsLittleEndian; }
514 /// MipsOperand - Instances of this class represent a parsed Mips machine
516 class MipsOperand : public MCParsedAsmOperand {
518 /// Broad categories of register classes
519 /// The exact class is finalized by the render method.
521 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
522 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
524 RegKind_FCC = 4, /// FCC
525 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
526 RegKind_MSACtrl = 16, /// MSA control registers
527 RegKind_COP2 = 32, /// COP2
528 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
530 RegKind_CCR = 128, /// CCR
531 RegKind_HWRegs = 256, /// HWRegs
532 RegKind_COP3 = 512, /// COP3
533 RegKind_COP0 = 1024, /// COP0
534 /// Potentially any (e.g. $1)
535 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
536 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
537 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
542 k_Immediate, /// An immediate (possibly involving symbol references)
543 k_Memory, /// Base + Offset Memory Address
544 k_PhysRegister, /// A physical register from the Mips namespace
545 k_RegisterIndex, /// A register index in one or more RegKind.
546 k_Token, /// A simple token
547 k_RegList, /// A physical register list
548 k_RegPair /// A pair of physical register
552 MipsOperand(KindTy K, MipsAsmParser &Parser)
553 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
556 /// For diagnostics, and checking the assembler temporary
557 MipsAsmParser &AsmParser;
565 unsigned Num; /// Register Number
569 unsigned Index; /// Index into the register class
570 RegKind Kind; /// Bitfield of the kinds it could possibly be
571 const MCRegisterInfo *RegInfo;
584 SmallVector<unsigned, 10> *List;
589 struct PhysRegOp PhysReg;
590 struct RegIdxOp RegIdx;
593 struct RegListOp RegList;
596 SMLoc StartLoc, EndLoc;
598 /// Internal constructor for register kinds
599 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
600 const MCRegisterInfo *RegInfo,
602 MipsAsmParser &Parser) {
603 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
604 Op->RegIdx.Index = Index;
605 Op->RegIdx.RegInfo = RegInfo;
606 Op->RegIdx.Kind = RegKind;
613 /// Coerce the register to GPR32 and return the real register for the current
615 unsigned getGPR32Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
617 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
618 unsigned ClassID = Mips::GPR32RegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
622 /// Coerce the register to GPR32 and return the real register for the current
624 unsigned getGPRMM16Reg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
626 unsigned ClassID = Mips::GPR32RegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 /// Coerce the register to GPR64 and return the real register for the current
632 unsigned getGPR64Reg() const {
633 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
634 unsigned ClassID = Mips::GPR64RegClassID;
635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 /// Coerce the register to AFGR64 and return the real register for the current
641 unsigned getAFGR64Reg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
643 if (RegIdx.Index % 2 != 0)
644 AsmParser.Warning(StartLoc, "Float register should be even.");
645 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
646 .getRegister(RegIdx.Index / 2);
649 /// Coerce the register to FGR64 and return the real register for the current
651 unsigned getFGR64Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
653 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
654 .getRegister(RegIdx.Index);
657 /// Coerce the register to FGR32 and return the real register for the current
659 unsigned getFGR32Reg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
661 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
662 .getRegister(RegIdx.Index);
665 /// Coerce the register to FGRH32 and return the real register for the current
667 unsigned getFGRH32Reg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
669 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
670 .getRegister(RegIdx.Index);
673 /// Coerce the register to FCC and return the real register for the current
675 unsigned getFCCReg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
677 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
678 .getRegister(RegIdx.Index);
681 /// Coerce the register to MSA128 and return the real register for the current
683 unsigned getMSA128Reg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
685 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
687 unsigned ClassID = Mips::MSA128BRegClassID;
688 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
691 /// Coerce the register to MSACtrl and return the real register for the
693 unsigned getMSACtrlReg() const {
694 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
695 unsigned ClassID = Mips::MSACtrlRegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
699 /// Coerce the register to COP0 and return the real register for the
701 unsigned getCOP0Reg() const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
703 unsigned ClassID = Mips::COP0RegClassID;
704 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
707 /// Coerce the register to COP2 and return the real register for the
709 unsigned getCOP2Reg() const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
711 unsigned ClassID = Mips::COP2RegClassID;
712 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
715 /// Coerce the register to COP3 and return the real register for the
717 unsigned getCOP3Reg() const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
719 unsigned ClassID = Mips::COP3RegClassID;
720 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
723 /// Coerce the register to ACC64DSP and return the real register for the
725 unsigned getACC64DSPReg() const {
726 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
727 unsigned ClassID = Mips::ACC64DSPRegClassID;
728 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
731 /// Coerce the register to HI32DSP and return the real register for the
733 unsigned getHI32DSPReg() const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
735 unsigned ClassID = Mips::HI32DSPRegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 /// Coerce the register to LO32DSP and return the real register for the
741 unsigned getLO32DSPReg() const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
743 unsigned ClassID = Mips::LO32DSPRegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
747 /// Coerce the register to CCR and return the real register for the
749 unsigned getCCRReg() const {
750 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
751 unsigned ClassID = Mips::CCRRegClassID;
752 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
755 /// Coerce the register to HWRegs and return the real register for the
757 unsigned getHWRegsReg() const {
758 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
759 unsigned ClassID = Mips::HWRegsRegClassID;
760 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
764 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
765 // Add as immediate when possible. Null MCExpr = 0.
767 Inst.addOperand(MCOperand::createImm(0));
768 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
769 Inst.addOperand(MCOperand::createImm(CE->getValue()));
771 Inst.addOperand(MCOperand::createExpr(Expr));
774 void addRegOperands(MCInst &Inst, unsigned N) const {
775 llvm_unreachable("Use a custom parser instead");
778 /// Render the operand to an MCInst as a GPR32
779 /// Asserts if the wrong number of operands are requested, or the operand
780 /// is not a k_RegisterIndex compatible with RegKind_GPR
781 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
782 assert(N == 1 && "Invalid number of operands!");
783 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
786 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
787 assert(N == 1 && "Invalid number of operands!");
788 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
791 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
796 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
801 /// Render the operand to an MCInst as a GPR64
802 /// Asserts if the wrong number of operands are requested, or the operand
803 /// is not a k_RegisterIndex compatible with RegKind_GPR
804 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
809 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
810 assert(N == 1 && "Invalid number of operands!");
811 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
814 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
815 assert(N == 1 && "Invalid number of operands!");
816 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
819 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 1 && "Invalid number of operands!");
821 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
822 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
823 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
824 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
828 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
830 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
833 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
834 assert(N == 1 && "Invalid number of operands!");
835 Inst.addOperand(MCOperand::createReg(getFCCReg()));
838 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 1 && "Invalid number of operands!");
840 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
843 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 1 && "Invalid number of operands!");
845 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
848 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
849 assert(N == 1 && "Invalid number of operands!");
850 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
853 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
854 assert(N == 1 && "Invalid number of operands!");
855 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
858 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
859 assert(N == 1 && "Invalid number of operands!");
860 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
863 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
864 assert(N == 1 && "Invalid number of operands!");
865 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
868 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
869 assert(N == 1 && "Invalid number of operands!");
870 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
873 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
874 assert(N == 1 && "Invalid number of operands!");
875 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
878 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
879 assert(N == 1 && "Invalid number of operands!");
880 Inst.addOperand(MCOperand::createReg(getCCRReg()));
883 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
884 assert(N == 1 && "Invalid number of operands!");
885 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
888 void addImmOperands(MCInst &Inst, unsigned N) const {
889 assert(N == 1 && "Invalid number of operands!");
890 const MCExpr *Expr = getImm();
894 void addMemOperands(MCInst &Inst, unsigned N) const {
895 assert(N == 2 && "Invalid number of operands!");
897 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
898 ? getMemBase()->getGPR64Reg()
899 : getMemBase()->getGPR32Reg()));
901 const MCExpr *Expr = getMemOff();
905 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
906 assert(N == 2 && "Invalid number of operands!");
908 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
910 const MCExpr *Expr = getMemOff();
914 void addRegListOperands(MCInst &Inst, unsigned N) const {
915 assert(N == 1 && "Invalid number of operands!");
917 for (auto RegNo : getRegList())
918 Inst.addOperand(MCOperand::createReg(RegNo));
921 void addRegPairOperands(MCInst &Inst, unsigned N) const {
922 assert(N == 2 && "Invalid number of operands!");
923 unsigned RegNo = getRegPair();
924 Inst.addOperand(MCOperand::createReg(RegNo++));
925 Inst.addOperand(MCOperand::createReg(RegNo));
928 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
929 assert(N == 2 && "Invalid number of operands!");
930 for (auto RegNo : getRegList())
931 Inst.addOperand(MCOperand::createReg(RegNo));
934 bool isReg() const override {
935 // As a special case until we sort out the definition of div/divu, pretend
936 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
937 if (isGPRAsmReg() && RegIdx.Index == 0)
940 return Kind == k_PhysRegister;
942 bool isRegIdx() const { return Kind == k_RegisterIndex; }
943 bool isImm() const override { return Kind == k_Immediate; }
944 bool isConstantImm() const {
945 return isImm() && dyn_cast<MCConstantExpr>(getImm());
947 template <unsigned Bits> bool isUImm() const {
948 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
950 bool isToken() const override {
951 // Note: It's not possible to pretend that other operand kinds are tokens.
952 // The matcher emitter checks tokens first.
953 return Kind == k_Token;
955 bool isMem() const override { return Kind == k_Memory; }
956 bool isConstantMemOff() const {
957 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
959 template <unsigned Bits> bool isMemWithSimmOffset() const {
960 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
962 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
963 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
964 && getMemBase()->isGPRAsmReg();
966 bool isMemWithGRPMM16Base() const {
967 return isMem() && getMemBase()->isMM16AsmReg();
969 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
970 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
971 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
973 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
974 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
975 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
976 && (getMemBase()->getGPR32Reg() == Mips::SP);
978 bool isRegList16() const {
982 int Size = RegList.List->size();
983 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
984 RegList.List->back() != Mips::RA)
987 int PrevReg = *RegList.List->begin();
988 for (int i = 1; i < Size - 1; i++) {
989 int Reg = (*(RegList.List))[i];
990 if ( Reg != PrevReg + 1)
997 bool isInvNum() const { return Kind == k_Immediate; }
998 bool isLSAImm() const {
999 if (!isConstantImm())
1001 int64_t Val = getConstantImm();
1002 return 1 <= Val && Val <= 4;
1004 bool isRegList() const { return Kind == k_RegList; }
1005 bool isMovePRegPair() const {
1006 if (Kind != k_RegList || RegList.List->size() != 2)
1009 unsigned R0 = RegList.List->front();
1010 unsigned R1 = RegList.List->back();
1012 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1013 (R0 == Mips::A1 && R1 == Mips::A3) ||
1014 (R0 == Mips::A2 && R1 == Mips::A3) ||
1015 (R0 == Mips::A0 && R1 == Mips::S5) ||
1016 (R0 == Mips::A0 && R1 == Mips::S6) ||
1017 (R0 == Mips::A0 && R1 == Mips::A1) ||
1018 (R0 == Mips::A0 && R1 == Mips::A2) ||
1019 (R0 == Mips::A0 && R1 == Mips::A3))
1025 StringRef getToken() const {
1026 assert(Kind == k_Token && "Invalid access!");
1027 return StringRef(Tok.Data, Tok.Length);
1029 bool isRegPair() const { return Kind == k_RegPair; }
1031 unsigned getReg() const override {
1032 // As a special case until we sort out the definition of div/divu, pretend
1033 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1034 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1035 RegIdx.Kind & RegKind_GPR)
1036 return getGPR32Reg(); // FIXME: GPR64 too
1038 assert(Kind == k_PhysRegister && "Invalid access!");
1042 const MCExpr *getImm() const {
1043 assert((Kind == k_Immediate) && "Invalid access!");
1047 int64_t getConstantImm() const {
1048 const MCExpr *Val = getImm();
1049 return static_cast<const MCConstantExpr *>(Val)->getValue();
1052 MipsOperand *getMemBase() const {
1053 assert((Kind == k_Memory) && "Invalid access!");
1057 const MCExpr *getMemOff() const {
1058 assert((Kind == k_Memory) && "Invalid access!");
1062 int64_t getConstantMemOff() const {
1063 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1066 const SmallVectorImpl<unsigned> &getRegList() const {
1067 assert((Kind == k_RegList) && "Invalid access!");
1068 return *(RegList.List);
1071 unsigned getRegPair() const {
1072 assert((Kind == k_RegPair) && "Invalid access!");
1073 return RegIdx.Index;
1076 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1077 MipsAsmParser &Parser) {
1078 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1079 Op->Tok.Data = Str.data();
1080 Op->Tok.Length = Str.size();
1086 /// Create a numeric register (e.g. $1). The exact register remains
1087 /// unresolved until an instruction successfully matches
1088 static std::unique_ptr<MipsOperand>
1089 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1090 SMLoc E, MipsAsmParser &Parser) {
1091 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1092 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1095 /// Create a register that is definitely a GPR.
1096 /// This is typically only used for named registers such as $gp.
1097 static std::unique_ptr<MipsOperand>
1098 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1099 MipsAsmParser &Parser) {
1100 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1103 /// Create a register that is definitely a FGR.
1104 /// This is typically only used for named registers such as $f0.
1105 static std::unique_ptr<MipsOperand>
1106 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1107 MipsAsmParser &Parser) {
1108 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1111 /// Create a register that is definitely a HWReg.
1112 /// This is typically only used for named registers such as $hwr_cpunum.
1113 static std::unique_ptr<MipsOperand>
1114 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1115 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1116 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1119 /// Create a register that is definitely an FCC.
1120 /// This is typically only used for named registers such as $fcc0.
1121 static std::unique_ptr<MipsOperand>
1122 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1123 MipsAsmParser &Parser) {
1124 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1127 /// Create a register that is definitely an ACC.
1128 /// This is typically only used for named registers such as $ac0.
1129 static std::unique_ptr<MipsOperand>
1130 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1131 MipsAsmParser &Parser) {
1132 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1135 /// Create a register that is definitely an MSA128.
1136 /// This is typically only used for named registers such as $w0.
1137 static std::unique_ptr<MipsOperand>
1138 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1139 SMLoc E, MipsAsmParser &Parser) {
1140 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1143 /// Create a register that is definitely an MSACtrl.
1144 /// This is typically only used for named registers such as $msaaccess.
1145 static std::unique_ptr<MipsOperand>
1146 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1147 SMLoc E, MipsAsmParser &Parser) {
1148 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1151 static std::unique_ptr<MipsOperand>
1152 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1153 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1160 static std::unique_ptr<MipsOperand>
1161 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1162 SMLoc E, MipsAsmParser &Parser) {
1163 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1164 Op->Mem.Base = Base.release();
1171 static std::unique_ptr<MipsOperand>
1172 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1173 MipsAsmParser &Parser) {
1174 assert (Regs.size() > 0 && "Empty list not allowed");
1176 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1177 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1178 Op->StartLoc = StartLoc;
1179 Op->EndLoc = EndLoc;
1183 static std::unique_ptr<MipsOperand>
1184 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1185 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1186 Op->RegIdx.Index = RegNo;
1192 bool isGPRAsmReg() const {
1193 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1195 bool isMM16AsmReg() const {
1196 if (!(isRegIdx() && RegIdx.Kind))
1198 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1199 || RegIdx.Index == 16 || RegIdx.Index == 17);
1201 bool isMM16AsmRegZero() const {
1202 if (!(isRegIdx() && RegIdx.Kind))
1204 return (RegIdx.Index == 0 ||
1205 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1206 RegIdx.Index == 17);
1208 bool isMM16AsmRegMoveP() const {
1209 if (!(isRegIdx() && RegIdx.Kind))
1211 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1212 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1214 bool isFGRAsmReg() const {
1215 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1216 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1218 bool isHWRegsAsmReg() const {
1219 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1221 bool isCCRAsmReg() const {
1222 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1224 bool isFCCAsmReg() const {
1225 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1227 if (!AsmParser.hasEightFccRegisters())
1228 return RegIdx.Index == 0;
1229 return RegIdx.Index <= 7;
1231 bool isACCAsmReg() const {
1232 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1234 bool isCOP0AsmReg() const {
1235 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1237 bool isCOP2AsmReg() const {
1238 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1240 bool isCOP3AsmReg() const {
1241 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1243 bool isMSA128AsmReg() const {
1244 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1246 bool isMSACtrlAsmReg() const {
1247 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1250 /// getStartLoc - Get the location of the first token of this operand.
1251 SMLoc getStartLoc() const override { return StartLoc; }
1252 /// getEndLoc - Get the location of the last token of this operand.
1253 SMLoc getEndLoc() const override { return EndLoc; }
1255 virtual ~MipsOperand() {
1263 delete RegList.List;
1264 case k_PhysRegister:
1265 case k_RegisterIndex:
1272 void print(raw_ostream &OS) const override {
1281 Mem.Base->print(OS);
1286 case k_PhysRegister:
1287 OS << "PhysReg<" << PhysReg.Num << ">";
1289 case k_RegisterIndex:
1290 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1297 for (auto Reg : (*RegList.List))
1302 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1306 }; // class MipsOperand
1310 extern const MCInstrDesc MipsInsts[];
1312 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1313 return MipsInsts[Opcode];
1316 static bool hasShortDelaySlot(unsigned Opcode) {
1319 case Mips::JALRS_MM:
1320 case Mips::JALRS16_MM:
1321 case Mips::BGEZALS_MM:
1322 case Mips::BLTZALS_MM:
1329 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1330 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1331 return &SRExpr->getSymbol();
1334 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1335 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1336 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1347 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1348 return getSingleMCSymbol(UExpr->getSubExpr());
1353 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1354 if (isa<MCSymbolRefExpr>(Expr))
1357 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1358 return countMCSymbolRefExpr(BExpr->getLHS()) +
1359 countMCSymbolRefExpr(BExpr->getRHS());
1361 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1362 return countMCSymbolRefExpr(UExpr->getSubExpr());
1367 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1368 SmallVectorImpl<MCInst> &Instructions) {
1369 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1373 if (MCID.isBranch() || MCID.isCall()) {
1374 const unsigned Opcode = Inst.getOpcode();
1384 assert(hasCnMips() && "instruction only valid for octeon cpus");
1391 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1392 Offset = Inst.getOperand(2);
1393 if (!Offset.isImm())
1394 break; // We'll deal with this situation later on when applying fixups.
1395 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1396 return Error(IDLoc, "branch target out of range");
1397 if (OffsetToAlignment(Offset.getImm(),
1398 1LL << (inMicroMipsMode() ? 1 : 2)))
1399 return Error(IDLoc, "branch to misaligned address");
1413 case Mips::BGEZAL_MM:
1414 case Mips::BLTZAL_MM:
1417 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1418 Offset = Inst.getOperand(1);
1419 if (!Offset.isImm())
1420 break; // We'll deal with this situation later on when applying fixups.
1421 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1422 return Error(IDLoc, "branch target out of range");
1423 if (OffsetToAlignment(Offset.getImm(),
1424 1LL << (inMicroMipsMode() ? 1 : 2)))
1425 return Error(IDLoc, "branch to misaligned address");
1427 case Mips::BEQZ16_MM:
1428 case Mips::BEQZC16_MMR6:
1429 case Mips::BNEZ16_MM:
1430 case Mips::BNEZC16_MMR6:
1431 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1432 Offset = Inst.getOperand(1);
1433 if (!Offset.isImm())
1434 break; // We'll deal with this situation later on when applying fixups.
1435 if (!isIntN(8, Offset.getImm()))
1436 return Error(IDLoc, "branch target out of range");
1437 if (OffsetToAlignment(Offset.getImm(), 2LL))
1438 return Error(IDLoc, "branch to misaligned address");
1443 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1444 // We still accept it but it is a normal nop.
1445 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1446 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1447 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1452 const unsigned Opcode = Inst.getOpcode();
1464 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1465 // The offset is handled above
1466 Opnd = Inst.getOperand(1);
1468 return Error(IDLoc, "expected immediate operand kind");
1469 Imm = Opnd.getImm();
1470 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1471 Opcode == Mips::BBIT1 ? 63 : 31))
1472 return Error(IDLoc, "immediate operand value out of range");
1474 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1476 Inst.getOperand(1).setImm(Imm - 32);
1484 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1486 Opnd = Inst.getOperand(3);
1488 return Error(IDLoc, "expected immediate operand kind");
1489 Imm = Opnd.getImm();
1490 if (Imm < 0 || Imm > 31)
1491 return Error(IDLoc, "immediate operand value out of range");
1493 Opnd = Inst.getOperand(2);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1498 Opcode == Mips::EXTS ? 63 : 31))
1499 return Error(IDLoc, "immediate operand value out of range");
1501 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1502 Inst.getOperand(2).setImm(Imm - 32);
1508 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1509 Opnd = Inst.getOperand(2);
1511 return Error(IDLoc, "expected immediate operand kind");
1512 Imm = Opnd.getImm();
1513 if (!isInt<10>(Imm))
1514 return Error(IDLoc, "immediate operand value out of range");
1519 // This expansion is not in a function called by expandInstruction() because
1520 // the pseudo-instruction doesn't have a distinct opcode.
1521 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1523 warnIfNoMacro(IDLoc);
1525 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1527 // We can do this expansion if there's only 1 symbol in the argument
1529 if (countMCSymbolRefExpr(JalExpr) > 1)
1530 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1532 // FIXME: This is checking the expression can be handled by the later stages
1533 // of the assembler. We ought to leave it to those later stages but
1534 // we can't do that until we stop evaluateRelocExpr() rewriting the
1535 // expressions into non-equivalent forms.
1536 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1538 // FIXME: Add support for label+offset operands (currently causes an error).
1539 // FIXME: Add support for forward-declared local symbols.
1540 // FIXME: Add expansion for when the LargeGOT option is enabled.
1541 if (JalSym->isInSection() || JalSym->isTemporary()) {
1543 // If it's a local symbol and the O32 ABI is being used, we expand to:
1545 // R_(MICRO)MIPS_GOT16 label
1546 // addiu $25, $25, 0
1547 // R_(MICRO)MIPS_LO16 label
1549 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1550 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1553 LwInst.setOpcode(Mips::LW);
1554 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1555 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1556 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1557 Instructions.push_back(LwInst);
1560 AddiuInst.setOpcode(Mips::ADDiu);
1561 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1562 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1563 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1564 Instructions.push_back(AddiuInst);
1565 } else if (isABI_N32() || isABI_N64()) {
1566 // If it's a local symbol and the N32/N64 ABIs are being used,
1568 // lw/ld $25, 0($gp)
1569 // R_(MICRO)MIPS_GOT_DISP label
1571 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1574 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1575 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1576 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1577 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1578 Instructions.push_back(LoadInst);
1581 // If it's an external/weak symbol, we expand to:
1582 // lw/ld $25, 0($gp)
1583 // R_(MICRO)MIPS_CALL16 label
1585 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1588 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1589 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1590 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1591 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1592 Instructions.push_back(LoadInst);
1596 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1597 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1598 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1600 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1601 // This relocation is supposed to be an optimization hint for the linker
1602 // and is not necessary for correctness.
1607 if (MCID.mayLoad() || MCID.mayStore()) {
1608 // Check the offset of memory operand, if it is a symbol
1609 // reference or immediate we may have to expand instructions.
1610 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1611 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1612 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1613 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1614 MCOperand &Op = Inst.getOperand(i);
1616 int MemOffset = Op.getImm();
1617 if (MemOffset < -32768 || MemOffset > 32767) {
1618 // Offset can't exceed 16bit value.
1619 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1622 } else if (Op.isExpr()) {
1623 const MCExpr *Expr = Op.getExpr();
1624 if (Expr->getKind() == MCExpr::SymbolRef) {
1625 const MCSymbolRefExpr *SR =
1626 static_cast<const MCSymbolRefExpr *>(Expr);
1627 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1629 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1632 } else if (!isEvaluated(Expr)) {
1633 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1641 if (inMicroMipsMode()) {
1642 if (MCID.mayLoad()) {
1643 // Try to create 16-bit GP relative load instruction.
1644 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1645 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1646 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1647 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1648 MCOperand &Op = Inst.getOperand(i);
1650 int MemOffset = Op.getImm();
1651 MCOperand &DstReg = Inst.getOperand(0);
1652 MCOperand &BaseReg = Inst.getOperand(1);
1653 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1654 getContext().getRegisterInfo()->getRegClass(
1655 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1656 BaseReg.getReg() == Mips::GP) {
1658 TmpInst.setLoc(IDLoc);
1659 TmpInst.setOpcode(Mips::LWGP_MM);
1660 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1661 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1662 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1663 Instructions.push_back(TmpInst);
1671 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1676 switch (Inst.getOpcode()) {
1679 case Mips::ADDIUS5_MM:
1680 Opnd = Inst.getOperand(2);
1682 return Error(IDLoc, "expected immediate operand kind");
1683 Imm = Opnd.getImm();
1684 if (Imm < -8 || Imm > 7)
1685 return Error(IDLoc, "immediate operand value out of range");
1687 case Mips::ADDIUSP_MM:
1688 Opnd = Inst.getOperand(0);
1690 return Error(IDLoc, "expected immediate operand kind");
1691 Imm = Opnd.getImm();
1692 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1694 return Error(IDLoc, "immediate operand value out of range");
1696 case Mips::SLL16_MM:
1697 case Mips::SRL16_MM:
1698 Opnd = Inst.getOperand(2);
1700 return Error(IDLoc, "expected immediate operand kind");
1701 Imm = Opnd.getImm();
1702 if (Imm < 1 || Imm > 8)
1703 return Error(IDLoc, "immediate operand value out of range");
1706 Opnd = Inst.getOperand(1);
1708 return Error(IDLoc, "expected immediate operand kind");
1709 Imm = Opnd.getImm();
1710 if (Imm < -1 || Imm > 126)
1711 return Error(IDLoc, "immediate operand value out of range");
1713 case Mips::ADDIUR2_MM:
1714 Opnd = Inst.getOperand(2);
1716 return Error(IDLoc, "expected immediate operand kind");
1717 Imm = Opnd.getImm();
1718 if (!(Imm == 1 || Imm == -1 ||
1719 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1720 return Error(IDLoc, "immediate operand value out of range");
1722 case Mips::ADDIUR1SP_MM:
1723 Opnd = Inst.getOperand(1);
1725 return Error(IDLoc, "expected immediate operand kind");
1726 Imm = Opnd.getImm();
1727 if (OffsetToAlignment(Imm, 4LL))
1728 return Error(IDLoc, "misaligned immediate operand value");
1729 if (Imm < 0 || Imm > 255)
1730 return Error(IDLoc, "immediate operand value out of range");
1732 case Mips::ANDI16_MM:
1733 Opnd = Inst.getOperand(2);
1735 return Error(IDLoc, "expected immediate operand kind");
1736 Imm = Opnd.getImm();
1737 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1738 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1739 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1740 return Error(IDLoc, "immediate operand value out of range");
1742 case Mips::LBU16_MM:
1743 Opnd = Inst.getOperand(2);
1745 return Error(IDLoc, "expected immediate operand kind");
1746 Imm = Opnd.getImm();
1747 if (Imm < -1 || Imm > 14)
1748 return Error(IDLoc, "immediate operand value out of range");
1751 Opnd = Inst.getOperand(2);
1753 return Error(IDLoc, "expected immediate operand kind");
1754 Imm = Opnd.getImm();
1755 if (Imm < 0 || Imm > 15)
1756 return Error(IDLoc, "immediate operand value out of range");
1758 case Mips::LHU16_MM:
1760 Opnd = Inst.getOperand(2);
1762 return Error(IDLoc, "expected immediate operand kind");
1763 Imm = Opnd.getImm();
1764 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1765 return Error(IDLoc, "immediate operand value out of range");
1769 Opnd = Inst.getOperand(2);
1771 return Error(IDLoc, "expected immediate operand kind");
1772 Imm = Opnd.getImm();
1773 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1774 return Error(IDLoc, "immediate operand value out of range");
1778 Opnd = Inst.getOperand(2);
1780 return Error(IDLoc, "expected immediate operand kind");
1781 Imm = Opnd.getImm();
1782 if (!isUInt<5>(Imm))
1783 return Error(IDLoc, "immediate operand value out of range");
1785 case Mips::ADDIUPC_MM:
1786 MCOperand Opnd = Inst.getOperand(1);
1788 return Error(IDLoc, "expected immediate operand kind");
1789 int Imm = Opnd.getImm();
1790 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1791 return Error(IDLoc, "immediate operand value out of range");
1796 if (needsExpansion(Inst)) {
1797 if (expandInstruction(Inst, IDLoc, Instructions))
1800 Instructions.push_back(Inst);
1802 // If this instruction has a delay slot and .set reorder is active,
1803 // emit a NOP after it.
1804 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1805 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1810 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1812 switch (Inst.getOpcode()) {
1813 case Mips::LoadImm32:
1814 case Mips::LoadImm64:
1815 case Mips::LoadAddrImm32:
1816 case Mips::LoadAddrImm64:
1817 case Mips::LoadAddrReg32:
1818 case Mips::LoadAddrReg64:
1819 case Mips::B_MM_Pseudo:
1820 case Mips::B_MMR6_Pseudo:
1823 case Mips::JalOneReg:
1824 case Mips::JalTwoReg:
1835 case Mips::SDivMacro:
1836 case Mips::UDivMacro:
1837 case Mips::DSDivMacro:
1838 case Mips::DUDivMacro:
1847 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1848 SmallVectorImpl<MCInst> &Instructions) {
1849 switch (Inst.getOpcode()) {
1850 default: llvm_unreachable("unimplemented expansion");
1851 case Mips::LoadImm32:
1852 return expandLoadImm(Inst, true, IDLoc, Instructions);
1853 case Mips::LoadImm64:
1854 return expandLoadImm(Inst, false, IDLoc, Instructions);
1855 case Mips::LoadAddrImm32:
1856 case Mips::LoadAddrImm64:
1857 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1858 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1859 "expected immediate operand kind");
1861 return expandLoadAddress(
1862 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1863 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1864 case Mips::LoadAddrReg32:
1865 case Mips::LoadAddrReg64:
1866 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1867 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1868 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1869 "expected immediate operand kind");
1871 return expandLoadAddress(
1872 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1873 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1874 case Mips::B_MM_Pseudo:
1875 case Mips::B_MMR6_Pseudo:
1876 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1879 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1880 case Mips::JalOneReg:
1881 case Mips::JalTwoReg:
1882 return expandJalWithRegs(Inst, IDLoc, Instructions);
1885 return expandBranchImm(Inst, IDLoc, Instructions);
1894 return expandCondBranches(Inst, IDLoc, Instructions);
1895 case Mips::SDivMacro:
1896 return expandDiv(Inst, IDLoc, Instructions, false, true);
1897 case Mips::DSDivMacro:
1898 return expandDiv(Inst, IDLoc, Instructions, true, true);
1899 case Mips::UDivMacro:
1900 return expandDiv(Inst, IDLoc, Instructions, false, false);
1901 case Mips::DUDivMacro:
1902 return expandDiv(Inst, IDLoc, Instructions, true, false);
1904 return expandUlhu(Inst, IDLoc, Instructions);
1906 return expandUlw(Inst, IDLoc, Instructions);
1911 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1912 SmallVectorImpl<MCInst> &Instructions) {
1914 tmpInst.setOpcode(Opcode);
1915 tmpInst.addOperand(MCOperand::createReg(Reg0));
1916 tmpInst.addOperand(Op1);
1917 tmpInst.setLoc(IDLoc);
1918 Instructions.push_back(tmpInst);
1921 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1922 SmallVectorImpl<MCInst> &Instructions) {
1923 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1926 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1927 SmallVectorImpl<MCInst> &Instructions) {
1928 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1931 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1932 SmallVectorImpl<MCInst> &Instructions) {
1934 tmpInst.setOpcode(Opcode);
1935 tmpInst.addOperand(MCOperand::createImm(Imm1));
1936 tmpInst.addOperand(MCOperand::createImm(Imm2));
1937 tmpInst.setLoc(IDLoc);
1938 Instructions.push_back(tmpInst);
1941 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1942 SmallVectorImpl<MCInst> &Instructions) {
1944 tmpInst.setOpcode(Opcode);
1945 tmpInst.addOperand(MCOperand::createReg(Reg0));
1946 tmpInst.setLoc(IDLoc);
1947 Instructions.push_back(tmpInst);
1950 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1951 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1953 tmpInst.setOpcode(Opcode);
1954 tmpInst.addOperand(MCOperand::createReg(Reg0));
1955 tmpInst.addOperand(MCOperand::createReg(Reg1));
1956 tmpInst.addOperand(Op2);
1957 tmpInst.setLoc(IDLoc);
1958 Instructions.push_back(tmpInst);
1961 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1962 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1963 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1967 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1968 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1969 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1973 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1974 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1975 if (ShiftAmount >= 32) {
1976 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1981 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1983 } // end anonymous namespace.
1985 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1986 SmallVectorImpl<MCInst> &Instructions) {
1987 // Create a JALR instruction which is going to replace the pseudo-JAL.
1989 JalrInst.setLoc(IDLoc);
1990 const MCOperand FirstRegOp = Inst.getOperand(0);
1991 const unsigned Opcode = Inst.getOpcode();
1993 if (Opcode == Mips::JalOneReg) {
1994 // jal $rs => jalr $rs
1995 if (inMicroMipsMode()) {
1996 JalrInst.setOpcode(Mips::JALR16_MM);
1997 JalrInst.addOperand(FirstRegOp);
1999 JalrInst.setOpcode(Mips::JALR);
2000 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2001 JalrInst.addOperand(FirstRegOp);
2003 } else if (Opcode == Mips::JalTwoReg) {
2004 // jal $rd, $rs => jalr $rd, $rs
2005 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2006 JalrInst.addOperand(FirstRegOp);
2007 const MCOperand SecondRegOp = Inst.getOperand(1);
2008 JalrInst.addOperand(SecondRegOp);
2010 Instructions.push_back(JalrInst);
2012 // If .set reorder is active, emit a NOP after it.
2013 if (AssemblerOptions.back()->isReorder()) {
2014 // This is a 32-bit NOP because these 2 pseudo-instructions
2015 // do not have a short delay slot.
2017 NopInst.setOpcode(Mips::SLL);
2018 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2019 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2020 NopInst.addOperand(MCOperand::createImm(0));
2021 Instructions.push_back(NopInst);
2027 /// Can the value be represented by a unsigned N-bit value and a shift left?
2028 template<unsigned N>
2029 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2030 unsigned BitNum = findFirstSet(x);
2032 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2035 /// Load (or add) an immediate into a register.
2037 /// @param ImmValue The immediate to load.
2038 /// @param DstReg The register that will hold the immediate.
2039 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2040 /// for a simple initialization.
2041 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2042 /// @param IsAddress True if the immediate represents an address. False if it
2044 /// @param IDLoc Location of the immediate in the source file.
2045 /// @param Instructions The instructions emitted by this expansion.
2046 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2047 unsigned SrcReg, bool Is32BitImm,
2048 bool IsAddress, SMLoc IDLoc,
2049 SmallVectorImpl<MCInst> &Instructions) {
2050 if (!Is32BitImm && !isGP64bit()) {
2051 Error(IDLoc, "instruction requires a 64-bit architecture");
2056 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2057 // Sign extend up to 64-bit so that the predicates match the hardware
2058 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2060 ImmValue = SignExtend64<32>(ImmValue);
2062 Error(IDLoc, "instruction requires a 32-bit immediate");
2067 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2068 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2070 bool UseSrcReg = false;
2071 if (SrcReg != Mips::NoRegister)
2074 unsigned TmpReg = DstReg;
2075 if (UseSrcReg && (DstReg == SrcReg)) {
2076 // At this point we need AT to perform the expansions and we exit if it is
2078 unsigned ATReg = getATReg(IDLoc);
2084 if (isInt<16>(ImmValue)) {
2088 // This doesn't quite follow the usual ABI expectations for N32 but matches
2089 // traditional assembler behaviour. N32 would normally use addiu for both
2090 // integers and addresses.
2091 if (IsAddress && !Is32BitImm) {
2092 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2096 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2100 if (isUInt<16>(ImmValue)) {
2101 unsigned TmpReg = DstReg;
2102 if (SrcReg == DstReg) {
2103 TmpReg = getATReg(IDLoc);
2108 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2110 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2114 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2115 warnIfNoMacro(IDLoc);
2117 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2118 uint16_t Bits15To0 = ImmValue & 0xffff;
2120 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2121 // Traditional behaviour seems to special case this particular value. It's
2122 // not clear why other masks are handled differently.
2123 if (ImmValue == 0xffffffff) {
2124 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2125 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2127 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2131 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2133 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2134 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2136 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2138 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2142 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2144 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2146 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2150 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2152 Error(IDLoc, "instruction requires a 32-bit immediate");
2156 // Traditionally, these immediates are shifted as little as possible and as
2157 // such we align the most significant bit to bit 15 of our temporary.
2158 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2159 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2160 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2161 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2162 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2163 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2166 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2171 warnIfNoMacro(IDLoc);
2173 // The remaining case is packed with a sequence of dsll and ori with zeros
2174 // being omitted and any neighbouring dsll's being coalesced.
2175 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2177 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2178 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2179 IDLoc, Instructions))
2182 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2183 // skip it and defer the shift to the next chunk.
2184 unsigned ShiftCarriedForwards = 16;
2185 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2186 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2188 if (ImmChunk != 0) {
2189 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2191 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2192 ShiftCarriedForwards = 0;
2195 ShiftCarriedForwards += 16;
2197 ShiftCarriedForwards -= 16;
2199 // Finish any remaining shifts left by trailing zeros.
2200 if (ShiftCarriedForwards)
2201 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2205 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2210 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2211 SmallVectorImpl<MCInst> &Instructions) {
2212 const MCOperand &ImmOp = Inst.getOperand(1);
2213 assert(ImmOp.isImm() && "expected immediate operand kind");
2214 const MCOperand &DstRegOp = Inst.getOperand(0);
2215 assert(DstRegOp.isReg() && "expected register operand kind");
2217 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2218 Is32BitImm, false, IDLoc, Instructions))
2224 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2225 const MCOperand &Offset,
2226 bool Is32BitAddress, SMLoc IDLoc,
2227 SmallVectorImpl<MCInst> &Instructions) {
2228 // la can't produce a usable address when addresses are 64-bit.
2229 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2230 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2231 // We currently can't do this because we depend on the equality
2232 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2233 Error(IDLoc, "la used to load 64-bit address");
2234 // Continue as if we had 'dla' instead.
2235 Is32BitAddress = false;
2238 // dla requires 64-bit addresses.
2239 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2240 Error(IDLoc, "instruction requires a 64-bit architecture");
2244 if (!Offset.isImm())
2245 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2246 Is32BitAddress, IDLoc, Instructions);
2248 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2249 IDLoc, Instructions);
2252 bool MipsAsmParser::loadAndAddSymbolAddress(
2253 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2254 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2255 warnIfNoMacro(IDLoc);
2257 // FIXME: The way we're handling symbols right now prevents simple expressions
2258 // like foo+8. We'll be able to fix this once our unary operators (%hi
2259 // and similar) are treated as operators rather than as fixup types.
2260 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2261 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2262 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2263 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2264 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2266 bool UseSrcReg = SrcReg != Mips::NoRegister;
2268 // This is the 64-bit symbol address expansion.
2269 if (ABI.ArePtrs64bit() && isGP64bit()) {
2270 // We always need AT for the 64-bit expansion.
2271 // If it is not available we exit.
2272 unsigned ATReg = getATReg(IDLoc);
2276 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2277 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2278 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2279 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2281 if (UseSrcReg && (DstReg == SrcReg)) {
2282 // If $rs is the same as $rd:
2283 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2284 // daddiu $at, $at, %higher(sym)
2285 // dsll $at, $at, 16
2286 // daddiu $at, $at, %hi(sym)
2287 // dsll $at, $at, 16
2288 // daddiu $at, $at, %lo(sym)
2289 // daddu $rd, $at, $rd
2290 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2292 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2293 IDLoc, Instructions);
2294 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2295 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2297 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2298 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2300 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2305 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2306 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2307 // lui $at, %hi(sym)
2308 // daddiu $rd, $rd, %higher(sym)
2309 // daddiu $at, $at, %lo(sym)
2310 // dsll32 $rd, $rd, 0
2311 // daddu $rd, $rd, $at
2312 // (daddu $rd, $rd, $rs)
2313 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2315 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2317 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2318 IDLoc, Instructions);
2319 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2321 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2322 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2324 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2329 // And now, the 32-bit symbol address expansion:
2330 // If $rs is the same as $rd:
2331 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2332 // ori $at, $at, %lo(sym)
2333 // addu $rd, $at, $rd
2334 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2335 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2336 // ori $rd, $rd, %lo(sym)
2337 // (addu $rd, $rd, $rs)
2338 unsigned TmpReg = DstReg;
2339 if (UseSrcReg && (DstReg == SrcReg)) {
2340 // If $rs is the same as $rd, we need to use AT.
2341 // If it is not available we exit.
2342 unsigned ATReg = getATReg(IDLoc);
2348 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2349 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2353 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2355 assert(DstReg == TmpReg);
2360 bool MipsAsmParser::expandUncondBranchMMPseudo(
2361 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2362 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2363 "unexpected number of operands");
2365 MCOperand Offset = Inst.getOperand(0);
2366 if (Offset.isExpr()) {
2368 Inst.setOpcode(Mips::BEQ_MM);
2369 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2370 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2371 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2373 assert(Offset.isImm() && "expected immediate operand kind");
2374 if (isIntN(11, Offset.getImm())) {
2375 // If offset fits into 11 bits then this instruction becomes microMIPS
2376 // 16-bit unconditional branch instruction.
2377 if (inMicroMipsMode())
2378 Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2380 if (!isIntN(17, Offset.getImm()))
2381 Error(IDLoc, "branch target out of range");
2382 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2383 Error(IDLoc, "branch to misaligned address");
2385 Inst.setOpcode(Mips::BEQ_MM);
2386 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2387 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2388 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2391 Instructions.push_back(Inst);
2393 // If .set reorder is active and branch instruction has a delay slot,
2394 // emit a NOP after it.
2395 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2396 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2397 createNop(true, IDLoc, Instructions);
2402 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2403 SmallVectorImpl<MCInst> &Instructions) {
2404 const MCOperand &DstRegOp = Inst.getOperand(0);
2405 assert(DstRegOp.isReg() && "expected register operand kind");
2407 const MCOperand &ImmOp = Inst.getOperand(1);
2408 assert(ImmOp.isImm() && "expected immediate operand kind");
2410 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2411 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2413 unsigned OpCode = 0;
2414 switch(Inst.getOpcode()) {
2422 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2426 int64_t ImmValue = ImmOp.getImm();
2427 if (ImmValue == 0) {
2429 BranchInst.setOpcode(OpCode);
2430 BranchInst.addOperand(DstRegOp);
2431 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2432 BranchInst.addOperand(MemOffsetOp);
2433 Instructions.push_back(BranchInst);
2435 warnIfNoMacro(IDLoc);
2437 unsigned ATReg = getATReg(IDLoc);
2441 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2442 IDLoc, Instructions))
2446 BranchInst.setOpcode(OpCode);
2447 BranchInst.addOperand(DstRegOp);
2448 BranchInst.addOperand(MCOperand::createReg(ATReg));
2449 BranchInst.addOperand(MemOffsetOp);
2450 Instructions.push_back(BranchInst);
2455 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2456 SmallVectorImpl<MCInst> &Instructions,
2457 bool isLoad, bool isImmOpnd) {
2459 unsigned ImmOffset, HiOffset, LoOffset;
2460 const MCExpr *ExprOffset;
2462 // 1st operand is either the source or destination register.
2463 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2464 unsigned RegOpNum = Inst.getOperand(0).getReg();
2465 // 2nd operand is the base register.
2466 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2467 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2468 // 3rd operand is either an immediate or expression.
2470 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2471 ImmOffset = Inst.getOperand(2).getImm();
2472 LoOffset = ImmOffset & 0x0000ffff;
2473 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2474 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2475 if (LoOffset & 0x8000)
2478 ExprOffset = Inst.getOperand(2).getExpr();
2479 // All instructions will have the same location.
2480 TempInst.setLoc(IDLoc);
2481 // These are some of the types of expansions we perform here:
2482 // 1) lw $8, sym => lui $8, %hi(sym)
2483 // lw $8, %lo(sym)($8)
2484 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2486 // lw $8, %lo(offset)($9)
2487 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2489 // lw $8, %lo(offset)($at)
2490 // 4) sw $8, sym => lui $at, %hi(sym)
2491 // sw $8, %lo(sym)($at)
2492 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2494 // sw $8, %lo(offset)($at)
2495 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2496 // ldc1 $f0, %lo(sym)($at)
2498 // For load instructions we can use the destination register as a temporary
2499 // if base and dst are different (examples 1 and 2) and if the base register
2500 // is general purpose otherwise we must use $at (example 6) and error if it's
2501 // not available. For stores we must use $at (examples 4 and 5) because we
2502 // must not clobber the source register setting up the offset.
2503 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2504 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2505 unsigned RegClassIDOp0 =
2506 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2507 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2508 (RegClassIDOp0 == Mips::GPR64RegClassID);
2509 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2510 TmpRegNum = RegOpNum;
2512 // At this point we need AT to perform the expansions and we exit if it is
2514 TmpRegNum = getATReg(IDLoc);
2519 TempInst.setOpcode(Mips::LUi);
2520 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2522 TempInst.addOperand(MCOperand::createImm(HiOffset));
2524 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2525 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2527 // Add the instruction to the list.
2528 Instructions.push_back(TempInst);
2529 // Prepare TempInst for next instruction.
2531 // Add temp register to base.
2532 if (BaseRegNum != Mips::ZERO) {
2533 TempInst.setOpcode(Mips::ADDu);
2534 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2535 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2536 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2537 Instructions.push_back(TempInst);
2540 // And finally, create original instruction with low part
2541 // of offset and new base.
2542 TempInst.setOpcode(Inst.getOpcode());
2543 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2544 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2546 TempInst.addOperand(MCOperand::createImm(LoOffset));
2548 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2549 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2551 Instructions.push_back(TempInst);
2556 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2557 SmallVectorImpl<MCInst> &Instructions) {
2558 unsigned OpNum = Inst.getNumOperands();
2559 unsigned Opcode = Inst.getOpcode();
2560 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2562 assert (Inst.getOperand(OpNum - 1).isImm() &&
2563 Inst.getOperand(OpNum - 2).isReg() &&
2564 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2566 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2567 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2568 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2569 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2570 // It can be implemented as SWM16 or LWM16 instruction.
2571 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2573 Inst.setOpcode(NewOpcode);
2574 Instructions.push_back(Inst);
2578 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2579 SmallVectorImpl<MCInst> &Instructions) {
2580 unsigned PseudoOpcode = Inst.getOpcode();
2581 unsigned SrcReg = Inst.getOperand(0).getReg();
2582 unsigned TrgReg = Inst.getOperand(1).getReg();
2583 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2585 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2586 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2588 switch (PseudoOpcode) {
2591 AcceptsEquality = false;
2592 ReverseOrderSLT = false;
2593 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2594 ZeroSrcOpcode = Mips::BGTZ;
2595 ZeroTrgOpcode = Mips::BLTZ;
2599 AcceptsEquality = true;
2600 ReverseOrderSLT = true;
2601 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2602 ZeroSrcOpcode = Mips::BGEZ;
2603 ZeroTrgOpcode = Mips::BLEZ;
2607 AcceptsEquality = true;
2608 ReverseOrderSLT = false;
2609 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2610 ZeroSrcOpcode = Mips::BLEZ;
2611 ZeroTrgOpcode = Mips::BGEZ;
2615 AcceptsEquality = false;
2616 ReverseOrderSLT = true;
2617 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2618 ZeroSrcOpcode = Mips::BLTZ;
2619 ZeroTrgOpcode = Mips::BGTZ;
2622 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2626 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2627 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2628 if (IsSrcRegZero && IsTrgRegZero) {
2629 // FIXME: All of these Opcode-specific if's are needed for compatibility
2630 // with GAS' behaviour. However, they may not generate the most efficient
2631 // code in some circumstances.
2632 if (PseudoOpcode == Mips::BLT) {
2633 BranchInst.setOpcode(Mips::BLTZ);
2634 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2635 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2636 Instructions.push_back(BranchInst);
2639 if (PseudoOpcode == Mips::BLE) {
2640 BranchInst.setOpcode(Mips::BLEZ);
2641 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2642 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2643 Instructions.push_back(BranchInst);
2644 Warning(IDLoc, "branch is always taken");
2647 if (PseudoOpcode == Mips::BGE) {
2648 BranchInst.setOpcode(Mips::BGEZ);
2649 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2650 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2651 Instructions.push_back(BranchInst);
2652 Warning(IDLoc, "branch is always taken");
2655 if (PseudoOpcode == Mips::BGT) {
2656 BranchInst.setOpcode(Mips::BGTZ);
2657 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2658 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2659 Instructions.push_back(BranchInst);
2662 if (PseudoOpcode == Mips::BGTU) {
2663 BranchInst.setOpcode(Mips::BNE);
2664 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2665 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2666 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2667 Instructions.push_back(BranchInst);
2670 if (AcceptsEquality) {
2671 // If both registers are $0 and the pseudo-branch accepts equality, it
2672 // will always be taken, so we emit an unconditional branch.
2673 BranchInst.setOpcode(Mips::BEQ);
2674 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2675 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2676 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2677 Instructions.push_back(BranchInst);
2678 Warning(IDLoc, "branch is always taken");
2681 // If both registers are $0 and the pseudo-branch does not accept
2682 // equality, it will never be taken, so we don't have to emit anything.
2685 if (IsSrcRegZero || IsTrgRegZero) {
2686 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2687 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2688 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2689 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2690 // the pseudo-branch will never be taken, so we don't emit anything.
2691 // This only applies to unsigned pseudo-branches.
2694 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2695 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2696 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2697 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2698 // the pseudo-branch will always be taken, so we emit an unconditional
2700 // This only applies to unsigned pseudo-branches.
2701 BranchInst.setOpcode(Mips::BEQ);
2702 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2703 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2704 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2705 Instructions.push_back(BranchInst);
2706 Warning(IDLoc, "branch is always taken");
2710 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2711 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2712 // the pseudo-branch will be taken only when the non-zero register is
2713 // different from 0, so we emit a BNEZ.
2715 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2716 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2717 // the pseudo-branch will be taken only when the non-zero register is
2718 // equal to 0, so we emit a BEQZ.
2720 // Because only BLEU and BGEU branch on equality, we can use the
2721 // AcceptsEquality variable to decide when to emit the BEQZ.
2722 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2723 BranchInst.addOperand(
2724 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2725 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2726 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2727 Instructions.push_back(BranchInst);
2730 // If we have a signed pseudo-branch and one of the registers is $0,
2731 // we can use an appropriate compare-to-zero branch. We select which one
2732 // to use in the switch statement above.
2733 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2734 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2735 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2736 Instructions.push_back(BranchInst);
2740 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2741 // expansions. If it is not available, we return.
2742 unsigned ATRegNum = getATReg(IDLoc);
2746 warnIfNoMacro(IDLoc);
2748 // SLT fits well with 2 of our 4 pseudo-branches:
2749 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2750 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2751 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2752 // This is accomplished by using a BNEZ with the result of the SLT.
2754 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2755 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2756 // Because only BGE and BLE branch on equality, we can use the
2757 // AcceptsEquality variable to decide when to emit the BEQZ.
2758 // Note that the order of the SLT arguments doesn't change between
2761 // The same applies to the unsigned variants, except that SLTu is used
2764 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2765 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2766 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2767 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2768 Instructions.push_back(SetInst);
2770 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2771 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2772 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2773 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2774 Instructions.push_back(BranchInst);
2778 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2779 SmallVectorImpl<MCInst> &Instructions,
2780 const bool IsMips64, const bool Signed) {
2781 if (hasMips32r6()) {
2782 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2786 warnIfNoMacro(IDLoc);
2788 const MCOperand &RsRegOp = Inst.getOperand(0);
2789 assert(RsRegOp.isReg() && "expected register operand kind");
2790 unsigned RsReg = RsRegOp.getReg();
2792 const MCOperand &RtRegOp = Inst.getOperand(1);
2793 assert(RtRegOp.isReg() && "expected register operand kind");
2794 unsigned RtReg = RtRegOp.getReg();
2799 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2800 ZeroReg = Mips::ZERO_64;
2802 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2803 ZeroReg = Mips::ZERO;
2806 bool UseTraps = useTraps();
2808 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2809 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2810 Warning(IDLoc, "dividing zero by zero");
2812 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2814 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2818 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2822 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2827 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2828 Warning(IDLoc, "division by zero");
2831 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2835 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2840 // FIXME: The values for these two BranchTarget variables may be different in
2841 // micromips. These magic numbers need to be removed.
2842 unsigned BranchTargetNoTraps;
2843 unsigned BranchTarget;
2846 BranchTarget = IsMips64 ? 12 : 8;
2847 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2849 BranchTarget = IsMips64 ? 20 : 16;
2850 BranchTargetNoTraps = 8;
2851 // Branch to the li instruction.
2852 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2856 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2859 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2862 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2866 unsigned ATReg = getATReg(IDLoc);
2870 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2872 // Branch to the mflo instruction.
2873 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2874 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2875 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2877 // Branch to the mflo instruction.
2878 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2879 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2883 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2885 // Branch to the mflo instruction.
2886 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2887 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2888 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2890 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2894 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2895 SmallVectorImpl<MCInst> &Instructions) {
2896 if (hasMips32r6() || hasMips64r6()) {
2897 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2901 warnIfNoMacro(IDLoc);
2903 const MCOperand &DstRegOp = Inst.getOperand(0);
2904 assert(DstRegOp.isReg() && "expected register operand kind");
2906 const MCOperand &SrcRegOp = Inst.getOperand(1);
2907 assert(SrcRegOp.isReg() && "expected register operand kind");
2909 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2910 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2912 unsigned DstReg = DstRegOp.getReg();
2913 unsigned SrcReg = SrcRegOp.getReg();
2914 int64_t OffsetValue = OffsetImmOp.getImm();
2916 // NOTE: We always need AT for ULHU, as it is always used as the source
2917 // register for one of the LBu's.
2918 unsigned ATReg = getATReg(IDLoc);
2922 // When the value of offset+1 does not fit in 16 bits, we have to load the
2923 // offset in AT, (D)ADDu the original source register (if there was one), and
2924 // then use AT as the source register for the 2 generated LBu's.
2925 bool LoadedOffsetInAT = false;
2926 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2927 LoadedOffsetInAT = true;
2929 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2930 true, IDLoc, Instructions))
2933 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2934 // because it will make our output more similar to GAS'. For example,
2935 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2936 // instead of just an "ori $1, $9, 32768".
2937 // NOTE: If there is no source register specified in the ULHU, the parser
2938 // will interpret it as $0.
2939 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2940 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2943 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2944 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2945 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2947 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2949 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2950 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2952 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2953 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2956 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2959 TmpInst.setOpcode(Mips::LBu);
2960 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2961 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2962 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2963 Instructions.push_back(TmpInst);
2966 TmpInst.setOpcode(Mips::LBu);
2967 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2968 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2969 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2970 Instructions.push_back(TmpInst);
2973 TmpInst.setOpcode(Mips::SLL);
2974 TmpInst.addOperand(MCOperand::createReg(SllReg));
2975 TmpInst.addOperand(MCOperand::createReg(SllReg));
2976 TmpInst.addOperand(MCOperand::createImm(8));
2977 Instructions.push_back(TmpInst);
2980 TmpInst.setOpcode(Mips::OR);
2981 TmpInst.addOperand(MCOperand::createReg(DstReg));
2982 TmpInst.addOperand(MCOperand::createReg(DstReg));
2983 TmpInst.addOperand(MCOperand::createReg(ATReg));
2984 Instructions.push_back(TmpInst);
2989 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2990 SmallVectorImpl<MCInst> &Instructions) {
2991 if (hasMips32r6() || hasMips64r6()) {
2992 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2996 const MCOperand &DstRegOp = Inst.getOperand(0);
2997 assert(DstRegOp.isReg() && "expected register operand kind");
2999 const MCOperand &SrcRegOp = Inst.getOperand(1);
3000 assert(SrcRegOp.isReg() && "expected register operand kind");
3002 const MCOperand &OffsetImmOp = Inst.getOperand(2);
3003 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3005 unsigned SrcReg = SrcRegOp.getReg();
3006 int64_t OffsetValue = OffsetImmOp.getImm();
3009 // When the value of offset+3 does not fit in 16 bits, we have to load the
3010 // offset in AT, (D)ADDu the original source register (if there was one), and
3011 // then use AT as the source register for the generated LWL and LWR.
3012 bool LoadedOffsetInAT = false;
3013 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3014 ATReg = getATReg(IDLoc);
3017 LoadedOffsetInAT = true;
3019 warnIfNoMacro(IDLoc);
3021 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3022 true, IDLoc, Instructions))
3025 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3026 // because it will make our output more similar to GAS'. For example,
3027 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3028 // instead of just an "ori $1, $9, 32768".
3029 // NOTE: If there is no source register specified in the ULW, the parser
3030 // will interpret it as $0.
3031 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3032 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3035 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3036 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3038 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3039 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3041 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3042 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3045 MCInst LeftLoadInst;
3046 LeftLoadInst.setOpcode(Mips::LWL);
3047 LeftLoadInst.addOperand(DstRegOp);
3048 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3049 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3050 Instructions.push_back(LeftLoadInst);
3052 MCInst RightLoadInst;
3053 RightLoadInst.setOpcode(Mips::LWR);
3054 RightLoadInst.addOperand(DstRegOp);
3055 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3056 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3057 Instructions.push_back(RightLoadInst);
3062 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3063 SmallVectorImpl<MCInst> &Instructions) {
3065 if (hasShortDelaySlot) {
3066 NopInst.setOpcode(Mips::MOVE16_MM);
3067 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3068 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3070 NopInst.setOpcode(Mips::SLL);
3071 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3072 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3073 NopInst.addOperand(MCOperand::createImm(0));
3075 Instructions.push_back(NopInst);
3078 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3079 unsigned TrgReg, bool Is64Bit,
3080 SmallVectorImpl<MCInst> &Instructions) {
3081 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3085 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3086 // As described by the Mips32r2 spec, the registers Rd and Rs for
3087 // jalr.hb must be different.
3088 unsigned Opcode = Inst.getOpcode();
3090 if (Opcode == Mips::JALR_HB &&
3091 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3092 return Match_RequiresDifferentSrcAndDst;
3094 return Match_Success;
3097 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3098 OperandVector &Operands,
3100 uint64_t &ErrorInfo,
3101 bool MatchingInlineAsm) {
3104 SmallVector<MCInst, 8> Instructions;
3105 unsigned MatchResult =
3106 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3108 switch (MatchResult) {
3109 case Match_Success: {
3110 if (processInstruction(Inst, IDLoc, Instructions))
3112 for (unsigned i = 0; i < Instructions.size(); i++)
3113 Out.EmitInstruction(Instructions[i], STI);
3116 case Match_MissingFeature:
3117 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3119 case Match_InvalidOperand: {
3120 SMLoc ErrorLoc = IDLoc;
3121 if (ErrorInfo != ~0ULL) {
3122 if (ErrorInfo >= Operands.size())
3123 return Error(IDLoc, "too few operands for instruction");
3125 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3126 if (ErrorLoc == SMLoc())
3130 return Error(ErrorLoc, "invalid operand for instruction");
3132 case Match_MnemonicFail:
3133 return Error(IDLoc, "invalid instruction");
3134 case Match_RequiresDifferentSrcAndDst:
3135 return Error(IDLoc, "source and destination must be different");
3138 llvm_unreachable("Implement any new match types added!");
3141 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3142 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3143 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3144 ") without \".set noat\"");
3147 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3148 if (!AssemblerOptions.back()->isMacro())
3149 Warning(Loc, "macro instruction expanded into multiple instructions");
3153 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3154 SMRange Range, bool ShowColors) {
3155 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3156 Range, SMFixIt(Range, FixMsg),
3160 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3163 CC = StringSwitch<unsigned>(Name)
3199 if (!(isABI_N32() || isABI_N64()))
3202 if (12 <= CC && CC <= 15) {
3203 // Name is one of t4-t7
3204 AsmToken RegTok = getLexer().peekTok();
3205 SMRange RegRange = RegTok.getLocRange();
3207 StringRef FixedName = StringSwitch<StringRef>(Name)
3213 assert(FixedName != "" && "Register name is not one of t4-t7.");
3215 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3216 "Did you mean $" + FixedName + "?", RegRange);
3219 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3220 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3221 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3222 if (8 <= CC && CC <= 11)
3226 CC = StringSwitch<unsigned>(Name)
3238 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3241 CC = StringSwitch<unsigned>(Name)
3242 .Case("hwr_cpunum", 0)
3243 .Case("hwr_synci_step", 1)
3245 .Case("hwr_ccres", 3)
3246 .Case("hwr_ulr", 29)
3252 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3254 if (Name[0] == 'f') {
3255 StringRef NumString = Name.substr(1);
3257 if (NumString.getAsInteger(10, IntVal))
3258 return -1; // This is not an integer.
3259 if (IntVal > 31) // Maximum index for fpu register.
3266 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3268 if (Name.startswith("fcc")) {
3269 StringRef NumString = Name.substr(3);
3271 if (NumString.getAsInteger(10, IntVal))
3272 return -1; // This is not an integer.
3273 if (IntVal > 7) // There are only 8 fcc registers.
3280 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3282 if (Name.startswith("ac")) {
3283 StringRef NumString = Name.substr(2);
3285 if (NumString.getAsInteger(10, IntVal))
3286 return -1; // This is not an integer.
3287 if (IntVal > 3) // There are only 3 acc registers.
3294 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3297 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3306 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3309 CC = StringSwitch<unsigned>(Name)
3312 .Case("msaaccess", 2)
3314 .Case("msamodify", 4)
3315 .Case("msarequest", 5)
3317 .Case("msaunmap", 7)
3323 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3324 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3326 reportParseError(Loc,
3327 "pseudo-instruction requires $at, which is not available");
3330 unsigned AT = getReg(
3331 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3335 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3336 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3339 unsigned MipsAsmParser::getGPR(int RegNo) {
3340 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3344 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3346 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3349 return getReg(RegClass, RegNum);
3352 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3353 MCAsmParser &Parser = getParser();
3354 DEBUG(dbgs() << "parseOperand\n");
3356 // Check if the current operand has a custom associated parser, if so, try to
3357 // custom parse the operand, or fallback to the general approach.
3358 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3359 if (ResTy == MatchOperand_Success)
3361 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3362 // there was a match, but an error occurred, in which case, just return that
3363 // the operand parsing failed.
3364 if (ResTy == MatchOperand_ParseFail)
3367 DEBUG(dbgs() << ".. Generic Parser\n");
3369 switch (getLexer().getKind()) {
3371 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3373 case AsmToken::Dollar: {
3374 // Parse the register.
3375 SMLoc S = Parser.getTok().getLoc();
3377 // Almost all registers have been parsed by custom parsers. There is only
3378 // one exception to this. $zero (and it's alias $0) will reach this point
3379 // for div, divu, and similar instructions because it is not an operand
3380 // to the instruction definition but an explicit register. Special case
3381 // this situation for now.
3382 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3385 // Maybe it is a symbol reference.
3386 StringRef Identifier;
3387 if (Parser.parseIdentifier(Identifier))
3390 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3391 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3392 // Otherwise create a symbol reference.
3394 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3396 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3399 // Else drop to expression parsing.
3400 case AsmToken::LParen:
3401 case AsmToken::Minus:
3402 case AsmToken::Plus:
3403 case AsmToken::Integer:
3404 case AsmToken::Tilde:
3405 case AsmToken::String: {
3406 DEBUG(dbgs() << ".. generic integer\n");
3407 OperandMatchResultTy ResTy = parseImm(Operands);
3408 return ResTy != MatchOperand_Success;
3410 case AsmToken::Percent: {
3411 // It is a symbol reference or constant expression.
3412 const MCExpr *IdVal;
3413 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3414 if (parseRelocOperand(IdVal))
3417 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3419 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3421 } // case AsmToken::Percent
3422 } // switch(getLexer().getKind())
3426 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3427 StringRef RelocStr) {
3429 // Check the type of the expression.
3430 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3431 // It's a constant, evaluate reloc value.
3433 switch (getVariantKind(RelocStr)) {
3434 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3435 // Get the 1st 16-bits.
3436 Val = MCE->getValue() & 0xffff;
3438 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3439 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3440 // 16 bits being negative.
3441 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3443 case MCSymbolRefExpr::VK_Mips_HIGHER:
3444 // Get the 3rd 16-bits.
3445 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3447 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3448 // Get the 4th 16-bits.
3449 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3452 report_fatal_error("unsupported reloc value");
3454 return MCConstantExpr::create(Val, getContext());
3457 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3458 // It's a symbol, create a symbolic expression from the symbol.
3459 const MCSymbol *Symbol = &MSRE->getSymbol();
3460 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3461 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3465 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3466 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3468 // Try to create target expression.
3469 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3470 return MipsMCExpr::create(VK, Expr, getContext());
3472 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3473 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3474 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3478 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3479 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3480 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3483 // Just return the original expression.
3487 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3489 switch (Expr->getKind()) {
3490 case MCExpr::Constant:
3492 case MCExpr::SymbolRef:
3493 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3494 case MCExpr::Binary:
3495 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3496 if (!isEvaluated(BE->getLHS()))
3498 return isEvaluated(BE->getRHS());
3501 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3502 case MCExpr::Target:
3508 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3509 MCAsmParser &Parser = getParser();
3510 Parser.Lex(); // Eat the % token.
3511 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3512 if (Tok.isNot(AsmToken::Identifier))
3515 std::string Str = Tok.getIdentifier();
3517 Parser.Lex(); // Eat the identifier.
3518 // Now make an expression from the rest of the operand.
3519 const MCExpr *IdVal;
3522 if (getLexer().getKind() == AsmToken::LParen) {
3524 Parser.Lex(); // Eat the '(' token.
3525 if (getLexer().getKind() == AsmToken::Percent) {
3526 Parser.Lex(); // Eat the % token.
3527 const AsmToken &nextTok = Parser.getTok();
3528 if (nextTok.isNot(AsmToken::Identifier))
3531 Str += nextTok.getIdentifier();
3532 Parser.Lex(); // Eat the identifier.
3533 if (getLexer().getKind() != AsmToken::LParen)
3538 if (getParser().parseParenExpression(IdVal, EndLoc))
3541 while (getLexer().getKind() == AsmToken::RParen)
3542 Parser.Lex(); // Eat the ')' token.
3545 return true; // Parenthesis must follow the relocation operand.
3547 Res = evaluateRelocExpr(IdVal, Str);
3551 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3553 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3554 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3555 if (ResTy == MatchOperand_Success) {
3556 assert(Operands.size() == 1);
3557 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3558 StartLoc = Operand.getStartLoc();
3559 EndLoc = Operand.getEndLoc();
3561 // AFAIK, we only support numeric registers and named GPR's in CFI
3563 // Don't worry about eating tokens before failing. Using an unrecognised
3564 // register is a parse error.
3565 if (Operand.isGPRAsmReg()) {
3566 // Resolve to GPR32 or GPR64 appropriately.
3567 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3570 return (RegNo == (unsigned)-1);
3573 assert(Operands.size() == 0);
3574 return (RegNo == (unsigned)-1);
3577 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3578 MCAsmParser &Parser = getParser();
3581 unsigned NumOfLParen = 0;
3583 while (getLexer().getKind() == AsmToken::LParen) {
3588 switch (getLexer().getKind()) {
3591 case AsmToken::Identifier:
3592 case AsmToken::LParen:
3593 case AsmToken::Integer:
3594 case AsmToken::Minus:
3595 case AsmToken::Plus:
3597 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3599 Result = (getParser().parseExpression(Res));
3600 while (getLexer().getKind() == AsmToken::RParen)
3603 case AsmToken::Percent:
3604 Result = parseRelocOperand(Res);
3609 MipsAsmParser::OperandMatchResultTy
3610 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3611 MCAsmParser &Parser = getParser();
3612 DEBUG(dbgs() << "parseMemOperand\n");
3613 const MCExpr *IdVal = nullptr;
3615 bool isParenExpr = false;
3616 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3617 // First operand is the offset.
3618 S = Parser.getTok().getLoc();
3620 if (getLexer().getKind() == AsmToken::LParen) {
3625 if (getLexer().getKind() != AsmToken::Dollar) {
3626 if (parseMemOffset(IdVal, isParenExpr))
3627 return MatchOperand_ParseFail;
3629 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3630 if (Tok.isNot(AsmToken::LParen)) {
3631 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3632 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3634 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3635 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3636 return MatchOperand_Success;
3638 if (Tok.is(AsmToken::EndOfStatement)) {
3640 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3642 // Zero register assumed, add a memory operand with ZERO as its base.
3643 // "Base" will be managed by k_Memory.
3644 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3647 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3648 return MatchOperand_Success;
3650 Error(Parser.getTok().getLoc(), "'(' expected");
3651 return MatchOperand_ParseFail;
3654 Parser.Lex(); // Eat the '(' token.
3657 Res = parseAnyRegister(Operands);
3658 if (Res != MatchOperand_Success)
3661 if (Parser.getTok().isNot(AsmToken::RParen)) {
3662 Error(Parser.getTok().getLoc(), "')' expected");
3663 return MatchOperand_ParseFail;
3666 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3668 Parser.Lex(); // Eat the ')' token.
3671 IdVal = MCConstantExpr::create(0, getContext());
3673 // Replace the register operand with the memory operand.
3674 std::unique_ptr<MipsOperand> op(
3675 static_cast<MipsOperand *>(Operands.back().release()));
3676 // Remove the register from the operands.
3677 // "op" will be managed by k_Memory.
3678 Operands.pop_back();
3679 // Add the memory operand.
3680 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3682 if (IdVal->evaluateAsAbsolute(Imm))
3683 IdVal = MCConstantExpr::create(Imm, getContext());
3684 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3685 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3689 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3690 return MatchOperand_Success;
3693 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3694 MCAsmParser &Parser = getParser();
3695 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3697 SMLoc S = Parser.getTok().getLoc();
3699 if (Sym->isVariable())
3700 Expr = Sym->getVariableValue();
3703 if (Expr->getKind() == MCExpr::SymbolRef) {
3704 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3705 StringRef DefSymbol = Ref->getSymbol().getName();
3706 if (DefSymbol.startswith("$")) {
3707 OperandMatchResultTy ResTy =
3708 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3709 if (ResTy == MatchOperand_Success) {
3712 } else if (ResTy == MatchOperand_ParseFail)
3713 llvm_unreachable("Should never ParseFail");
3716 } else if (Expr->getKind() == MCExpr::Constant) {
3718 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3720 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3727 MipsAsmParser::OperandMatchResultTy
3728 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3729 StringRef Identifier,
3731 int Index = matchCPURegisterName(Identifier);
3733 Operands.push_back(MipsOperand::createGPRReg(
3734 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3735 return MatchOperand_Success;
3738 Index = matchHWRegsRegisterName(Identifier);
3740 Operands.push_back(MipsOperand::createHWRegsReg(
3741 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3742 return MatchOperand_Success;
3745 Index = matchFPURegisterName(Identifier);
3747 Operands.push_back(MipsOperand::createFGRReg(
3748 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3749 return MatchOperand_Success;
3752 Index = matchFCCRegisterName(Identifier);
3754 Operands.push_back(MipsOperand::createFCCReg(
3755 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3756 return MatchOperand_Success;
3759 Index = matchACRegisterName(Identifier);
3761 Operands.push_back(MipsOperand::createACCReg(
3762 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3763 return MatchOperand_Success;
3766 Index = matchMSA128RegisterName(Identifier);
3768 Operands.push_back(MipsOperand::createMSA128Reg(
3769 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3770 return MatchOperand_Success;
3773 Index = matchMSA128CtrlRegisterName(Identifier);
3775 Operands.push_back(MipsOperand::createMSACtrlReg(
3776 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3777 return MatchOperand_Success;
3780 return MatchOperand_NoMatch;
3783 MipsAsmParser::OperandMatchResultTy
3784 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3785 MCAsmParser &Parser = getParser();
3786 auto Token = Parser.getLexer().peekTok(false);
3788 if (Token.is(AsmToken::Identifier)) {
3789 DEBUG(dbgs() << ".. identifier\n");
3790 StringRef Identifier = Token.getIdentifier();
3791 OperandMatchResultTy ResTy =
3792 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3794 } else if (Token.is(AsmToken::Integer)) {
3795 DEBUG(dbgs() << ".. integer\n");
3796 Operands.push_back(MipsOperand::createNumericReg(
3797 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3799 return MatchOperand_Success;
3802 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3804 return MatchOperand_NoMatch;
3807 MipsAsmParser::OperandMatchResultTy
3808 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3809 MCAsmParser &Parser = getParser();
3810 DEBUG(dbgs() << "parseAnyRegister\n");
3812 auto Token = Parser.getTok();
3814 SMLoc S = Token.getLoc();
3816 if (Token.isNot(AsmToken::Dollar)) {
3817 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3818 if (Token.is(AsmToken::Identifier)) {
3819 if (searchSymbolAlias(Operands))
3820 return MatchOperand_Success;
3822 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3823 return MatchOperand_NoMatch;
3825 DEBUG(dbgs() << ".. $\n");
3827 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3828 if (ResTy == MatchOperand_Success) {
3830 Parser.Lex(); // identifier
3835 MipsAsmParser::OperandMatchResultTy
3836 MipsAsmParser::parseImm(OperandVector &Operands) {
3837 MCAsmParser &Parser = getParser();
3838 switch (getLexer().getKind()) {
3840 return MatchOperand_NoMatch;
3841 case AsmToken::LParen:
3842 case AsmToken::Minus:
3843 case AsmToken::Plus:
3844 case AsmToken::Integer:
3845 case AsmToken::Tilde:
3846 case AsmToken::String:
3850 const MCExpr *IdVal;
3851 SMLoc S = Parser.getTok().getLoc();
3852 if (getParser().parseExpression(IdVal))
3853 return MatchOperand_ParseFail;
3855 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3856 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3857 return MatchOperand_Success;
3860 MipsAsmParser::OperandMatchResultTy
3861 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3862 MCAsmParser &Parser = getParser();
3863 DEBUG(dbgs() << "parseJumpTarget\n");
3865 SMLoc S = getLexer().getLoc();
3867 // Integers and expressions are acceptable
3868 OperandMatchResultTy ResTy = parseImm(Operands);
3869 if (ResTy != MatchOperand_NoMatch)
3872 // Registers are a valid target and have priority over symbols.
3873 ResTy = parseAnyRegister(Operands);
3874 if (ResTy != MatchOperand_NoMatch)
3877 const MCExpr *Expr = nullptr;
3878 if (Parser.parseExpression(Expr)) {
3879 // We have no way of knowing if a symbol was consumed so we must ParseFail
3880 return MatchOperand_ParseFail;
3883 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3884 return MatchOperand_Success;
3887 MipsAsmParser::OperandMatchResultTy
3888 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3889 MCAsmParser &Parser = getParser();
3890 const MCExpr *IdVal;
3891 // If the first token is '$' we may have register operand.
3892 if (Parser.getTok().is(AsmToken::Dollar))
3893 return MatchOperand_NoMatch;
3894 SMLoc S = Parser.getTok().getLoc();
3895 if (getParser().parseExpression(IdVal))
3896 return MatchOperand_ParseFail;
3897 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3898 assert(MCE && "Unexpected MCExpr type.");
3899 int64_t Val = MCE->getValue();
3900 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3901 Operands.push_back(MipsOperand::CreateImm(
3902 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3903 return MatchOperand_Success;
3906 MipsAsmParser::OperandMatchResultTy
3907 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3908 MCAsmParser &Parser = getParser();
3909 switch (getLexer().getKind()) {
3911 return MatchOperand_NoMatch;
3912 case AsmToken::LParen:
3913 case AsmToken::Plus:
3914 case AsmToken::Minus:
3915 case AsmToken::Integer:
3920 SMLoc S = Parser.getTok().getLoc();
3922 if (getParser().parseExpression(Expr))
3923 return MatchOperand_ParseFail;
3926 if (!Expr->evaluateAsAbsolute(Val)) {
3927 Error(S, "expected immediate value");
3928 return MatchOperand_ParseFail;
3931 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3932 // and because the CPU always adds one to the immediate field, the allowed
3933 // range becomes 1..4. We'll only check the range here and will deal
3934 // with the addition/subtraction when actually decoding/encoding
3936 if (Val < 1 || Val > 4) {
3937 Error(S, "immediate not in range (1..4)");
3938 return MatchOperand_ParseFail;
3942 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3943 return MatchOperand_Success;
3946 MipsAsmParser::OperandMatchResultTy
3947 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3948 MCAsmParser &Parser = getParser();
3949 SmallVector<unsigned, 10> Regs;
3951 unsigned PrevReg = Mips::NoRegister;
3952 bool RegRange = false;
3953 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3955 if (Parser.getTok().isNot(AsmToken::Dollar))
3956 return MatchOperand_ParseFail;
3958 SMLoc S = Parser.getTok().getLoc();
3959 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3960 SMLoc E = getLexer().getLoc();
3961 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3962 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3964 // Remove last register operand because registers from register range
3965 // should be inserted first.
3966 if (RegNo == Mips::RA) {
3967 Regs.push_back(RegNo);
3969 unsigned TmpReg = PrevReg + 1;
3970 while (TmpReg <= RegNo) {
3971 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3972 Error(E, "invalid register operand");
3973 return MatchOperand_ParseFail;
3977 Regs.push_back(TmpReg++);
3983 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3984 (RegNo != Mips::RA)) {
3985 Error(E, "$16 or $31 expected");
3986 return MatchOperand_ParseFail;
3987 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3988 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3989 Error(E, "invalid register operand");
3990 return MatchOperand_ParseFail;
3991 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3992 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3993 Error(E, "consecutive register numbers expected");
3994 return MatchOperand_ParseFail;
3997 Regs.push_back(RegNo);
4000 if (Parser.getTok().is(AsmToken::Minus))
4003 if (!Parser.getTok().isNot(AsmToken::Minus) &&
4004 !Parser.getTok().isNot(AsmToken::Comma)) {
4005 Error(E, "',' or '-' expected");
4006 return MatchOperand_ParseFail;
4009 Lex(); // Consume comma or minus
4010 if (Parser.getTok().isNot(AsmToken::Dollar))
4016 SMLoc E = Parser.getTok().getLoc();
4017 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4018 parseMemOperand(Operands);
4019 return MatchOperand_Success;
4022 MipsAsmParser::OperandMatchResultTy
4023 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4024 MCAsmParser &Parser = getParser();
4026 SMLoc S = Parser.getTok().getLoc();
4027 if (parseAnyRegister(Operands) != MatchOperand_Success)
4028 return MatchOperand_ParseFail;
4030 SMLoc E = Parser.getTok().getLoc();
4031 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4032 unsigned Reg = Op.getGPR32Reg();
4033 Operands.pop_back();
4034 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4035 return MatchOperand_Success;
4038 MipsAsmParser::OperandMatchResultTy
4039 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4040 MCAsmParser &Parser = getParser();
4041 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4042 SmallVector<unsigned, 10> Regs;
4044 if (Parser.getTok().isNot(AsmToken::Dollar))
4045 return MatchOperand_ParseFail;
4047 SMLoc S = Parser.getTok().getLoc();
4049 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4050 return MatchOperand_ParseFail;
4052 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4053 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4054 Regs.push_back(RegNo);
4056 SMLoc E = Parser.getTok().getLoc();
4057 if (Parser.getTok().isNot(AsmToken::Comma)) {
4058 Error(E, "',' expected");
4059 return MatchOperand_ParseFail;
4065 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4066 return MatchOperand_ParseFail;
4068 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4069 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4070 Regs.push_back(RegNo);
4072 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4074 return MatchOperand_Success;
4077 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4079 MCSymbolRefExpr::VariantKind VK =
4080 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4081 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4082 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4083 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4084 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4085 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4086 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4087 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4088 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4089 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4090 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4091 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4092 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4093 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4094 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4095 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4096 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4097 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4098 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4099 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4100 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4101 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4102 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4103 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4104 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4105 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4106 .Default(MCSymbolRefExpr::VK_None);
4108 assert(VK != MCSymbolRefExpr::VK_None);
4113 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4115 /// ::= '(', register, ')'
4116 /// handle it before we iterate so we don't get tripped up by the lack of
4118 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4119 MCAsmParser &Parser = getParser();
4120 if (getLexer().is(AsmToken::LParen)) {
4122 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4124 if (parseOperand(Operands, Name)) {
4125 SMLoc Loc = getLexer().getLoc();
4126 Parser.eatToEndOfStatement();
4127 return Error(Loc, "unexpected token in argument list");
4129 if (Parser.getTok().isNot(AsmToken::RParen)) {
4130 SMLoc Loc = getLexer().getLoc();
4131 Parser.eatToEndOfStatement();
4132 return Error(Loc, "unexpected token, expected ')'");
4135 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4141 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4142 /// either one of these.
4143 /// ::= '[', register, ']'
4144 /// ::= '[', integer, ']'
4145 /// handle it before we iterate so we don't get tripped up by the lack of
4147 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4148 OperandVector &Operands) {
4149 MCAsmParser &Parser = getParser();
4150 if (getLexer().is(AsmToken::LBrac)) {
4152 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4154 if (parseOperand(Operands, Name)) {
4155 SMLoc Loc = getLexer().getLoc();
4156 Parser.eatToEndOfStatement();
4157 return Error(Loc, "unexpected token in argument list");
4159 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4160 SMLoc Loc = getLexer().getLoc();
4161 Parser.eatToEndOfStatement();
4162 return Error(Loc, "unexpected token, expected ']'");
4165 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4171 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4172 SMLoc NameLoc, OperandVector &Operands) {
4173 MCAsmParser &Parser = getParser();
4174 DEBUG(dbgs() << "ParseInstruction\n");
4176 // We have reached first instruction, module directive are now forbidden.
4177 getTargetStreamer().forbidModuleDirective();
4179 // Check if we have valid mnemonic
4180 if (!mnemonicIsValid(Name, 0)) {
4181 Parser.eatToEndOfStatement();
4182 return Error(NameLoc, "unknown instruction");
4184 // First operand in MCInst is instruction mnemonic.
4185 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4187 // Read the remaining operands.
4188 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4189 // Read the first operand.
4190 if (parseOperand(Operands, Name)) {
4191 SMLoc Loc = getLexer().getLoc();
4192 Parser.eatToEndOfStatement();
4193 return Error(Loc, "unexpected token in argument list");
4195 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4197 // AFAIK, parenthesis suffixes are never on the first operand
4199 while (getLexer().is(AsmToken::Comma)) {
4200 Parser.Lex(); // Eat the comma.
4201 // Parse and remember the operand.
4202 if (parseOperand(Operands, Name)) {
4203 SMLoc Loc = getLexer().getLoc();
4204 Parser.eatToEndOfStatement();
4205 return Error(Loc, "unexpected token in argument list");
4207 // Parse bracket and parenthesis suffixes before we iterate
4208 if (getLexer().is(AsmToken::LBrac)) {
4209 if (parseBracketSuffix(Name, Operands))
4211 } else if (getLexer().is(AsmToken::LParen) &&
4212 parseParenSuffix(Name, Operands))
4216 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4217 SMLoc Loc = getLexer().getLoc();
4218 Parser.eatToEndOfStatement();
4219 return Error(Loc, "unexpected token in argument list");
4221 Parser.Lex(); // Consume the EndOfStatement.
4225 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4226 MCAsmParser &Parser = getParser();
4227 SMLoc Loc = getLexer().getLoc();
4228 Parser.eatToEndOfStatement();
4229 return Error(Loc, ErrorMsg);
4232 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4233 return Error(Loc, ErrorMsg);
4236 bool MipsAsmParser::parseSetNoAtDirective() {
4237 MCAsmParser &Parser = getParser();
4238 // Line should look like: ".set noat".
4240 // Set the $at register to $0.
4241 AssemblerOptions.back()->setATRegIndex(0);
4243 Parser.Lex(); // Eat "noat".
4245 // If this is not the end of the statement, report an error.
4246 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4247 reportParseError("unexpected token, expected end of statement");
4251 getTargetStreamer().emitDirectiveSetNoAt();
4252 Parser.Lex(); // Consume the EndOfStatement.
4256 bool MipsAsmParser::parseSetAtDirective() {
4257 // Line can be: ".set at", which sets $at to $1
4258 // or ".set at=$reg", which sets $at to $reg.
4259 MCAsmParser &Parser = getParser();
4260 Parser.Lex(); // Eat "at".
4262 if (getLexer().is(AsmToken::EndOfStatement)) {
4263 // No register was specified, so we set $at to $1.
4264 AssemblerOptions.back()->setATRegIndex(1);
4266 getTargetStreamer().emitDirectiveSetAt();
4267 Parser.Lex(); // Consume the EndOfStatement.
4271 if (getLexer().isNot(AsmToken::Equal)) {
4272 reportParseError("unexpected token, expected equals sign");
4275 Parser.Lex(); // Eat "=".
4277 if (getLexer().isNot(AsmToken::Dollar)) {
4278 if (getLexer().is(AsmToken::EndOfStatement)) {
4279 reportParseError("no register specified");
4282 reportParseError("unexpected token, expected dollar sign '$'");
4286 Parser.Lex(); // Eat "$".
4288 // Find out what "reg" is.
4290 const AsmToken &Reg = Parser.getTok();
4291 if (Reg.is(AsmToken::Identifier)) {
4292 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4293 } else if (Reg.is(AsmToken::Integer)) {
4294 AtRegNo = Reg.getIntVal();
4296 reportParseError("unexpected token, expected identifier or integer");
4300 // Check if $reg is a valid register. If it is, set $at to $reg.
4301 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4302 reportParseError("invalid register");
4305 Parser.Lex(); // Eat "reg".
4307 // If this is not the end of the statement, report an error.
4308 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4309 reportParseError("unexpected token, expected end of statement");
4313 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4315 Parser.Lex(); // Consume the EndOfStatement.
4319 bool MipsAsmParser::parseSetReorderDirective() {
4320 MCAsmParser &Parser = getParser();
4322 // If this is not the end of the statement, report an error.
4323 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4324 reportParseError("unexpected token, expected end of statement");
4327 AssemblerOptions.back()->setReorder();
4328 getTargetStreamer().emitDirectiveSetReorder();
4329 Parser.Lex(); // Consume the EndOfStatement.
4333 bool MipsAsmParser::parseSetNoReorderDirective() {
4334 MCAsmParser &Parser = getParser();
4336 // If this is not the end of the statement, report an error.
4337 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4338 reportParseError("unexpected token, expected end of statement");
4341 AssemblerOptions.back()->setNoReorder();
4342 getTargetStreamer().emitDirectiveSetNoReorder();
4343 Parser.Lex(); // Consume the EndOfStatement.
4347 bool MipsAsmParser::parseSetMacroDirective() {
4348 MCAsmParser &Parser = getParser();
4350 // If this is not the end of the statement, report an error.
4351 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4352 reportParseError("unexpected token, expected end of statement");
4355 AssemblerOptions.back()->setMacro();
4356 getTargetStreamer().emitDirectiveSetMacro();
4357 Parser.Lex(); // Consume the EndOfStatement.
4361 bool MipsAsmParser::parseSetNoMacroDirective() {
4362 MCAsmParser &Parser = getParser();
4364 // If this is not the end of the statement, report an error.
4365 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4366 reportParseError("unexpected token, expected end of statement");
4369 if (AssemblerOptions.back()->isReorder()) {
4370 reportParseError("`noreorder' must be set before `nomacro'");
4373 AssemblerOptions.back()->setNoMacro();
4374 getTargetStreamer().emitDirectiveSetNoMacro();
4375 Parser.Lex(); // Consume the EndOfStatement.
4379 bool MipsAsmParser::parseSetMsaDirective() {
4380 MCAsmParser &Parser = getParser();
4383 // If this is not the end of the statement, report an error.
4384 if (getLexer().isNot(AsmToken::EndOfStatement))
4385 return reportParseError("unexpected token, expected end of statement");
4387 setFeatureBits(Mips::FeatureMSA, "msa");
4388 getTargetStreamer().emitDirectiveSetMsa();
4392 bool MipsAsmParser::parseSetNoMsaDirective() {
4393 MCAsmParser &Parser = getParser();
4396 // If this is not the end of the statement, report an error.
4397 if (getLexer().isNot(AsmToken::EndOfStatement))
4398 return reportParseError("unexpected token, expected end of statement");
4400 clearFeatureBits(Mips::FeatureMSA, "msa");
4401 getTargetStreamer().emitDirectiveSetNoMsa();
4405 bool MipsAsmParser::parseSetNoDspDirective() {
4406 MCAsmParser &Parser = getParser();
4407 Parser.Lex(); // Eat "nodsp".
4409 // If this is not the end of the statement, report an error.
4410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4411 reportParseError("unexpected token, expected end of statement");
4415 clearFeatureBits(Mips::FeatureDSP, "dsp");
4416 getTargetStreamer().emitDirectiveSetNoDsp();
4420 bool MipsAsmParser::parseSetMips16Directive() {
4421 MCAsmParser &Parser = getParser();
4422 Parser.Lex(); // Eat "mips16".
4424 // If this is not the end of the statement, report an error.
4425 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4426 reportParseError("unexpected token, expected end of statement");
4430 setFeatureBits(Mips::FeatureMips16, "mips16");
4431 getTargetStreamer().emitDirectiveSetMips16();
4432 Parser.Lex(); // Consume the EndOfStatement.
4436 bool MipsAsmParser::parseSetNoMips16Directive() {
4437 MCAsmParser &Parser = getParser();
4438 Parser.Lex(); // Eat "nomips16".
4440 // If this is not the end of the statement, report an error.
4441 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4442 reportParseError("unexpected token, expected end of statement");
4446 clearFeatureBits(Mips::FeatureMips16, "mips16");
4447 getTargetStreamer().emitDirectiveSetNoMips16();
4448 Parser.Lex(); // Consume the EndOfStatement.
4452 bool MipsAsmParser::parseSetFpDirective() {
4453 MCAsmParser &Parser = getParser();
4454 MipsABIFlagsSection::FpABIKind FpAbiVal;
4455 // Line can be: .set fp=32
4458 Parser.Lex(); // Eat fp token
4459 AsmToken Tok = Parser.getTok();
4460 if (Tok.isNot(AsmToken::Equal)) {
4461 reportParseError("unexpected token, expected equals sign '='");
4464 Parser.Lex(); // Eat '=' token.
4465 Tok = Parser.getTok();
4467 if (!parseFpABIValue(FpAbiVal, ".set"))
4470 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4471 reportParseError("unexpected token, expected end of statement");
4474 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4475 Parser.Lex(); // Consume the EndOfStatement.
4479 bool MipsAsmParser::parseSetOddSPRegDirective() {
4480 MCAsmParser &Parser = getParser();
4482 Parser.Lex(); // Eat "oddspreg".
4483 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4484 reportParseError("unexpected token, expected end of statement");
4488 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4489 getTargetStreamer().emitDirectiveSetOddSPReg();
4493 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4494 MCAsmParser &Parser = getParser();
4496 Parser.Lex(); // Eat "nooddspreg".
4497 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4498 reportParseError("unexpected token, expected end of statement");
4502 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4503 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4507 bool MipsAsmParser::parseSetPopDirective() {
4508 MCAsmParser &Parser = getParser();
4509 SMLoc Loc = getLexer().getLoc();
4512 if (getLexer().isNot(AsmToken::EndOfStatement))
4513 return reportParseError("unexpected token, expected end of statement");
4515 // Always keep an element on the options "stack" to prevent the user
4516 // from changing the initial options. This is how we remember them.
4517 if (AssemblerOptions.size() == 2)
4518 return reportParseError(Loc, ".set pop with no .set push");
4520 AssemblerOptions.pop_back();
4521 setAvailableFeatures(
4522 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4523 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4525 getTargetStreamer().emitDirectiveSetPop();
4529 bool MipsAsmParser::parseSetPushDirective() {
4530 MCAsmParser &Parser = getParser();
4532 if (getLexer().isNot(AsmToken::EndOfStatement))
4533 return reportParseError("unexpected token, expected end of statement");
4535 // Create a copy of the current assembler options environment and push it.
4536 AssemblerOptions.push_back(
4537 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4539 getTargetStreamer().emitDirectiveSetPush();
4543 bool MipsAsmParser::parseSetSoftFloatDirective() {
4544 MCAsmParser &Parser = getParser();
4546 if (getLexer().isNot(AsmToken::EndOfStatement))
4547 return reportParseError("unexpected token, expected end of statement");
4549 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4550 getTargetStreamer().emitDirectiveSetSoftFloat();
4554 bool MipsAsmParser::parseSetHardFloatDirective() {
4555 MCAsmParser &Parser = getParser();
4557 if (getLexer().isNot(AsmToken::EndOfStatement))
4558 return reportParseError("unexpected token, expected end of statement");
4560 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4561 getTargetStreamer().emitDirectiveSetHardFloat();
4565 bool MipsAsmParser::parseSetAssignment() {
4567 const MCExpr *Value;
4568 MCAsmParser &Parser = getParser();
4570 if (Parser.parseIdentifier(Name))
4571 reportParseError("expected identifier after .set");
4573 if (getLexer().isNot(AsmToken::Comma))
4574 return reportParseError("unexpected token, expected comma");
4577 if (Parser.parseExpression(Value))
4578 return reportParseError("expected valid expression after comma");
4580 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4581 Sym->setVariableValue(Value);
4586 bool MipsAsmParser::parseSetMips0Directive() {
4587 MCAsmParser &Parser = getParser();
4589 if (getLexer().isNot(AsmToken::EndOfStatement))
4590 return reportParseError("unexpected token, expected end of statement");
4592 // Reset assembler options to their initial values.
4593 setAvailableFeatures(
4594 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4595 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4596 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4598 getTargetStreamer().emitDirectiveSetMips0();
4602 bool MipsAsmParser::parseSetArchDirective() {
4603 MCAsmParser &Parser = getParser();
4605 if (getLexer().isNot(AsmToken::Equal))
4606 return reportParseError("unexpected token, expected equals sign");
4610 if (Parser.parseIdentifier(Arch))
4611 return reportParseError("expected arch identifier");
4613 StringRef ArchFeatureName =
4614 StringSwitch<StringRef>(Arch)
4615 .Case("mips1", "mips1")
4616 .Case("mips2", "mips2")
4617 .Case("mips3", "mips3")
4618 .Case("mips4", "mips4")
4619 .Case("mips5", "mips5")
4620 .Case("mips32", "mips32")
4621 .Case("mips32r2", "mips32r2")
4622 .Case("mips32r3", "mips32r3")
4623 .Case("mips32r5", "mips32r5")
4624 .Case("mips32r6", "mips32r6")
4625 .Case("mips64", "mips64")
4626 .Case("mips64r2", "mips64r2")
4627 .Case("mips64r3", "mips64r3")
4628 .Case("mips64r5", "mips64r5")
4629 .Case("mips64r6", "mips64r6")
4630 .Case("cnmips", "cnmips")
4631 .Case("r4000", "mips3") // This is an implementation of Mips3.
4634 if (ArchFeatureName.empty())
4635 return reportParseError("unsupported architecture");
4637 selectArch(ArchFeatureName);
4638 getTargetStreamer().emitDirectiveSetArch(Arch);
4642 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4643 MCAsmParser &Parser = getParser();
4645 if (getLexer().isNot(AsmToken::EndOfStatement))
4646 return reportParseError("unexpected token, expected end of statement");
4650 llvm_unreachable("Unimplemented feature");
4651 case Mips::FeatureDSP:
4652 setFeatureBits(Mips::FeatureDSP, "dsp");
4653 getTargetStreamer().emitDirectiveSetDsp();
4655 case Mips::FeatureMicroMips:
4656 getTargetStreamer().emitDirectiveSetMicroMips();
4658 case Mips::FeatureMips1:
4659 selectArch("mips1");
4660 getTargetStreamer().emitDirectiveSetMips1();
4662 case Mips::FeatureMips2:
4663 selectArch("mips2");
4664 getTargetStreamer().emitDirectiveSetMips2();
4666 case Mips::FeatureMips3:
4667 selectArch("mips3");
4668 getTargetStreamer().emitDirectiveSetMips3();
4670 case Mips::FeatureMips4:
4671 selectArch("mips4");
4672 getTargetStreamer().emitDirectiveSetMips4();
4674 case Mips::FeatureMips5:
4675 selectArch("mips5");
4676 getTargetStreamer().emitDirectiveSetMips5();
4678 case Mips::FeatureMips32:
4679 selectArch("mips32");
4680 getTargetStreamer().emitDirectiveSetMips32();
4682 case Mips::FeatureMips32r2:
4683 selectArch("mips32r2");
4684 getTargetStreamer().emitDirectiveSetMips32R2();
4686 case Mips::FeatureMips32r3:
4687 selectArch("mips32r3");
4688 getTargetStreamer().emitDirectiveSetMips32R3();
4690 case Mips::FeatureMips32r5:
4691 selectArch("mips32r5");
4692 getTargetStreamer().emitDirectiveSetMips32R5();
4694 case Mips::FeatureMips32r6:
4695 selectArch("mips32r6");
4696 getTargetStreamer().emitDirectiveSetMips32R6();
4698 case Mips::FeatureMips64:
4699 selectArch("mips64");
4700 getTargetStreamer().emitDirectiveSetMips64();
4702 case Mips::FeatureMips64r2:
4703 selectArch("mips64r2");
4704 getTargetStreamer().emitDirectiveSetMips64R2();
4706 case Mips::FeatureMips64r3:
4707 selectArch("mips64r3");
4708 getTargetStreamer().emitDirectiveSetMips64R3();
4710 case Mips::FeatureMips64r5:
4711 selectArch("mips64r5");
4712 getTargetStreamer().emitDirectiveSetMips64R5();
4714 case Mips::FeatureMips64r6:
4715 selectArch("mips64r6");
4716 getTargetStreamer().emitDirectiveSetMips64R6();
4722 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4723 MCAsmParser &Parser = getParser();
4724 if (getLexer().isNot(AsmToken::Comma)) {
4725 SMLoc Loc = getLexer().getLoc();
4726 Parser.eatToEndOfStatement();
4727 return Error(Loc, ErrorStr);
4730 Parser.Lex(); // Eat the comma.
4734 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4735 if (AssemblerOptions.back()->isReorder())
4736 Warning(Loc, ".cpload should be inside a noreorder section");
4738 if (inMips16Mode()) {
4739 reportParseError(".cpload is not supported in Mips16 mode");
4743 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4744 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4745 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4746 reportParseError("expected register containing function address");
4750 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4751 if (!RegOpnd.isGPRAsmReg()) {
4752 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4756 // If this is not the end of the statement, report an error.
4757 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4758 reportParseError("unexpected token, expected end of statement");
4762 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4766 bool MipsAsmParser::parseDirectiveCPSetup() {
4767 MCAsmParser &Parser = getParser();
4770 bool SaveIsReg = true;
4772 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4773 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4774 if (ResTy == MatchOperand_NoMatch) {
4775 reportParseError("expected register containing function address");
4776 Parser.eatToEndOfStatement();
4780 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4781 if (!FuncRegOpnd.isGPRAsmReg()) {
4782 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4783 Parser.eatToEndOfStatement();
4787 FuncReg = FuncRegOpnd.getGPR32Reg();
4790 if (!eatComma("unexpected token, expected comma"))
4793 ResTy = parseAnyRegister(TmpReg);
4794 if (ResTy == MatchOperand_NoMatch) {
4795 const AsmToken &Tok = Parser.getTok();
4796 if (Tok.is(AsmToken::Integer)) {
4797 Save = Tok.getIntVal();
4801 reportParseError("expected save register or stack offset");
4802 Parser.eatToEndOfStatement();
4806 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4807 if (!SaveOpnd.isGPRAsmReg()) {
4808 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4809 Parser.eatToEndOfStatement();
4812 Save = SaveOpnd.getGPR32Reg();
4815 if (!eatComma("unexpected token, expected comma"))
4819 if (Parser.parseExpression(Expr)) {
4820 reportParseError("expected expression");
4824 if (Expr->getKind() != MCExpr::SymbolRef) {
4825 reportParseError("expected symbol");
4828 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4830 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4835 bool MipsAsmParser::parseDirectiveNaN() {
4836 MCAsmParser &Parser = getParser();
4837 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4838 const AsmToken &Tok = Parser.getTok();
4840 if (Tok.getString() == "2008") {
4842 getTargetStreamer().emitDirectiveNaN2008();
4844 } else if (Tok.getString() == "legacy") {
4846 getTargetStreamer().emitDirectiveNaNLegacy();
4850 // If we don't recognize the option passed to the .nan
4851 // directive (e.g. no option or unknown option), emit an error.
4852 reportParseError("invalid option in .nan directive");
4856 bool MipsAsmParser::parseDirectiveSet() {
4857 MCAsmParser &Parser = getParser();
4858 // Get the next token.
4859 const AsmToken &Tok = Parser.getTok();
4861 if (Tok.getString() == "noat") {
4862 return parseSetNoAtDirective();
4863 } else if (Tok.getString() == "at") {
4864 return parseSetAtDirective();
4865 } else if (Tok.getString() == "arch") {
4866 return parseSetArchDirective();
4867 } else if (Tok.getString() == "fp") {
4868 return parseSetFpDirective();
4869 } else if (Tok.getString() == "oddspreg") {
4870 return parseSetOddSPRegDirective();
4871 } else if (Tok.getString() == "nooddspreg") {
4872 return parseSetNoOddSPRegDirective();
4873 } else if (Tok.getString() == "pop") {
4874 return parseSetPopDirective();
4875 } else if (Tok.getString() == "push") {
4876 return parseSetPushDirective();
4877 } else if (Tok.getString() == "reorder") {
4878 return parseSetReorderDirective();
4879 } else if (Tok.getString() == "noreorder") {
4880 return parseSetNoReorderDirective();
4881 } else if (Tok.getString() == "macro") {
4882 return parseSetMacroDirective();
4883 } else if (Tok.getString() == "nomacro") {
4884 return parseSetNoMacroDirective();
4885 } else if (Tok.getString() == "mips16") {
4886 return parseSetMips16Directive();
4887 } else if (Tok.getString() == "nomips16") {
4888 return parseSetNoMips16Directive();
4889 } else if (Tok.getString() == "nomicromips") {
4890 getTargetStreamer().emitDirectiveSetNoMicroMips();
4891 Parser.eatToEndOfStatement();
4893 } else if (Tok.getString() == "micromips") {
4894 return parseSetFeature(Mips::FeatureMicroMips);
4895 } else if (Tok.getString() == "mips0") {
4896 return parseSetMips0Directive();
4897 } else if (Tok.getString() == "mips1") {
4898 return parseSetFeature(Mips::FeatureMips1);
4899 } else if (Tok.getString() == "mips2") {
4900 return parseSetFeature(Mips::FeatureMips2);
4901 } else if (Tok.getString() == "mips3") {
4902 return parseSetFeature(Mips::FeatureMips3);
4903 } else if (Tok.getString() == "mips4") {
4904 return parseSetFeature(Mips::FeatureMips4);
4905 } else if (Tok.getString() == "mips5") {
4906 return parseSetFeature(Mips::FeatureMips5);
4907 } else if (Tok.getString() == "mips32") {
4908 return parseSetFeature(Mips::FeatureMips32);
4909 } else if (Tok.getString() == "mips32r2") {
4910 return parseSetFeature(Mips::FeatureMips32r2);
4911 } else if (Tok.getString() == "mips32r3") {
4912 return parseSetFeature(Mips::FeatureMips32r3);
4913 } else if (Tok.getString() == "mips32r5") {
4914 return parseSetFeature(Mips::FeatureMips32r5);
4915 } else if (Tok.getString() == "mips32r6") {
4916 return parseSetFeature(Mips::FeatureMips32r6);
4917 } else if (Tok.getString() == "mips64") {
4918 return parseSetFeature(Mips::FeatureMips64);
4919 } else if (Tok.getString() == "mips64r2") {
4920 return parseSetFeature(Mips::FeatureMips64r2);
4921 } else if (Tok.getString() == "mips64r3") {
4922 return parseSetFeature(Mips::FeatureMips64r3);
4923 } else if (Tok.getString() == "mips64r5") {
4924 return parseSetFeature(Mips::FeatureMips64r5);
4925 } else if (Tok.getString() == "mips64r6") {
4926 return parseSetFeature(Mips::FeatureMips64r6);
4927 } else if (Tok.getString() == "dsp") {
4928 return parseSetFeature(Mips::FeatureDSP);
4929 } else if (Tok.getString() == "nodsp") {
4930 return parseSetNoDspDirective();
4931 } else if (Tok.getString() == "msa") {
4932 return parseSetMsaDirective();
4933 } else if (Tok.getString() == "nomsa") {
4934 return parseSetNoMsaDirective();
4935 } else if (Tok.getString() == "softfloat") {
4936 return parseSetSoftFloatDirective();
4937 } else if (Tok.getString() == "hardfloat") {
4938 return parseSetHardFloatDirective();
4940 // It is just an identifier, look for an assignment.
4941 parseSetAssignment();
4948 /// parseDataDirective
4949 /// ::= .word [ expression (, expression)* ]
4950 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4951 MCAsmParser &Parser = getParser();
4952 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4954 const MCExpr *Value;
4955 if (getParser().parseExpression(Value))
4958 getParser().getStreamer().EmitValue(Value, Size);
4960 if (getLexer().is(AsmToken::EndOfStatement))
4963 if (getLexer().isNot(AsmToken::Comma))
4964 return Error(L, "unexpected token, expected comma");
4973 /// parseDirectiveGpWord
4974 /// ::= .gpword local_sym
4975 bool MipsAsmParser::parseDirectiveGpWord() {
4976 MCAsmParser &Parser = getParser();
4977 const MCExpr *Value;
4978 // EmitGPRel32Value requires an expression, so we are using base class
4979 // method to evaluate the expression.
4980 if (getParser().parseExpression(Value))
4982 getParser().getStreamer().EmitGPRel32Value(Value);
4984 if (getLexer().isNot(AsmToken::EndOfStatement))
4985 return Error(getLexer().getLoc(),
4986 "unexpected token, expected end of statement");
4987 Parser.Lex(); // Eat EndOfStatement token.
4991 /// parseDirectiveGpDWord
4992 /// ::= .gpdword local_sym
4993 bool MipsAsmParser::parseDirectiveGpDWord() {
4994 MCAsmParser &Parser = getParser();
4995 const MCExpr *Value;
4996 // EmitGPRel64Value requires an expression, so we are using base class
4997 // method to evaluate the expression.
4998 if (getParser().parseExpression(Value))
5000 getParser().getStreamer().EmitGPRel64Value(Value);
5002 if (getLexer().isNot(AsmToken::EndOfStatement))
5003 return Error(getLexer().getLoc(),
5004 "unexpected token, expected end of statement");
5005 Parser.Lex(); // Eat EndOfStatement token.
5009 bool MipsAsmParser::parseDirectiveOption() {
5010 MCAsmParser &Parser = getParser();
5011 // Get the option token.
5012 AsmToken Tok = Parser.getTok();
5013 // At the moment only identifiers are supported.
5014 if (Tok.isNot(AsmToken::Identifier)) {
5015 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5016 Parser.eatToEndOfStatement();
5020 StringRef Option = Tok.getIdentifier();
5022 if (Option == "pic0") {
5023 // MipsAsmParser needs to know if the current PIC mode changes.
5024 IsPicEnabled = false;
5026 getTargetStreamer().emitDirectiveOptionPic0();
5028 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5029 Error(Parser.getTok().getLoc(),
5030 "unexpected token, expected end of statement");
5031 Parser.eatToEndOfStatement();
5036 if (Option == "pic2") {
5037 // MipsAsmParser needs to know if the current PIC mode changes.
5038 IsPicEnabled = true;
5040 getTargetStreamer().emitDirectiveOptionPic2();
5042 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5043 Error(Parser.getTok().getLoc(),
5044 "unexpected token, expected end of statement");
5045 Parser.eatToEndOfStatement();
5051 Warning(Parser.getTok().getLoc(),
5052 "unknown option, expected 'pic0' or 'pic2'");
5053 Parser.eatToEndOfStatement();
5057 /// parseInsnDirective
5059 bool MipsAsmParser::parseInsnDirective() {
5060 // If this is not the end of the statement, report an error.
5061 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5062 reportParseError("unexpected token, expected end of statement");
5066 // The actual label marking happens in
5067 // MipsELFStreamer::createPendingLabelRelocs().
5068 getTargetStreamer().emitDirectiveInsn();
5070 getParser().Lex(); // Eat EndOfStatement token.
5074 /// parseDirectiveModule
5075 /// ::= .module oddspreg
5076 /// ::= .module nooddspreg
5077 /// ::= .module fp=value
5078 /// ::= .module softfloat
5079 /// ::= .module hardfloat
5080 bool MipsAsmParser::parseDirectiveModule() {
5081 MCAsmParser &Parser = getParser();
5082 MCAsmLexer &Lexer = getLexer();
5083 SMLoc L = Lexer.getLoc();
5085 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5086 // TODO : get a better message.
5087 reportParseError(".module directive must appear before any code");
5092 if (Parser.parseIdentifier(Option)) {
5093 reportParseError("expected .module option identifier");
5097 if (Option == "oddspreg") {
5098 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5100 // Synchronize the abiflags information with the FeatureBits information we
5102 getTargetStreamer().updateABIInfo(*this);
5104 // If printing assembly, use the recently updated abiflags information.
5105 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5106 // emitted at the end).
5107 getTargetStreamer().emitDirectiveModuleOddSPReg();
5109 // If this is not the end of the statement, report an error.
5110 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5111 reportParseError("unexpected token, expected end of statement");
5115 return false; // parseDirectiveModule has finished successfully.
5116 } else if (Option == "nooddspreg") {
5118 Error(L, "'.module nooddspreg' requires the O32 ABI");
5122 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5124 // Synchronize the abiflags information with the FeatureBits information we
5126 getTargetStreamer().updateABIInfo(*this);
5128 // If printing assembly, use the recently updated abiflags information.
5129 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5130 // emitted at the end).
5131 getTargetStreamer().emitDirectiveModuleOddSPReg();
5133 // If this is not the end of the statement, report an error.
5134 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5135 reportParseError("unexpected token, expected end of statement");
5139 return false; // parseDirectiveModule has finished successfully.
5140 } else if (Option == "fp") {
5141 return parseDirectiveModuleFP();
5142 } else if (Option == "softfloat") {
5143 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5145 // Synchronize the ABI Flags information with the FeatureBits information we
5147 getTargetStreamer().updateABIInfo(*this);
5149 // If printing assembly, use the recently updated ABI Flags information.
5150 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5152 getTargetStreamer().emitDirectiveModuleSoftFloat();
5154 // If this is not the end of the statement, report an error.
5155 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5156 reportParseError("unexpected token, expected end of statement");
5160 return false; // parseDirectiveModule has finished successfully.
5161 } else if (Option == "hardfloat") {
5162 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5164 // Synchronize the ABI Flags information with the FeatureBits information we
5166 getTargetStreamer().updateABIInfo(*this);
5168 // If printing assembly, use the recently updated ABI Flags information.
5169 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5171 getTargetStreamer().emitDirectiveModuleHardFloat();
5173 // If this is not the end of the statement, report an error.
5174 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5175 reportParseError("unexpected token, expected end of statement");
5179 return false; // parseDirectiveModule has finished successfully.
5181 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5185 /// parseDirectiveModuleFP
5189 bool MipsAsmParser::parseDirectiveModuleFP() {
5190 MCAsmParser &Parser = getParser();
5191 MCAsmLexer &Lexer = getLexer();
5193 if (Lexer.isNot(AsmToken::Equal)) {
5194 reportParseError("unexpected token, expected equals sign '='");
5197 Parser.Lex(); // Eat '=' token.
5199 MipsABIFlagsSection::FpABIKind FpABI;
5200 if (!parseFpABIValue(FpABI, ".module"))
5203 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5204 reportParseError("unexpected token, expected end of statement");
5208 // Synchronize the abiflags information with the FeatureBits information we
5210 getTargetStreamer().updateABIInfo(*this);
5212 // If printing assembly, use the recently updated abiflags information.
5213 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5214 // emitted at the end).
5215 getTargetStreamer().emitDirectiveModuleFP();
5217 Parser.Lex(); // Consume the EndOfStatement.
5221 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5222 StringRef Directive) {
5223 MCAsmParser &Parser = getParser();
5224 MCAsmLexer &Lexer = getLexer();
5225 bool ModuleLevelOptions = Directive == ".module";
5227 if (Lexer.is(AsmToken::Identifier)) {
5228 StringRef Value = Parser.getTok().getString();
5231 if (Value != "xx") {
5232 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5237 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5241 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5242 if (ModuleLevelOptions) {
5243 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5244 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5246 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5247 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5252 if (Lexer.is(AsmToken::Integer)) {
5253 unsigned Value = Parser.getTok().getIntVal();
5256 if (Value != 32 && Value != 64) {
5257 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5263 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5267 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5268 if (ModuleLevelOptions) {
5269 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5270 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5272 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5273 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5276 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5277 if (ModuleLevelOptions) {
5278 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5279 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5281 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5282 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5292 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5293 MCAsmParser &Parser = getParser();
5294 StringRef IDVal = DirectiveID.getString();
5296 if (IDVal == ".cpload")
5297 return parseDirectiveCpLoad(DirectiveID.getLoc());
5298 if (IDVal == ".dword") {
5299 parseDataDirective(8, DirectiveID.getLoc());
5302 if (IDVal == ".ent") {
5303 StringRef SymbolName;
5305 if (Parser.parseIdentifier(SymbolName)) {
5306 reportParseError("expected identifier after .ent");
5310 // There's an undocumented extension that allows an integer to
5311 // follow the name of the procedure which AFAICS is ignored by GAS.
5312 // Example: .ent foo,2
5313 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5314 if (getLexer().isNot(AsmToken::Comma)) {
5315 // Even though we accept this undocumented extension for compatibility
5316 // reasons, the additional integer argument does not actually change
5317 // the behaviour of the '.ent' directive, so we would like to discourage
5318 // its use. We do this by not referring to the extended version in
5319 // error messages which are not directly related to its use.
5320 reportParseError("unexpected token, expected end of statement");
5323 Parser.Lex(); // Eat the comma.
5324 const MCExpr *DummyNumber;
5325 int64_t DummyNumberVal;
5326 // If the user was explicitly trying to use the extended version,
5327 // we still give helpful extension-related error messages.
5328 if (Parser.parseExpression(DummyNumber)) {
5329 reportParseError("expected number after comma");
5332 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5333 reportParseError("expected an absolute expression after comma");
5338 // If this is not the end of the statement, report an error.
5339 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5340 reportParseError("unexpected token, expected end of statement");
5344 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5346 getTargetStreamer().emitDirectiveEnt(*Sym);
5351 if (IDVal == ".end") {
5352 StringRef SymbolName;
5354 if (Parser.parseIdentifier(SymbolName)) {
5355 reportParseError("expected identifier after .end");
5359 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5360 reportParseError("unexpected token, expected end of statement");
5364 if (CurrentFn == nullptr) {
5365 reportParseError(".end used without .ent");
5369 if ((SymbolName != CurrentFn->getName())) {
5370 reportParseError(".end symbol does not match .ent symbol");
5374 getTargetStreamer().emitDirectiveEnd(SymbolName);
5375 CurrentFn = nullptr;
5379 if (IDVal == ".frame") {
5380 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5381 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5382 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5383 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5384 reportParseError("expected stack register");
5388 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5389 if (!StackRegOpnd.isGPRAsmReg()) {
5390 reportParseError(StackRegOpnd.getStartLoc(),
5391 "expected general purpose register");
5394 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5396 if (Parser.getTok().is(AsmToken::Comma))
5399 reportParseError("unexpected token, expected comma");
5403 // Parse the frame size.
5404 const MCExpr *FrameSize;
5405 int64_t FrameSizeVal;
5407 if (Parser.parseExpression(FrameSize)) {
5408 reportParseError("expected frame size value");
5412 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5413 reportParseError("frame size not an absolute expression");
5417 if (Parser.getTok().is(AsmToken::Comma))
5420 reportParseError("unexpected token, expected comma");
5424 // Parse the return register.
5426 ResTy = parseAnyRegister(TmpReg);
5427 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5428 reportParseError("expected return register");
5432 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5433 if (!ReturnRegOpnd.isGPRAsmReg()) {
5434 reportParseError(ReturnRegOpnd.getStartLoc(),
5435 "expected general purpose 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().emitFrame(StackReg, FrameSizeVal,
5446 ReturnRegOpnd.getGPR32Reg());
5450 if (IDVal == ".set") {
5451 return parseDirectiveSet();
5454 if (IDVal == ".mask" || IDVal == ".fmask") {
5455 // .mask bitmask, frame_offset
5456 // bitmask: One bit for each register used.
5457 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5458 // first register is expected to be saved.
5460 // .mask 0x80000000, -4
5461 // .fmask 0x80000000, -4
5464 // Parse the bitmask
5465 const MCExpr *BitMask;
5468 if (Parser.parseExpression(BitMask)) {
5469 reportParseError("expected bitmask value");
5473 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5474 reportParseError("bitmask not an absolute expression");
5478 if (Parser.getTok().is(AsmToken::Comma))
5481 reportParseError("unexpected token, expected comma");
5485 // Parse the frame_offset
5486 const MCExpr *FrameOffset;
5487 int64_t FrameOffsetVal;
5489 if (Parser.parseExpression(FrameOffset)) {
5490 reportParseError("expected frame offset value");
5494 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5495 reportParseError("frame offset not an absolute expression");
5499 // If this is not the end of the statement, report an error.
5500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5501 reportParseError("unexpected token, expected end of statement");
5505 if (IDVal == ".mask")
5506 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5508 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5512 if (IDVal == ".nan")
5513 return parseDirectiveNaN();
5515 if (IDVal == ".gpword") {
5516 parseDirectiveGpWord();
5520 if (IDVal == ".gpdword") {
5521 parseDirectiveGpDWord();
5525 if (IDVal == ".word") {
5526 parseDataDirective(4, DirectiveID.getLoc());
5530 if (IDVal == ".option")
5531 return parseDirectiveOption();
5533 if (IDVal == ".abicalls") {
5534 getTargetStreamer().emitDirectiveAbiCalls();
5535 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5536 Error(Parser.getTok().getLoc(),
5537 "unexpected token, expected end of statement");
5539 Parser.eatToEndOfStatement();
5544 if (IDVal == ".cpsetup")
5545 return parseDirectiveCPSetup();
5547 if (IDVal == ".module")
5548 return parseDirectiveModule();
5550 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5551 return parseInternalDirectiveReallowModule();
5553 if (IDVal == ".insn")
5554 return parseInsnDirective();
5559 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5560 // If this is not the end of the statement, report an error.
5561 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5562 reportParseError("unexpected token, expected end of statement");
5566 getTargetStreamer().reallowModuleDirective();
5568 getParser().Lex(); // Eat EndOfStatement token.
5572 extern "C" void LLVMInitializeMipsAsmParser() {
5573 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5574 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5575 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5576 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5579 #define GET_REGISTER_MATCHER
5580 #define GET_MATCHER_IMPLEMENTATION
5581 #include "MipsGenAsmMatcher.inc"