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 expandUlhu(MCInst &Inst, SMLoc IDLoc,
220 SmallVectorImpl<MCInst> &Instructions);
222 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
223 SmallVectorImpl<MCInst> &Instructions);
225 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
226 SmallVectorImpl<MCInst> &Instructions);
228 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
229 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
231 bool reportParseError(Twine ErrorMsg);
232 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
234 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
235 bool parseRelocOperand(const MCExpr *&Res);
237 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
239 bool isEvaluated(const MCExpr *Expr);
240 bool parseSetMips0Directive();
241 bool parseSetArchDirective();
242 bool parseSetFeature(uint64_t Feature);
243 bool parseDirectiveCpLoad(SMLoc Loc);
244 bool parseDirectiveCPSetup();
245 bool parseDirectiveNaN();
246 bool parseDirectiveSet();
247 bool parseDirectiveOption();
248 bool parseInsnDirective();
250 bool parseSetAtDirective();
251 bool parseSetNoAtDirective();
252 bool parseSetMacroDirective();
253 bool parseSetNoMacroDirective();
254 bool parseSetMsaDirective();
255 bool parseSetNoMsaDirective();
256 bool parseSetNoDspDirective();
257 bool parseSetReorderDirective();
258 bool parseSetNoReorderDirective();
259 bool parseSetMips16Directive();
260 bool parseSetNoMips16Directive();
261 bool parseSetFpDirective();
262 bool parseSetOddSPRegDirective();
263 bool parseSetNoOddSPRegDirective();
264 bool parseSetPopDirective();
265 bool parseSetPushDirective();
266 bool parseSetSoftFloatDirective();
267 bool parseSetHardFloatDirective();
269 bool parseSetAssignment();
271 bool parseDataDirective(unsigned Size, SMLoc L);
272 bool parseDirectiveGpWord();
273 bool parseDirectiveGpDWord();
274 bool parseDirectiveModule();
275 bool parseDirectiveModuleFP();
276 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
277 StringRef Directive);
279 bool parseInternalDirectiveReallowModule();
281 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
283 bool eatComma(StringRef ErrorStr);
285 int matchCPURegisterName(StringRef Symbol);
287 int matchHWRegsRegisterName(StringRef Symbol);
289 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
291 int matchFPURegisterName(StringRef Name);
293 int matchFCCRegisterName(StringRef Name);
295 int matchACRegisterName(StringRef Name);
297 int matchMSA128RegisterName(StringRef Name);
299 int matchMSA128CtrlRegisterName(StringRef Name);
301 unsigned getReg(int RC, int RegNo);
303 unsigned getGPR(int RegNo);
305 /// Returns the internal register number for the current AT. Also checks if
306 /// the current AT is unavailable (set to $0) and gives an error if it is.
307 /// This should be used in pseudo-instruction expansions which need AT.
308 unsigned getATReg(SMLoc Loc);
310 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
311 SmallVectorImpl<MCInst> &Instructions);
313 // Helper function that checks if the value of a vector index is within the
314 // boundaries of accepted values for each RegisterKind
315 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
316 bool validateMSAIndex(int Val, int RegKind);
318 // Selects a new architecture by updating the FeatureBits with the necessary
319 // info including implied dependencies.
320 // Internally, it clears all the feature bits related to *any* architecture
321 // and selects the new one using the ToggleFeature functionality of the
322 // MCSubtargetInfo object that handles implied dependencies. The reason we
323 // clear all the arch related bits manually is because ToggleFeature only
324 // clears the features that imply the feature being cleared and not the
325 // features implied by the feature being cleared. This is easier to see
327 // --------------------------------------------------
328 // | Feature | Implies |
329 // | -------------------------------------------------|
330 // | FeatureMips1 | None |
331 // | FeatureMips2 | FeatureMips1 |
332 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
333 // | FeatureMips4 | FeatureMips3 |
335 // --------------------------------------------------
337 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
338 // FeatureMipsGP64 | FeatureMips1)
339 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
340 void selectArch(StringRef ArchFeature) {
341 FeatureBitset FeatureBits = STI.getFeatureBits();
342 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
343 STI.setFeatureBits(FeatureBits);
344 setAvailableFeatures(
345 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
346 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
349 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
350 if (!(STI.getFeatureBits()[Feature])) {
351 setAvailableFeatures(
352 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
353 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
357 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
358 if (STI.getFeatureBits()[Feature]) {
359 setAvailableFeatures(
360 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
361 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
365 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
366 setFeatureBits(Feature, FeatureString);
367 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
370 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
371 clearFeatureBits(Feature, FeatureString);
372 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
376 enum MipsMatchResultTy {
377 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
378 #define GET_OPERAND_DIAGNOSTIC_TYPES
379 #include "MipsGenAsmMatcher.inc"
380 #undef GET_OPERAND_DIAGNOSTIC_TYPES
384 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
385 const MCInstrInfo &MII, const MCTargetOptions &Options)
386 : MCTargetAsmParser(Options), STI(sti),
387 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
388 sti.getCPU(), Options)) {
389 MCAsmParserExtension::Initialize(parser);
391 parser.addAliasForDirective(".asciiz", ".asciz");
393 // Initialize the set of available features.
394 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
396 // Remember the initial assembler options. The user can not modify these.
397 AssemblerOptions.push_back(
398 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
400 // Create an assembler options environment for the user to modify.
401 AssemblerOptions.push_back(
402 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
404 getTargetStreamer().updateABIInfo(*this);
406 if (!isABI_O32() && !useOddSPReg() != 0)
407 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
412 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
414 Triple TheTriple(sti.getTargetTriple());
415 if ((TheTriple.getArch() == Triple::mips) ||
416 (TheTriple.getArch() == Triple::mips64))
417 IsLittleEndian = false;
419 IsLittleEndian = true;
422 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
423 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
425 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
426 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
427 const MipsABIInfo &getABI() const { return ABI; }
428 bool isABI_N32() const { return ABI.IsN32(); }
429 bool isABI_N64() const { return ABI.IsN64(); }
430 bool isABI_O32() const { return ABI.IsO32(); }
431 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
433 bool useOddSPReg() const {
434 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
437 bool inMicroMipsMode() const {
438 return STI.getFeatureBits()[Mips::FeatureMicroMips];
440 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
441 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
442 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
443 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
444 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
445 bool hasMips32() const {
446 return STI.getFeatureBits()[Mips::FeatureMips32];
448 bool hasMips64() const {
449 return STI.getFeatureBits()[Mips::FeatureMips64];
451 bool hasMips32r2() const {
452 return STI.getFeatureBits()[Mips::FeatureMips32r2];
454 bool hasMips64r2() const {
455 return STI.getFeatureBits()[Mips::FeatureMips64r2];
457 bool hasMips32r3() const {
458 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
460 bool hasMips64r3() const {
461 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
463 bool hasMips32r5() const {
464 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
466 bool hasMips64r5() const {
467 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
469 bool hasMips32r6() const {
470 return STI.getFeatureBits()[Mips::FeatureMips32r6];
472 bool hasMips64r6() const {
473 return STI.getFeatureBits()[Mips::FeatureMips64r6];
476 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
477 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
478 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
479 bool hasCnMips() const {
480 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
487 bool inMips16Mode() const {
488 return STI.getFeatureBits()[Mips::FeatureMips16];
491 bool useSoftFloat() const {
492 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
495 /// Warn if RegIndex is the same as the current AT.
496 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
498 void warnIfNoMacro(SMLoc Loc);
500 bool isLittle() const { return IsLittleEndian; }
506 /// MipsOperand - Instances of this class represent a parsed Mips machine
508 class MipsOperand : public MCParsedAsmOperand {
510 /// Broad categories of register classes
511 /// The exact class is finalized by the render method.
513 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
514 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
516 RegKind_FCC = 4, /// FCC
517 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
518 RegKind_MSACtrl = 16, /// MSA control registers
519 RegKind_COP2 = 32, /// COP2
520 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
522 RegKind_CCR = 128, /// CCR
523 RegKind_HWRegs = 256, /// HWRegs
524 RegKind_COP3 = 512, /// COP3
525 RegKind_COP0 = 1024, /// COP0
526 /// Potentially any (e.g. $1)
527 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
528 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
529 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
534 k_Immediate, /// An immediate (possibly involving symbol references)
535 k_Memory, /// Base + Offset Memory Address
536 k_PhysRegister, /// A physical register from the Mips namespace
537 k_RegisterIndex, /// A register index in one or more RegKind.
538 k_Token, /// A simple token
539 k_RegList, /// A physical register list
540 k_RegPair /// A pair of physical register
544 MipsOperand(KindTy K, MipsAsmParser &Parser)
545 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
548 /// For diagnostics, and checking the assembler temporary
549 MipsAsmParser &AsmParser;
557 unsigned Num; /// Register Number
561 unsigned Index; /// Index into the register class
562 RegKind Kind; /// Bitfield of the kinds it could possibly be
563 const MCRegisterInfo *RegInfo;
576 SmallVector<unsigned, 10> *List;
581 struct PhysRegOp PhysReg;
582 struct RegIdxOp RegIdx;
585 struct RegListOp RegList;
588 SMLoc StartLoc, EndLoc;
590 /// Internal constructor for register kinds
591 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
592 const MCRegisterInfo *RegInfo,
594 MipsAsmParser &Parser) {
595 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
596 Op->RegIdx.Index = Index;
597 Op->RegIdx.RegInfo = RegInfo;
598 Op->RegIdx.Kind = RegKind;
605 /// Coerce the register to GPR32 and return the real register for the current
607 unsigned getGPR32Reg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
609 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
610 unsigned ClassID = Mips::GPR32RegClassID;
611 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
614 /// Coerce the register to GPR32 and return the real register for the current
616 unsigned getGPRMM16Reg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
618 unsigned ClassID = Mips::GPR32RegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
622 /// Coerce the register to GPR64 and return the real register for the current
624 unsigned getGPR64Reg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
626 unsigned ClassID = Mips::GPR64RegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
631 /// Coerce the register to AFGR64 and return the real register for the current
633 unsigned getAFGR64Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
635 if (RegIdx.Index % 2 != 0)
636 AsmParser.Warning(StartLoc, "Float register should be even.");
637 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
638 .getRegister(RegIdx.Index / 2);
641 /// Coerce the register to FGR64 and return the real register for the current
643 unsigned getFGR64Reg() const {
644 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
645 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
646 .getRegister(RegIdx.Index);
649 /// Coerce the register to FGR32 and return the real register for the current
651 unsigned getFGR32Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
653 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
654 .getRegister(RegIdx.Index);
657 /// Coerce the register to FGRH32 and return the real register for the current
659 unsigned getFGRH32Reg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
661 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
662 .getRegister(RegIdx.Index);
665 /// Coerce the register to FCC and return the real register for the current
667 unsigned getFCCReg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
669 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
670 .getRegister(RegIdx.Index);
673 /// Coerce the register to MSA128 and return the real register for the current
675 unsigned getMSA128Reg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
677 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
679 unsigned ClassID = Mips::MSA128BRegClassID;
680 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
683 /// Coerce the register to MSACtrl and return the real register for the
685 unsigned getMSACtrlReg() const {
686 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
687 unsigned ClassID = Mips::MSACtrlRegClassID;
688 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
691 /// Coerce the register to COP0 and return the real register for the
693 unsigned getCOP0Reg() const {
694 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
695 unsigned ClassID = Mips::COP0RegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
699 /// Coerce the register to COP2 and return the real register for the
701 unsigned getCOP2Reg() const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
703 unsigned ClassID = Mips::COP2RegClassID;
704 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
707 /// Coerce the register to COP3 and return the real register for the
709 unsigned getCOP3Reg() const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
711 unsigned ClassID = Mips::COP3RegClassID;
712 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
715 /// Coerce the register to ACC64DSP and return the real register for the
717 unsigned getACC64DSPReg() const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
719 unsigned ClassID = Mips::ACC64DSPRegClassID;
720 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
723 /// Coerce the register to HI32DSP and return the real register for the
725 unsigned getHI32DSPReg() const {
726 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
727 unsigned ClassID = Mips::HI32DSPRegClassID;
728 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
731 /// Coerce the register to LO32DSP and return the real register for the
733 unsigned getLO32DSPReg() const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
735 unsigned ClassID = Mips::LO32DSPRegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 /// Coerce the register to CCR and return the real register for the
741 unsigned getCCRReg() const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
743 unsigned ClassID = Mips::CCRRegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
747 /// Coerce the register to HWRegs and return the real register for the
749 unsigned getHWRegsReg() const {
750 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
751 unsigned ClassID = Mips::HWRegsRegClassID;
752 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
756 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
757 // Add as immediate when possible. Null MCExpr = 0.
759 Inst.addOperand(MCOperand::createImm(0));
760 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
761 Inst.addOperand(MCOperand::createImm(CE->getValue()));
763 Inst.addOperand(MCOperand::createExpr(Expr));
766 void addRegOperands(MCInst &Inst, unsigned N) const {
767 llvm_unreachable("Use a custom parser instead");
770 /// Render the operand to an MCInst as a GPR32
771 /// Asserts if the wrong number of operands are requested, or the operand
772 /// is not a k_RegisterIndex compatible with RegKind_GPR
773 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
778 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
783 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
788 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
793 /// Render the operand to an MCInst as a GPR64
794 /// Asserts if the wrong number of operands are requested, or the operand
795 /// is not a k_RegisterIndex compatible with RegKind_GPR
796 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
801 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
802 assert(N == 1 && "Invalid number of operands!");
803 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
806 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
807 assert(N == 1 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
811 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
812 assert(N == 1 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
814 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
815 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
816 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
820 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 1 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
825 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
826 assert(N == 1 && "Invalid number of operands!");
827 Inst.addOperand(MCOperand::createReg(getFCCReg()));
830 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
831 assert(N == 1 && "Invalid number of operands!");
832 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
835 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
836 assert(N == 1 && "Invalid number of operands!");
837 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
840 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
841 assert(N == 1 && "Invalid number of operands!");
842 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
845 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
846 assert(N == 1 && "Invalid number of operands!");
847 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
850 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 1 && "Invalid number of operands!");
852 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
855 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
856 assert(N == 1 && "Invalid number of operands!");
857 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
860 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
861 assert(N == 1 && "Invalid number of operands!");
862 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
865 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
866 assert(N == 1 && "Invalid number of operands!");
867 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
870 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
871 assert(N == 1 && "Invalid number of operands!");
872 Inst.addOperand(MCOperand::createReg(getCCRReg()));
875 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
876 assert(N == 1 && "Invalid number of operands!");
877 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
880 void addImmOperands(MCInst &Inst, unsigned N) const {
881 assert(N == 1 && "Invalid number of operands!");
882 const MCExpr *Expr = getImm();
886 void addMemOperands(MCInst &Inst, unsigned N) const {
887 assert(N == 2 && "Invalid number of operands!");
889 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
890 ? getMemBase()->getGPR64Reg()
891 : getMemBase()->getGPR32Reg()));
893 const MCExpr *Expr = getMemOff();
897 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
898 assert(N == 2 && "Invalid number of operands!");
900 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
902 const MCExpr *Expr = getMemOff();
906 void addRegListOperands(MCInst &Inst, unsigned N) const {
907 assert(N == 1 && "Invalid number of operands!");
909 for (auto RegNo : getRegList())
910 Inst.addOperand(MCOperand::createReg(RegNo));
913 void addRegPairOperands(MCInst &Inst, unsigned N) const {
914 assert(N == 2 && "Invalid number of operands!");
915 unsigned RegNo = getRegPair();
916 Inst.addOperand(MCOperand::createReg(RegNo++));
917 Inst.addOperand(MCOperand::createReg(RegNo));
920 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
921 assert(N == 2 && "Invalid number of operands!");
922 for (auto RegNo : getRegList())
923 Inst.addOperand(MCOperand::createReg(RegNo));
926 bool isReg() const override {
927 // As a special case until we sort out the definition of div/divu, pretend
928 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
929 if (isGPRAsmReg() && RegIdx.Index == 0)
932 return Kind == k_PhysRegister;
934 bool isRegIdx() const { return Kind == k_RegisterIndex; }
935 bool isImm() const override { return Kind == k_Immediate; }
936 bool isConstantImm() const {
937 return isImm() && dyn_cast<MCConstantExpr>(getImm());
939 template <unsigned Bits> bool isUImm() const {
940 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
942 bool isToken() const override {
943 // Note: It's not possible to pretend that other operand kinds are tokens.
944 // The matcher emitter checks tokens first.
945 return Kind == k_Token;
947 bool isMem() const override { return Kind == k_Memory; }
948 bool isConstantMemOff() const {
949 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
951 template <unsigned Bits> bool isMemWithSimmOffset() const {
952 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
954 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
955 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
956 && getMemBase()->isGPRAsmReg();
958 bool isMemWithGRPMM16Base() const {
959 return isMem() && getMemBase()->isMM16AsmReg();
961 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
962 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
963 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
965 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
966 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
967 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
968 && (getMemBase()->getGPR32Reg() == Mips::SP);
970 bool isRegList16() const {
974 int Size = RegList.List->size();
975 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
976 RegList.List->back() != Mips::RA)
979 int PrevReg = *RegList.List->begin();
980 for (int i = 1; i < Size - 1; i++) {
981 int Reg = (*(RegList.List))[i];
982 if ( Reg != PrevReg + 1)
989 bool isInvNum() const { return Kind == k_Immediate; }
990 bool isLSAImm() const {
991 if (!isConstantImm())
993 int64_t Val = getConstantImm();
994 return 1 <= Val && Val <= 4;
996 bool isRegList() const { return Kind == k_RegList; }
997 bool isMovePRegPair() const {
998 if (Kind != k_RegList || RegList.List->size() != 2)
1001 unsigned R0 = RegList.List->front();
1002 unsigned R1 = RegList.List->back();
1004 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1005 (R0 == Mips::A1 && R1 == Mips::A3) ||
1006 (R0 == Mips::A2 && R1 == Mips::A3) ||
1007 (R0 == Mips::A0 && R1 == Mips::S5) ||
1008 (R0 == Mips::A0 && R1 == Mips::S6) ||
1009 (R0 == Mips::A0 && R1 == Mips::A1) ||
1010 (R0 == Mips::A0 && R1 == Mips::A2) ||
1011 (R0 == Mips::A0 && R1 == Mips::A3))
1017 StringRef getToken() const {
1018 assert(Kind == k_Token && "Invalid access!");
1019 return StringRef(Tok.Data, Tok.Length);
1021 bool isRegPair() const { return Kind == k_RegPair; }
1023 unsigned getReg() const override {
1024 // As a special case until we sort out the definition of div/divu, pretend
1025 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1026 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1027 RegIdx.Kind & RegKind_GPR)
1028 return getGPR32Reg(); // FIXME: GPR64 too
1030 assert(Kind == k_PhysRegister && "Invalid access!");
1034 const MCExpr *getImm() const {
1035 assert((Kind == k_Immediate) && "Invalid access!");
1039 int64_t getConstantImm() const {
1040 const MCExpr *Val = getImm();
1041 return static_cast<const MCConstantExpr *>(Val)->getValue();
1044 MipsOperand *getMemBase() const {
1045 assert((Kind == k_Memory) && "Invalid access!");
1049 const MCExpr *getMemOff() const {
1050 assert((Kind == k_Memory) && "Invalid access!");
1054 int64_t getConstantMemOff() const {
1055 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1058 const SmallVectorImpl<unsigned> &getRegList() const {
1059 assert((Kind == k_RegList) && "Invalid access!");
1060 return *(RegList.List);
1063 unsigned getRegPair() const {
1064 assert((Kind == k_RegPair) && "Invalid access!");
1065 return RegIdx.Index;
1068 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1069 MipsAsmParser &Parser) {
1070 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1071 Op->Tok.Data = Str.data();
1072 Op->Tok.Length = Str.size();
1078 /// Create a numeric register (e.g. $1). The exact register remains
1079 /// unresolved until an instruction successfully matches
1080 static std::unique_ptr<MipsOperand>
1081 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1082 SMLoc E, MipsAsmParser &Parser) {
1083 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1084 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1087 /// Create a register that is definitely a GPR.
1088 /// This is typically only used for named registers such as $gp.
1089 static std::unique_ptr<MipsOperand>
1090 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1091 MipsAsmParser &Parser) {
1092 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1095 /// Create a register that is definitely a FGR.
1096 /// This is typically only used for named registers such as $f0.
1097 static std::unique_ptr<MipsOperand>
1098 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1099 MipsAsmParser &Parser) {
1100 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1103 /// Create a register that is definitely a HWReg.
1104 /// This is typically only used for named registers such as $hwr_cpunum.
1105 static std::unique_ptr<MipsOperand>
1106 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1107 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1108 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1111 /// Create a register that is definitely an FCC.
1112 /// This is typically only used for named registers such as $fcc0.
1113 static std::unique_ptr<MipsOperand>
1114 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1115 MipsAsmParser &Parser) {
1116 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1119 /// Create a register that is definitely an ACC.
1120 /// This is typically only used for named registers such as $ac0.
1121 static std::unique_ptr<MipsOperand>
1122 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1123 MipsAsmParser &Parser) {
1124 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1127 /// Create a register that is definitely an MSA128.
1128 /// This is typically only used for named registers such as $w0.
1129 static std::unique_ptr<MipsOperand>
1130 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1131 SMLoc E, MipsAsmParser &Parser) {
1132 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1135 /// Create a register that is definitely an MSACtrl.
1136 /// This is typically only used for named registers such as $msaaccess.
1137 static std::unique_ptr<MipsOperand>
1138 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1139 SMLoc E, MipsAsmParser &Parser) {
1140 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1143 static std::unique_ptr<MipsOperand>
1144 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1145 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1152 static std::unique_ptr<MipsOperand>
1153 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1154 SMLoc E, MipsAsmParser &Parser) {
1155 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1156 Op->Mem.Base = Base.release();
1163 static std::unique_ptr<MipsOperand>
1164 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1165 MipsAsmParser &Parser) {
1166 assert (Regs.size() > 0 && "Empty list not allowed");
1168 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1169 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1170 Op->StartLoc = StartLoc;
1171 Op->EndLoc = EndLoc;
1175 static std::unique_ptr<MipsOperand>
1176 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1177 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1178 Op->RegIdx.Index = RegNo;
1184 bool isGPRAsmReg() const {
1185 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1187 bool isMM16AsmReg() const {
1188 if (!(isRegIdx() && RegIdx.Kind))
1190 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1191 || RegIdx.Index == 16 || RegIdx.Index == 17);
1193 bool isMM16AsmRegZero() const {
1194 if (!(isRegIdx() && RegIdx.Kind))
1196 return (RegIdx.Index == 0 ||
1197 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1198 RegIdx.Index == 17);
1200 bool isMM16AsmRegMoveP() const {
1201 if (!(isRegIdx() && RegIdx.Kind))
1203 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1204 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1206 bool isFGRAsmReg() const {
1207 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1208 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1210 bool isHWRegsAsmReg() const {
1211 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1213 bool isCCRAsmReg() const {
1214 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1216 bool isFCCAsmReg() const {
1217 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1219 if (!AsmParser.hasEightFccRegisters())
1220 return RegIdx.Index == 0;
1221 return RegIdx.Index <= 7;
1223 bool isACCAsmReg() const {
1224 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1226 bool isCOP0AsmReg() const {
1227 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1229 bool isCOP2AsmReg() const {
1230 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1232 bool isCOP3AsmReg() const {
1233 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1235 bool isMSA128AsmReg() const {
1236 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1238 bool isMSACtrlAsmReg() const {
1239 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1242 /// getStartLoc - Get the location of the first token of this operand.
1243 SMLoc getStartLoc() const override { return StartLoc; }
1244 /// getEndLoc - Get the location of the last token of this operand.
1245 SMLoc getEndLoc() const override { return EndLoc; }
1247 virtual ~MipsOperand() {
1255 delete RegList.List;
1256 case k_PhysRegister:
1257 case k_RegisterIndex:
1264 void print(raw_ostream &OS) const override {
1273 Mem.Base->print(OS);
1278 case k_PhysRegister:
1279 OS << "PhysReg<" << PhysReg.Num << ">";
1281 case k_RegisterIndex:
1282 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1289 for (auto Reg : (*RegList.List))
1294 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1298 }; // class MipsOperand
1302 extern const MCInstrDesc MipsInsts[];
1304 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1305 return MipsInsts[Opcode];
1308 static bool hasShortDelaySlot(unsigned Opcode) {
1311 case Mips::JALRS_MM:
1312 case Mips::JALRS16_MM:
1313 case Mips::BGEZALS_MM:
1314 case Mips::BLTZALS_MM:
1321 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1322 SmallVectorImpl<MCInst> &Instructions) {
1323 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1327 if (MCID.isBranch() || MCID.isCall()) {
1328 const unsigned Opcode = Inst.getOpcode();
1338 assert(hasCnMips() && "instruction only valid for octeon cpus");
1345 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1346 Offset = Inst.getOperand(2);
1347 if (!Offset.isImm())
1348 break; // We'll deal with this situation later on when applying fixups.
1349 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1350 return Error(IDLoc, "branch target out of range");
1351 if (OffsetToAlignment(Offset.getImm(),
1352 1LL << (inMicroMipsMode() ? 1 : 2)))
1353 return Error(IDLoc, "branch to misaligned address");
1367 case Mips::BGEZAL_MM:
1368 case Mips::BLTZAL_MM:
1371 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1372 Offset = Inst.getOperand(1);
1373 if (!Offset.isImm())
1374 break; // We'll deal with this situation later on when applying fixups.
1375 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1376 return Error(IDLoc, "branch target out of range");
1377 if (OffsetToAlignment(Offset.getImm(),
1378 1LL << (inMicroMipsMode() ? 1 : 2)))
1379 return Error(IDLoc, "branch to misaligned address");
1381 case Mips::BEQZ16_MM:
1382 case Mips::BNEZ16_MM:
1383 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1384 Offset = Inst.getOperand(1);
1385 if (!Offset.isImm())
1386 break; // We'll deal with this situation later on when applying fixups.
1387 if (!isIntN(8, Offset.getImm()))
1388 return Error(IDLoc, "branch target out of range");
1389 if (OffsetToAlignment(Offset.getImm(), 2LL))
1390 return Error(IDLoc, "branch to misaligned address");
1395 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1396 // We still accept it but it is a normal nop.
1397 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1398 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1399 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1404 const unsigned Opcode = Inst.getOpcode();
1416 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1417 // The offset is handled above
1418 Opnd = Inst.getOperand(1);
1420 return Error(IDLoc, "expected immediate operand kind");
1421 Imm = Opnd.getImm();
1422 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1423 Opcode == Mips::BBIT1 ? 63 : 31))
1424 return Error(IDLoc, "immediate operand value out of range");
1426 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1428 Inst.getOperand(1).setImm(Imm - 32);
1436 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1438 Opnd = Inst.getOperand(3);
1440 return Error(IDLoc, "expected immediate operand kind");
1441 Imm = Opnd.getImm();
1442 if (Imm < 0 || Imm > 31)
1443 return Error(IDLoc, "immediate operand value out of range");
1445 Opnd = Inst.getOperand(2);
1447 return Error(IDLoc, "expected immediate operand kind");
1448 Imm = Opnd.getImm();
1449 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1450 Opcode == Mips::EXTS ? 63 : 31))
1451 return Error(IDLoc, "immediate operand value out of range");
1453 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1454 Inst.getOperand(2).setImm(Imm - 32);
1460 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1461 Opnd = Inst.getOperand(2);
1463 return Error(IDLoc, "expected immediate operand kind");
1464 Imm = Opnd.getImm();
1465 if (!isInt<10>(Imm))
1466 return Error(IDLoc, "immediate operand value out of range");
1471 if (MCID.mayLoad() || MCID.mayStore()) {
1472 // Check the offset of memory operand, if it is a symbol
1473 // reference or immediate we may have to expand instructions.
1474 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1475 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1476 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1477 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1478 MCOperand &Op = Inst.getOperand(i);
1480 int MemOffset = Op.getImm();
1481 if (MemOffset < -32768 || MemOffset > 32767) {
1482 // Offset can't exceed 16bit value.
1483 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1486 } else if (Op.isExpr()) {
1487 const MCExpr *Expr = Op.getExpr();
1488 if (Expr->getKind() == MCExpr::SymbolRef) {
1489 const MCSymbolRefExpr *SR =
1490 static_cast<const MCSymbolRefExpr *>(Expr);
1491 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1493 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1496 } else if (!isEvaluated(Expr)) {
1497 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1505 if (inMicroMipsMode()) {
1506 if (MCID.mayLoad()) {
1507 // Try to create 16-bit GP relative load instruction.
1508 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1509 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1510 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1511 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1512 MCOperand &Op = Inst.getOperand(i);
1514 int MemOffset = Op.getImm();
1515 MCOperand &DstReg = Inst.getOperand(0);
1516 MCOperand &BaseReg = Inst.getOperand(1);
1517 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1518 getContext().getRegisterInfo()->getRegClass(
1519 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1520 BaseReg.getReg() == Mips::GP) {
1522 TmpInst.setLoc(IDLoc);
1523 TmpInst.setOpcode(Mips::LWGP_MM);
1524 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1525 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1526 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1527 Instructions.push_back(TmpInst);
1535 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1540 switch (Inst.getOpcode()) {
1543 case Mips::ADDIUS5_MM:
1544 Opnd = Inst.getOperand(2);
1546 return Error(IDLoc, "expected immediate operand kind");
1547 Imm = Opnd.getImm();
1548 if (Imm < -8 || Imm > 7)
1549 return Error(IDLoc, "immediate operand value out of range");
1551 case Mips::ADDIUSP_MM:
1552 Opnd = Inst.getOperand(0);
1554 return Error(IDLoc, "expected immediate operand kind");
1555 Imm = Opnd.getImm();
1556 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1558 return Error(IDLoc, "immediate operand value out of range");
1560 case Mips::SLL16_MM:
1561 case Mips::SRL16_MM:
1562 Opnd = Inst.getOperand(2);
1564 return Error(IDLoc, "expected immediate operand kind");
1565 Imm = Opnd.getImm();
1566 if (Imm < 1 || Imm > 8)
1567 return Error(IDLoc, "immediate operand value out of range");
1570 Opnd = Inst.getOperand(1);
1572 return Error(IDLoc, "expected immediate operand kind");
1573 Imm = Opnd.getImm();
1574 if (Imm < -1 || Imm > 126)
1575 return Error(IDLoc, "immediate operand value out of range");
1577 case Mips::ADDIUR2_MM:
1578 Opnd = Inst.getOperand(2);
1580 return Error(IDLoc, "expected immediate operand kind");
1581 Imm = Opnd.getImm();
1582 if (!(Imm == 1 || Imm == -1 ||
1583 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1584 return Error(IDLoc, "immediate operand value out of range");
1586 case Mips::ADDIUR1SP_MM:
1587 Opnd = Inst.getOperand(1);
1589 return Error(IDLoc, "expected immediate operand kind");
1590 Imm = Opnd.getImm();
1591 if (OffsetToAlignment(Imm, 4LL))
1592 return Error(IDLoc, "misaligned immediate operand value");
1593 if (Imm < 0 || Imm > 255)
1594 return Error(IDLoc, "immediate operand value out of range");
1596 case Mips::ANDI16_MM:
1597 Opnd = Inst.getOperand(2);
1599 return Error(IDLoc, "expected immediate operand kind");
1600 Imm = Opnd.getImm();
1601 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1602 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1603 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1604 return Error(IDLoc, "immediate operand value out of range");
1606 case Mips::LBU16_MM:
1607 Opnd = Inst.getOperand(2);
1609 return Error(IDLoc, "expected immediate operand kind");
1610 Imm = Opnd.getImm();
1611 if (Imm < -1 || Imm > 14)
1612 return Error(IDLoc, "immediate operand value out of range");
1615 Opnd = Inst.getOperand(2);
1617 return Error(IDLoc, "expected immediate operand kind");
1618 Imm = Opnd.getImm();
1619 if (Imm < 0 || Imm > 15)
1620 return Error(IDLoc, "immediate operand value out of range");
1622 case Mips::LHU16_MM:
1624 Opnd = Inst.getOperand(2);
1626 return Error(IDLoc, "expected immediate operand kind");
1627 Imm = Opnd.getImm();
1628 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1629 return Error(IDLoc, "immediate operand value out of range");
1633 Opnd = Inst.getOperand(2);
1635 return Error(IDLoc, "expected immediate operand kind");
1636 Imm = Opnd.getImm();
1637 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1638 return Error(IDLoc, "immediate operand value out of range");
1642 Opnd = Inst.getOperand(2);
1644 return Error(IDLoc, "expected immediate operand kind");
1645 Imm = Opnd.getImm();
1646 if (!isUInt<5>(Imm))
1647 return Error(IDLoc, "immediate operand value out of range");
1649 case Mips::ADDIUPC_MM:
1650 MCOperand Opnd = Inst.getOperand(1);
1652 return Error(IDLoc, "expected immediate operand kind");
1653 int Imm = Opnd.getImm();
1654 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1655 return Error(IDLoc, "immediate operand value out of range");
1660 if (needsExpansion(Inst)) {
1661 if (expandInstruction(Inst, IDLoc, Instructions))
1664 Instructions.push_back(Inst);
1666 // If this instruction has a delay slot and .set reorder is active,
1667 // emit a NOP after it.
1668 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1669 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1674 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1676 switch (Inst.getOpcode()) {
1677 case Mips::LoadImm32:
1678 case Mips::LoadImm64:
1679 case Mips::LoadAddrImm32:
1680 case Mips::LoadAddrImm64:
1681 case Mips::LoadAddrReg32:
1682 case Mips::LoadAddrReg64:
1683 case Mips::B_MM_Pseudo:
1686 case Mips::JalOneReg:
1687 case Mips::JalTwoReg:
1706 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1707 SmallVectorImpl<MCInst> &Instructions) {
1708 switch (Inst.getOpcode()) {
1709 default: llvm_unreachable("unimplemented expansion");
1710 case Mips::LoadImm32:
1711 return expandLoadImm(Inst, true, IDLoc, Instructions);
1712 case Mips::LoadImm64:
1713 return expandLoadImm(Inst, false, IDLoc, Instructions);
1714 case Mips::LoadAddrImm32:
1715 case Mips::LoadAddrImm64:
1716 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1717 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1718 "expected immediate operand kind");
1720 return expandLoadAddress(
1721 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1722 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1723 case Mips::LoadAddrReg32:
1724 case Mips::LoadAddrReg64:
1725 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1726 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1727 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1728 "expected immediate operand kind");
1730 return expandLoadAddress(
1731 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1732 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1733 case Mips::B_MM_Pseudo:
1734 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1737 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1738 case Mips::JalOneReg:
1739 case Mips::JalTwoReg:
1740 return expandJalWithRegs(Inst, IDLoc, Instructions);
1743 return expandBranchImm(Inst, IDLoc, Instructions);
1752 return expandCondBranches(Inst, IDLoc, Instructions);
1754 return expandUlhu(Inst, IDLoc, Instructions);
1756 return expandUlw(Inst, IDLoc, Instructions);
1761 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1762 SmallVectorImpl<MCInst> &Instructions) {
1764 tmpInst.setOpcode(Opcode);
1765 tmpInst.addOperand(MCOperand::createReg(Reg0));
1766 tmpInst.addOperand(Op1);
1767 tmpInst.setLoc(IDLoc);
1768 Instructions.push_back(tmpInst);
1771 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1772 SmallVectorImpl<MCInst> &Instructions) {
1773 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1776 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1777 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1779 tmpInst.setOpcode(Opcode);
1780 tmpInst.addOperand(MCOperand::createReg(Reg0));
1781 tmpInst.addOperand(MCOperand::createReg(Reg1));
1782 tmpInst.addOperand(Op2);
1783 tmpInst.setLoc(IDLoc);
1784 Instructions.push_back(tmpInst);
1787 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1788 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1789 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1793 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1794 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1795 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1799 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1800 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1801 if (ShiftAmount >= 32) {
1802 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1807 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1809 } // end anonymous namespace.
1811 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1812 SmallVectorImpl<MCInst> &Instructions) {
1813 // Create a JALR instruction which is going to replace the pseudo-JAL.
1815 JalrInst.setLoc(IDLoc);
1816 const MCOperand FirstRegOp = Inst.getOperand(0);
1817 const unsigned Opcode = Inst.getOpcode();
1819 if (Opcode == Mips::JalOneReg) {
1820 // jal $rs => jalr $rs
1821 if (inMicroMipsMode()) {
1822 JalrInst.setOpcode(Mips::JALR16_MM);
1823 JalrInst.addOperand(FirstRegOp);
1825 JalrInst.setOpcode(Mips::JALR);
1826 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1827 JalrInst.addOperand(FirstRegOp);
1829 } else if (Opcode == Mips::JalTwoReg) {
1830 // jal $rd, $rs => jalr $rd, $rs
1831 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1832 JalrInst.addOperand(FirstRegOp);
1833 const MCOperand SecondRegOp = Inst.getOperand(1);
1834 JalrInst.addOperand(SecondRegOp);
1836 Instructions.push_back(JalrInst);
1838 // If .set reorder is active, emit a NOP after it.
1839 if (AssemblerOptions.back()->isReorder()) {
1840 // This is a 32-bit NOP because these 2 pseudo-instructions
1841 // do not have a short delay slot.
1843 NopInst.setOpcode(Mips::SLL);
1844 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1845 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1846 NopInst.addOperand(MCOperand::createImm(0));
1847 Instructions.push_back(NopInst);
1853 /// Can the value be represented by a unsigned N-bit value and a shift left?
1854 template<unsigned N>
1855 bool isShiftedUIntAtAnyPosition(uint64_t x) {
1856 unsigned BitNum = findFirstSet(x);
1858 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
1861 /// Load (or add) an immediate into a register.
1863 /// @param ImmValue The immediate to load.
1864 /// @param DstReg The register that will hold the immediate.
1865 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
1866 /// for a simple initialization.
1867 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
1868 /// @param IsAddress True if the immediate represents an address. False if it
1870 /// @param IDLoc Location of the immediate in the source file.
1871 /// @param Instructions The instructions emitted by this expansion.
1872 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1873 unsigned SrcReg, bool Is32BitImm,
1874 bool IsAddress, SMLoc IDLoc,
1875 SmallVectorImpl<MCInst> &Instructions) {
1876 if (!Is32BitImm && !isGP64bit()) {
1877 Error(IDLoc, "instruction requires a 64-bit architecture");
1882 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1883 // Sign extend up to 64-bit so that the predicates match the hardware
1884 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
1886 ImmValue = SignExtend64<32>(ImmValue);
1888 Error(IDLoc, "instruction requires a 32-bit immediate");
1893 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
1894 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
1896 bool UseSrcReg = false;
1897 if (SrcReg != Mips::NoRegister)
1900 unsigned TmpReg = DstReg;
1901 if (UseSrcReg && (DstReg == SrcReg)) {
1902 // At this point we need AT to perform the expansions and we exit if it is
1904 unsigned ATReg = getATReg(IDLoc);
1910 if (isInt<16>(ImmValue)) {
1914 // This doesn't quite follow the usual ABI expectations for N32 but matches
1915 // traditional assembler behaviour. N32 would normally use addiu for both
1916 // integers and addresses.
1917 if (IsAddress && !Is32BitImm) {
1918 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1922 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1926 if (isUInt<16>(ImmValue)) {
1927 unsigned TmpReg = DstReg;
1928 if (SrcReg == DstReg) {
1929 TmpReg = getATReg(IDLoc);
1934 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
1936 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1940 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1941 warnIfNoMacro(IDLoc);
1943 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1944 uint16_t Bits15To0 = ImmValue & 0xffff;
1946 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1947 // Traditional behaviour seems to special case this particular value. It's
1948 // not clear why other masks are handled differently.
1949 if (ImmValue == 0xffffffff) {
1950 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
1951 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
1953 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1957 // Expand to an ORi instead of a LUi to avoid sign-extending into the
1959 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
1960 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
1962 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
1964 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1968 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
1970 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
1972 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1976 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
1978 Error(IDLoc, "instruction requires a 32-bit immediate");
1982 // Traditionally, these immediates are shifted as little as possible and as
1983 // such we align the most significant bit to bit 15 of our temporary.
1984 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
1985 unsigned LastSet = findLastSet((uint64_t)ImmValue);
1986 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
1987 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
1988 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
1989 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
1992 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1997 warnIfNoMacro(IDLoc);
1999 // The remaining case is packed with a sequence of dsll and ori with zeros
2000 // being omitted and any neighbouring dsll's being coalesced.
2001 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2003 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2004 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2005 IDLoc, Instructions))
2008 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2009 // skip it and defer the shift to the next chunk.
2010 unsigned ShiftCarriedForwards = 16;
2011 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2012 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2014 if (ImmChunk != 0) {
2015 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2017 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2018 ShiftCarriedForwards = 0;
2021 ShiftCarriedForwards += 16;
2023 ShiftCarriedForwards -= 16;
2025 // Finish any remaining shifts left by trailing zeros.
2026 if (ShiftCarriedForwards)
2027 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2031 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2036 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2037 SmallVectorImpl<MCInst> &Instructions) {
2038 const MCOperand &ImmOp = Inst.getOperand(1);
2039 assert(ImmOp.isImm() && "expected immediate operand kind");
2040 const MCOperand &DstRegOp = Inst.getOperand(0);
2041 assert(DstRegOp.isReg() && "expected register operand kind");
2043 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2044 Is32BitImm, false, IDLoc, Instructions))
2050 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2051 const MCOperand &Offset,
2052 bool Is32BitAddress, SMLoc IDLoc,
2053 SmallVectorImpl<MCInst> &Instructions) {
2054 // la can't produce a usable address when addresses are 64-bit.
2055 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2056 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2057 // We currently can't do this because we depend on the equality
2058 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2059 Error(IDLoc, "la used to load 64-bit address");
2060 // Continue as if we had 'dla' instead.
2061 Is32BitAddress = false;
2064 // dla requires 64-bit addresses.
2065 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2066 Error(IDLoc, "instruction requires a 64-bit architecture");
2070 if (!Offset.isImm())
2071 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2072 Is32BitAddress, IDLoc, Instructions);
2074 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2075 IDLoc, Instructions);
2078 bool MipsAsmParser::loadAndAddSymbolAddress(
2079 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2080 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2081 warnIfNoMacro(IDLoc);
2083 // FIXME: The way we're handling symbols right now prevents simple expressions
2084 // like foo+8. We'll be able to fix this once our unary operators (%hi
2085 // and similar) are treated as operators rather than as fixup types.
2086 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2087 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2088 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2089 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2090 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2092 bool UseSrcReg = SrcReg != Mips::NoRegister;
2094 // This is the 64-bit symbol address expansion.
2095 if (ABI.ArePtrs64bit() && isGP64bit()) {
2096 // We always need AT for the 64-bit expansion.
2097 // If it is not available we exit.
2098 unsigned ATReg = getATReg(IDLoc);
2102 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2103 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2104 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2105 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2107 if (UseSrcReg && (DstReg == SrcReg)) {
2108 // If $rs is the same as $rd:
2109 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2110 // daddiu $at, $at, %higher(sym)
2111 // dsll $at, $at, 16
2112 // daddiu $at, $at, %hi(sym)
2113 // dsll $at, $at, 16
2114 // daddiu $at, $at, %lo(sym)
2115 // daddu $rd, $at, $rd
2116 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2118 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2119 IDLoc, Instructions);
2120 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2121 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2123 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2124 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2126 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2131 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2132 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2133 // lui $at, %hi(sym)
2134 // daddiu $rd, $rd, %higher(sym)
2135 // daddiu $at, $at, %lo(sym)
2136 // dsll32 $rd, $rd, 0
2137 // daddu $rd, $rd, $at
2138 // (daddu $rd, $rd, $rs)
2139 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2141 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2143 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2144 IDLoc, Instructions);
2145 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2147 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2148 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2150 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2155 // And now, the 32-bit symbol address expansion:
2156 // If $rs is the same as $rd:
2157 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2158 // ori $at, $at, %lo(sym)
2159 // addu $rd, $at, $rd
2160 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2161 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2162 // ori $rd, $rd, %lo(sym)
2163 // (addu $rd, $rd, $rs)
2164 unsigned TmpReg = DstReg;
2165 if (UseSrcReg && (DstReg == SrcReg)) {
2166 // If $rs is the same as $rd, we need to use AT.
2167 // If it is not available we exit.
2168 unsigned ATReg = getATReg(IDLoc);
2174 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2175 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2179 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2181 assert(DstReg == TmpReg);
2186 bool MipsAsmParser::expandUncondBranchMMPseudo(
2187 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2188 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2189 "unexpected number of operands");
2191 MCOperand Offset = Inst.getOperand(0);
2192 if (Offset.isExpr()) {
2194 Inst.setOpcode(Mips::BEQ_MM);
2195 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2196 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2197 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2199 assert(Offset.isImm() && "expected immediate operand kind");
2200 if (isIntN(11, Offset.getImm())) {
2201 // If offset fits into 11 bits then this instruction becomes microMIPS
2202 // 16-bit unconditional branch instruction.
2203 Inst.setOpcode(Mips::B16_MM);
2205 if (!isIntN(17, Offset.getImm()))
2206 Error(IDLoc, "branch target out of range");
2207 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2208 Error(IDLoc, "branch to misaligned address");
2210 Inst.setOpcode(Mips::BEQ_MM);
2211 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2212 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2213 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2216 Instructions.push_back(Inst);
2218 // If .set reorder is active, emit a NOP after the branch instruction.
2219 if (AssemblerOptions.back()->isReorder())
2220 createNop(true, IDLoc, Instructions);
2225 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2226 SmallVectorImpl<MCInst> &Instructions) {
2227 const MCOperand &DstRegOp = Inst.getOperand(0);
2228 assert(DstRegOp.isReg() && "expected register operand kind");
2230 const MCOperand &ImmOp = Inst.getOperand(1);
2231 assert(ImmOp.isImm() && "expected immediate operand kind");
2233 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2234 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2236 unsigned OpCode = 0;
2237 switch(Inst.getOpcode()) {
2245 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2249 int64_t ImmValue = ImmOp.getImm();
2250 if (ImmValue == 0) {
2252 BranchInst.setOpcode(OpCode);
2253 BranchInst.addOperand(DstRegOp);
2254 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2255 BranchInst.addOperand(MemOffsetOp);
2256 Instructions.push_back(BranchInst);
2258 warnIfNoMacro(IDLoc);
2260 unsigned ATReg = getATReg(IDLoc);
2264 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2265 IDLoc, Instructions))
2269 BranchInst.setOpcode(OpCode);
2270 BranchInst.addOperand(DstRegOp);
2271 BranchInst.addOperand(MCOperand::createReg(ATReg));
2272 BranchInst.addOperand(MemOffsetOp);
2273 Instructions.push_back(BranchInst);
2278 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2279 SmallVectorImpl<MCInst> &Instructions,
2280 bool isLoad, bool isImmOpnd) {
2282 unsigned ImmOffset, HiOffset, LoOffset;
2283 const MCExpr *ExprOffset;
2285 // 1st operand is either the source or destination register.
2286 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2287 unsigned RegOpNum = Inst.getOperand(0).getReg();
2288 // 2nd operand is the base register.
2289 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2290 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2291 // 3rd operand is either an immediate or expression.
2293 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2294 ImmOffset = Inst.getOperand(2).getImm();
2295 LoOffset = ImmOffset & 0x0000ffff;
2296 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2297 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2298 if (LoOffset & 0x8000)
2301 ExprOffset = Inst.getOperand(2).getExpr();
2302 // All instructions will have the same location.
2303 TempInst.setLoc(IDLoc);
2304 // These are some of the types of expansions we perform here:
2305 // 1) lw $8, sym => lui $8, %hi(sym)
2306 // lw $8, %lo(sym)($8)
2307 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2309 // lw $8, %lo(offset)($9)
2310 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2312 // lw $8, %lo(offset)($at)
2313 // 4) sw $8, sym => lui $at, %hi(sym)
2314 // sw $8, %lo(sym)($at)
2315 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2317 // sw $8, %lo(offset)($at)
2318 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2319 // ldc1 $f0, %lo(sym)($at)
2321 // For load instructions we can use the destination register as a temporary
2322 // if base and dst are different (examples 1 and 2) and if the base register
2323 // is general purpose otherwise we must use $at (example 6) and error if it's
2324 // not available. For stores we must use $at (examples 4 and 5) because we
2325 // must not clobber the source register setting up the offset.
2326 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2327 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2328 unsigned RegClassIDOp0 =
2329 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2330 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2331 (RegClassIDOp0 == Mips::GPR64RegClassID);
2332 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2333 TmpRegNum = RegOpNum;
2335 // At this point we need AT to perform the expansions and we exit if it is
2337 TmpRegNum = getATReg(IDLoc);
2342 TempInst.setOpcode(Mips::LUi);
2343 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2345 TempInst.addOperand(MCOperand::createImm(HiOffset));
2347 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2348 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2350 // Add the instruction to the list.
2351 Instructions.push_back(TempInst);
2352 // Prepare TempInst for next instruction.
2354 // Add temp register to base.
2355 if (BaseRegNum != Mips::ZERO) {
2356 TempInst.setOpcode(Mips::ADDu);
2357 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2358 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2359 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2360 Instructions.push_back(TempInst);
2363 // And finally, create original instruction with low part
2364 // of offset and new base.
2365 TempInst.setOpcode(Inst.getOpcode());
2366 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2367 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2369 TempInst.addOperand(MCOperand::createImm(LoOffset));
2371 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2372 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2374 Instructions.push_back(TempInst);
2379 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2380 SmallVectorImpl<MCInst> &Instructions) {
2381 unsigned OpNum = Inst.getNumOperands();
2382 unsigned Opcode = Inst.getOpcode();
2383 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2385 assert (Inst.getOperand(OpNum - 1).isImm() &&
2386 Inst.getOperand(OpNum - 2).isReg() &&
2387 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2389 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2390 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2391 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2392 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2393 // It can be implemented as SWM16 or LWM16 instruction.
2394 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2396 Inst.setOpcode(NewOpcode);
2397 Instructions.push_back(Inst);
2401 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2402 SmallVectorImpl<MCInst> &Instructions) {
2403 unsigned PseudoOpcode = Inst.getOpcode();
2404 unsigned SrcReg = Inst.getOperand(0).getReg();
2405 unsigned TrgReg = Inst.getOperand(1).getReg();
2406 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2408 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2409 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2411 switch (PseudoOpcode) {
2414 AcceptsEquality = false;
2415 ReverseOrderSLT = false;
2416 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2417 ZeroSrcOpcode = Mips::BGTZ;
2418 ZeroTrgOpcode = Mips::BLTZ;
2422 AcceptsEquality = true;
2423 ReverseOrderSLT = true;
2424 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2425 ZeroSrcOpcode = Mips::BGEZ;
2426 ZeroTrgOpcode = Mips::BLEZ;
2430 AcceptsEquality = true;
2431 ReverseOrderSLT = false;
2432 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2433 ZeroSrcOpcode = Mips::BLEZ;
2434 ZeroTrgOpcode = Mips::BGEZ;
2438 AcceptsEquality = false;
2439 ReverseOrderSLT = true;
2440 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2441 ZeroSrcOpcode = Mips::BLTZ;
2442 ZeroTrgOpcode = Mips::BGTZ;
2445 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2449 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2450 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2451 if (IsSrcRegZero && IsTrgRegZero) {
2452 // FIXME: All of these Opcode-specific if's are needed for compatibility
2453 // with GAS' behaviour. However, they may not generate the most efficient
2454 // code in some circumstances.
2455 if (PseudoOpcode == Mips::BLT) {
2456 BranchInst.setOpcode(Mips::BLTZ);
2457 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2458 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2459 Instructions.push_back(BranchInst);
2462 if (PseudoOpcode == Mips::BLE) {
2463 BranchInst.setOpcode(Mips::BLEZ);
2464 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2465 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2466 Instructions.push_back(BranchInst);
2467 Warning(IDLoc, "branch is always taken");
2470 if (PseudoOpcode == Mips::BGE) {
2471 BranchInst.setOpcode(Mips::BGEZ);
2472 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2473 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2474 Instructions.push_back(BranchInst);
2475 Warning(IDLoc, "branch is always taken");
2478 if (PseudoOpcode == Mips::BGT) {
2479 BranchInst.setOpcode(Mips::BGTZ);
2480 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2481 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2482 Instructions.push_back(BranchInst);
2485 if (PseudoOpcode == Mips::BGTU) {
2486 BranchInst.setOpcode(Mips::BNE);
2487 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2488 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2489 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2490 Instructions.push_back(BranchInst);
2493 if (AcceptsEquality) {
2494 // If both registers are $0 and the pseudo-branch accepts equality, it
2495 // will always be taken, so we emit an unconditional branch.
2496 BranchInst.setOpcode(Mips::BEQ);
2497 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2498 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2499 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2500 Instructions.push_back(BranchInst);
2501 Warning(IDLoc, "branch is always taken");
2504 // If both registers are $0 and the pseudo-branch does not accept
2505 // equality, it will never be taken, so we don't have to emit anything.
2508 if (IsSrcRegZero || IsTrgRegZero) {
2509 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2510 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2511 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2512 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2513 // the pseudo-branch will never be taken, so we don't emit anything.
2514 // This only applies to unsigned pseudo-branches.
2517 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2518 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2519 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2520 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2521 // the pseudo-branch will always be taken, so we emit an unconditional
2523 // This only applies to unsigned pseudo-branches.
2524 BranchInst.setOpcode(Mips::BEQ);
2525 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2526 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2527 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2528 Instructions.push_back(BranchInst);
2529 Warning(IDLoc, "branch is always taken");
2533 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2534 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2535 // the pseudo-branch will be taken only when the non-zero register is
2536 // different from 0, so we emit a BNEZ.
2538 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2539 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2540 // the pseudo-branch will be taken only when the non-zero register is
2541 // equal to 0, so we emit a BEQZ.
2543 // Because only BLEU and BGEU branch on equality, we can use the
2544 // AcceptsEquality variable to decide when to emit the BEQZ.
2545 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2546 BranchInst.addOperand(
2547 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2548 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2549 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2550 Instructions.push_back(BranchInst);
2553 // If we have a signed pseudo-branch and one of the registers is $0,
2554 // we can use an appropriate compare-to-zero branch. We select which one
2555 // to use in the switch statement above.
2556 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2557 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2558 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2559 Instructions.push_back(BranchInst);
2563 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2564 // expansions. If it is not available, we return.
2565 unsigned ATRegNum = getATReg(IDLoc);
2569 warnIfNoMacro(IDLoc);
2571 // SLT fits well with 2 of our 4 pseudo-branches:
2572 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2573 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2574 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2575 // This is accomplished by using a BNEZ with the result of the SLT.
2577 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2578 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2579 // Because only BGE and BLE branch on equality, we can use the
2580 // AcceptsEquality variable to decide when to emit the BEQZ.
2581 // Note that the order of the SLT arguments doesn't change between
2584 // The same applies to the unsigned variants, except that SLTu is used
2587 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2588 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2589 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2590 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2591 Instructions.push_back(SetInst);
2593 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2594 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2595 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2596 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2597 Instructions.push_back(BranchInst);
2601 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2602 SmallVectorImpl<MCInst> &Instructions) {
2603 if (hasMips32r6() || hasMips64r6()) {
2604 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2608 warnIfNoMacro(IDLoc);
2610 const MCOperand &DstRegOp = Inst.getOperand(0);
2611 assert(DstRegOp.isReg() && "expected register operand kind");
2613 const MCOperand &SrcRegOp = Inst.getOperand(1);
2614 assert(SrcRegOp.isReg() && "expected register operand kind");
2616 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2617 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2619 unsigned DstReg = DstRegOp.getReg();
2620 unsigned SrcReg = SrcRegOp.getReg();
2621 int64_t OffsetValue = OffsetImmOp.getImm();
2623 // NOTE: We always need AT for ULHU, as it is always used as the source
2624 // register for one of the LBu's.
2625 unsigned ATReg = getATReg(IDLoc);
2629 // When the value of offset+1 does not fit in 16 bits, we have to load the
2630 // offset in AT, (D)ADDu the original source register (if there was one), and
2631 // then use AT as the source register for the 2 generated LBu's.
2632 bool LoadedOffsetInAT = false;
2633 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2634 LoadedOffsetInAT = true;
2636 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2637 true, IDLoc, Instructions))
2640 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2641 // because it will make our output more similar to GAS'. For example,
2642 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2643 // instead of just an "ori $1, $9, 32768".
2644 // NOTE: If there is no source register specified in the ULHU, the parser
2645 // will interpret it as $0.
2646 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2647 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2650 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2651 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2652 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2654 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2656 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2657 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2659 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2660 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2663 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2666 TmpInst.setOpcode(Mips::LBu);
2667 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2668 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2669 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2670 Instructions.push_back(TmpInst);
2673 TmpInst.setOpcode(Mips::LBu);
2674 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2675 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2676 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2677 Instructions.push_back(TmpInst);
2680 TmpInst.setOpcode(Mips::SLL);
2681 TmpInst.addOperand(MCOperand::createReg(SllReg));
2682 TmpInst.addOperand(MCOperand::createReg(SllReg));
2683 TmpInst.addOperand(MCOperand::createImm(8));
2684 Instructions.push_back(TmpInst);
2687 TmpInst.setOpcode(Mips::OR);
2688 TmpInst.addOperand(MCOperand::createReg(DstReg));
2689 TmpInst.addOperand(MCOperand::createReg(DstReg));
2690 TmpInst.addOperand(MCOperand::createReg(ATReg));
2691 Instructions.push_back(TmpInst);
2696 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2697 SmallVectorImpl<MCInst> &Instructions) {
2698 if (hasMips32r6() || hasMips64r6()) {
2699 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2703 const MCOperand &DstRegOp = Inst.getOperand(0);
2704 assert(DstRegOp.isReg() && "expected register operand kind");
2706 const MCOperand &SrcRegOp = Inst.getOperand(1);
2707 assert(SrcRegOp.isReg() && "expected register operand kind");
2709 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2710 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2712 unsigned SrcReg = SrcRegOp.getReg();
2713 int64_t OffsetValue = OffsetImmOp.getImm();
2716 // When the value of offset+3 does not fit in 16 bits, we have to load the
2717 // offset in AT, (D)ADDu the original source register (if there was one), and
2718 // then use AT as the source register for the generated LWL and LWR.
2719 bool LoadedOffsetInAT = false;
2720 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2721 ATReg = getATReg(IDLoc);
2724 LoadedOffsetInAT = true;
2726 warnIfNoMacro(IDLoc);
2728 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2729 true, IDLoc, Instructions))
2732 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2733 // because it will make our output more similar to GAS'. For example,
2734 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2735 // instead of just an "ori $1, $9, 32768".
2736 // NOTE: If there is no source register specified in the ULW, the parser
2737 // will interpret it as $0.
2738 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2739 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2742 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2743 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2745 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2746 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2748 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2749 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2752 MCInst LeftLoadInst;
2753 LeftLoadInst.setOpcode(Mips::LWL);
2754 LeftLoadInst.addOperand(DstRegOp);
2755 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2756 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2757 Instructions.push_back(LeftLoadInst);
2759 MCInst RightLoadInst;
2760 RightLoadInst.setOpcode(Mips::LWR);
2761 RightLoadInst.addOperand(DstRegOp);
2762 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2763 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2764 Instructions.push_back(RightLoadInst);
2769 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2770 SmallVectorImpl<MCInst> &Instructions) {
2772 if (hasShortDelaySlot) {
2773 NopInst.setOpcode(Mips::MOVE16_MM);
2774 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2775 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2777 NopInst.setOpcode(Mips::SLL);
2778 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2779 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2780 NopInst.addOperand(MCOperand::createImm(0));
2782 Instructions.push_back(NopInst);
2785 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2786 unsigned TrgReg, bool Is64Bit,
2787 SmallVectorImpl<MCInst> &Instructions) {
2788 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
2792 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2793 // As described by the Mips32r2 spec, the registers Rd and Rs for
2794 // jalr.hb must be different.
2795 unsigned Opcode = Inst.getOpcode();
2797 if (Opcode == Mips::JALR_HB &&
2798 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2799 return Match_RequiresDifferentSrcAndDst;
2801 return Match_Success;
2804 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2805 OperandVector &Operands,
2807 uint64_t &ErrorInfo,
2808 bool MatchingInlineAsm) {
2811 SmallVector<MCInst, 8> Instructions;
2812 unsigned MatchResult =
2813 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2815 switch (MatchResult) {
2816 case Match_Success: {
2817 if (processInstruction(Inst, IDLoc, Instructions))
2819 for (unsigned i = 0; i < Instructions.size(); i++)
2820 Out.EmitInstruction(Instructions[i], STI);
2823 case Match_MissingFeature:
2824 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2826 case Match_InvalidOperand: {
2827 SMLoc ErrorLoc = IDLoc;
2828 if (ErrorInfo != ~0ULL) {
2829 if (ErrorInfo >= Operands.size())
2830 return Error(IDLoc, "too few operands for instruction");
2832 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2833 if (ErrorLoc == SMLoc())
2837 return Error(ErrorLoc, "invalid operand for instruction");
2839 case Match_MnemonicFail:
2840 return Error(IDLoc, "invalid instruction");
2841 case Match_RequiresDifferentSrcAndDst:
2842 return Error(IDLoc, "source and destination must be different");
2845 llvm_unreachable("Implement any new match types added!");
2848 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2849 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2850 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2851 ") without \".set noat\"");
2854 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2855 if (!AssemblerOptions.back()->isMacro())
2856 Warning(Loc, "macro instruction expanded into multiple instructions");
2860 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2861 SMRange Range, bool ShowColors) {
2862 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2863 Range, SMFixIt(Range, FixMsg),
2867 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2870 CC = StringSwitch<unsigned>(Name)
2906 if (!(isABI_N32() || isABI_N64()))
2909 if (12 <= CC && CC <= 15) {
2910 // Name is one of t4-t7
2911 AsmToken RegTok = getLexer().peekTok();
2912 SMRange RegRange = RegTok.getLocRange();
2914 StringRef FixedName = StringSwitch<StringRef>(Name)
2920 assert(FixedName != "" && "Register name is not one of t4-t7.");
2922 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2923 "Did you mean $" + FixedName + "?", RegRange);
2926 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2927 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2928 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2929 if (8 <= CC && CC <= 11)
2933 CC = StringSwitch<unsigned>(Name)
2945 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2948 CC = StringSwitch<unsigned>(Name)
2949 .Case("hwr_cpunum", 0)
2950 .Case("hwr_synci_step", 1)
2952 .Case("hwr_ccres", 3)
2953 .Case("hwr_ulr", 29)
2959 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2961 if (Name[0] == 'f') {
2962 StringRef NumString = Name.substr(1);
2964 if (NumString.getAsInteger(10, IntVal))
2965 return -1; // This is not an integer.
2966 if (IntVal > 31) // Maximum index for fpu register.
2973 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2975 if (Name.startswith("fcc")) {
2976 StringRef NumString = Name.substr(3);
2978 if (NumString.getAsInteger(10, IntVal))
2979 return -1; // This is not an integer.
2980 if (IntVal > 7) // There are only 8 fcc registers.
2987 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2989 if (Name.startswith("ac")) {
2990 StringRef NumString = Name.substr(2);
2992 if (NumString.getAsInteger(10, IntVal))
2993 return -1; // This is not an integer.
2994 if (IntVal > 3) // There are only 3 acc registers.
3001 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3004 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3013 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3016 CC = StringSwitch<unsigned>(Name)
3019 .Case("msaaccess", 2)
3021 .Case("msamodify", 4)
3022 .Case("msarequest", 5)
3024 .Case("msaunmap", 7)
3030 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3031 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3033 reportParseError(Loc,
3034 "pseudo-instruction requires $at, which is not available");
3037 unsigned AT = getReg(
3038 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3042 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3043 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3046 unsigned MipsAsmParser::getGPR(int RegNo) {
3047 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3051 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3053 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3056 return getReg(RegClass, RegNum);
3059 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3060 MCAsmParser &Parser = getParser();
3061 DEBUG(dbgs() << "parseOperand\n");
3063 // Check if the current operand has a custom associated parser, if so, try to
3064 // custom parse the operand, or fallback to the general approach.
3065 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3066 if (ResTy == MatchOperand_Success)
3068 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3069 // there was a match, but an error occurred, in which case, just return that
3070 // the operand parsing failed.
3071 if (ResTy == MatchOperand_ParseFail)
3074 DEBUG(dbgs() << ".. Generic Parser\n");
3076 switch (getLexer().getKind()) {
3078 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3080 case AsmToken::Dollar: {
3081 // Parse the register.
3082 SMLoc S = Parser.getTok().getLoc();
3084 // Almost all registers have been parsed by custom parsers. There is only
3085 // one exception to this. $zero (and it's alias $0) will reach this point
3086 // for div, divu, and similar instructions because it is not an operand
3087 // to the instruction definition but an explicit register. Special case
3088 // this situation for now.
3089 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3092 // Maybe it is a symbol reference.
3093 StringRef Identifier;
3094 if (Parser.parseIdentifier(Identifier))
3097 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3098 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3099 // Otherwise create a symbol reference.
3101 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3103 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3106 // Else drop to expression parsing.
3107 case AsmToken::LParen:
3108 case AsmToken::Minus:
3109 case AsmToken::Plus:
3110 case AsmToken::Integer:
3111 case AsmToken::Tilde:
3112 case AsmToken::String: {
3113 DEBUG(dbgs() << ".. generic integer\n");
3114 OperandMatchResultTy ResTy = parseImm(Operands);
3115 return ResTy != MatchOperand_Success;
3117 case AsmToken::Percent: {
3118 // It is a symbol reference or constant expression.
3119 const MCExpr *IdVal;
3120 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3121 if (parseRelocOperand(IdVal))
3124 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3126 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3128 } // case AsmToken::Percent
3129 } // switch(getLexer().getKind())
3133 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3134 StringRef RelocStr) {
3136 // Check the type of the expression.
3137 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3138 // It's a constant, evaluate reloc value.
3140 switch (getVariantKind(RelocStr)) {
3141 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3142 // Get the 1st 16-bits.
3143 Val = MCE->getValue() & 0xffff;
3145 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3146 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3147 // 16 bits being negative.
3148 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3150 case MCSymbolRefExpr::VK_Mips_HIGHER:
3151 // Get the 3rd 16-bits.
3152 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3154 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3155 // Get the 4th 16-bits.
3156 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3159 report_fatal_error("unsupported reloc value");
3161 return MCConstantExpr::create(Val, getContext());
3164 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3165 // It's a symbol, create a symbolic expression from the symbol.
3166 const MCSymbol *Symbol = &MSRE->getSymbol();
3167 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3168 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3172 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3173 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3175 // Try to create target expression.
3176 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3177 return MipsMCExpr::create(VK, Expr, getContext());
3179 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3180 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3181 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3185 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3186 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3187 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3190 // Just return the original expression.
3194 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3196 switch (Expr->getKind()) {
3197 case MCExpr::Constant:
3199 case MCExpr::SymbolRef:
3200 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3201 case MCExpr::Binary:
3202 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3203 if (!isEvaluated(BE->getLHS()))
3205 return isEvaluated(BE->getRHS());
3208 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3209 case MCExpr::Target:
3215 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3216 MCAsmParser &Parser = getParser();
3217 Parser.Lex(); // Eat the % token.
3218 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3219 if (Tok.isNot(AsmToken::Identifier))
3222 std::string Str = Tok.getIdentifier();
3224 Parser.Lex(); // Eat the identifier.
3225 // Now make an expression from the rest of the operand.
3226 const MCExpr *IdVal;
3229 if (getLexer().getKind() == AsmToken::LParen) {
3231 Parser.Lex(); // Eat the '(' token.
3232 if (getLexer().getKind() == AsmToken::Percent) {
3233 Parser.Lex(); // Eat the % token.
3234 const AsmToken &nextTok = Parser.getTok();
3235 if (nextTok.isNot(AsmToken::Identifier))
3238 Str += nextTok.getIdentifier();
3239 Parser.Lex(); // Eat the identifier.
3240 if (getLexer().getKind() != AsmToken::LParen)
3245 if (getParser().parseParenExpression(IdVal, EndLoc))
3248 while (getLexer().getKind() == AsmToken::RParen)
3249 Parser.Lex(); // Eat the ')' token.
3252 return true; // Parenthesis must follow the relocation operand.
3254 Res = evaluateRelocExpr(IdVal, Str);
3258 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3260 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3261 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3262 if (ResTy == MatchOperand_Success) {
3263 assert(Operands.size() == 1);
3264 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3265 StartLoc = Operand.getStartLoc();
3266 EndLoc = Operand.getEndLoc();
3268 // AFAIK, we only support numeric registers and named GPR's in CFI
3270 // Don't worry about eating tokens before failing. Using an unrecognised
3271 // register is a parse error.
3272 if (Operand.isGPRAsmReg()) {
3273 // Resolve to GPR32 or GPR64 appropriately.
3274 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3277 return (RegNo == (unsigned)-1);
3280 assert(Operands.size() == 0);
3281 return (RegNo == (unsigned)-1);
3284 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3285 MCAsmParser &Parser = getParser();
3288 unsigned NumOfLParen = 0;
3290 while (getLexer().getKind() == AsmToken::LParen) {
3295 switch (getLexer().getKind()) {
3298 case AsmToken::Identifier:
3299 case AsmToken::LParen:
3300 case AsmToken::Integer:
3301 case AsmToken::Minus:
3302 case AsmToken::Plus:
3304 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3306 Result = (getParser().parseExpression(Res));
3307 while (getLexer().getKind() == AsmToken::RParen)
3310 case AsmToken::Percent:
3311 Result = parseRelocOperand(Res);
3316 MipsAsmParser::OperandMatchResultTy
3317 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3318 MCAsmParser &Parser = getParser();
3319 DEBUG(dbgs() << "parseMemOperand\n");
3320 const MCExpr *IdVal = nullptr;
3322 bool isParenExpr = false;
3323 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3324 // First operand is the offset.
3325 S = Parser.getTok().getLoc();
3327 if (getLexer().getKind() == AsmToken::LParen) {
3332 if (getLexer().getKind() != AsmToken::Dollar) {
3333 if (parseMemOffset(IdVal, isParenExpr))
3334 return MatchOperand_ParseFail;
3336 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3337 if (Tok.isNot(AsmToken::LParen)) {
3338 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3339 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3341 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3342 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3343 return MatchOperand_Success;
3345 if (Tok.is(AsmToken::EndOfStatement)) {
3347 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3349 // Zero register assumed, add a memory operand with ZERO as its base.
3350 // "Base" will be managed by k_Memory.
3351 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3354 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3355 return MatchOperand_Success;
3357 Error(Parser.getTok().getLoc(), "'(' expected");
3358 return MatchOperand_ParseFail;
3361 Parser.Lex(); // Eat the '(' token.
3364 Res = parseAnyRegister(Operands);
3365 if (Res != MatchOperand_Success)
3368 if (Parser.getTok().isNot(AsmToken::RParen)) {
3369 Error(Parser.getTok().getLoc(), "')' expected");
3370 return MatchOperand_ParseFail;
3373 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3375 Parser.Lex(); // Eat the ')' token.
3378 IdVal = MCConstantExpr::create(0, getContext());
3380 // Replace the register operand with the memory operand.
3381 std::unique_ptr<MipsOperand> op(
3382 static_cast<MipsOperand *>(Operands.back().release()));
3383 // Remove the register from the operands.
3384 // "op" will be managed by k_Memory.
3385 Operands.pop_back();
3386 // Add the memory operand.
3387 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3389 if (IdVal->evaluateAsAbsolute(Imm))
3390 IdVal = MCConstantExpr::create(Imm, getContext());
3391 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3392 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3396 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3397 return MatchOperand_Success;
3400 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3401 MCAsmParser &Parser = getParser();
3402 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3404 SMLoc S = Parser.getTok().getLoc();
3406 if (Sym->isVariable())
3407 Expr = Sym->getVariableValue();
3410 if (Expr->getKind() == MCExpr::SymbolRef) {
3411 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3412 StringRef DefSymbol = Ref->getSymbol().getName();
3413 if (DefSymbol.startswith("$")) {
3414 OperandMatchResultTy ResTy =
3415 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3416 if (ResTy == MatchOperand_Success) {
3419 } else if (ResTy == MatchOperand_ParseFail)
3420 llvm_unreachable("Should never ParseFail");
3423 } else if (Expr->getKind() == MCExpr::Constant) {
3425 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3427 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3434 MipsAsmParser::OperandMatchResultTy
3435 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3436 StringRef Identifier,
3438 int Index = matchCPURegisterName(Identifier);
3440 Operands.push_back(MipsOperand::createGPRReg(
3441 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3442 return MatchOperand_Success;
3445 Index = matchHWRegsRegisterName(Identifier);
3447 Operands.push_back(MipsOperand::createHWRegsReg(
3448 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3449 return MatchOperand_Success;
3452 Index = matchFPURegisterName(Identifier);
3454 Operands.push_back(MipsOperand::createFGRReg(
3455 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3456 return MatchOperand_Success;
3459 Index = matchFCCRegisterName(Identifier);
3461 Operands.push_back(MipsOperand::createFCCReg(
3462 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3463 return MatchOperand_Success;
3466 Index = matchACRegisterName(Identifier);
3468 Operands.push_back(MipsOperand::createACCReg(
3469 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3470 return MatchOperand_Success;
3473 Index = matchMSA128RegisterName(Identifier);
3475 Operands.push_back(MipsOperand::createMSA128Reg(
3476 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3477 return MatchOperand_Success;
3480 Index = matchMSA128CtrlRegisterName(Identifier);
3482 Operands.push_back(MipsOperand::createMSACtrlReg(
3483 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3484 return MatchOperand_Success;
3487 return MatchOperand_NoMatch;
3490 MipsAsmParser::OperandMatchResultTy
3491 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3492 MCAsmParser &Parser = getParser();
3493 auto Token = Parser.getLexer().peekTok(false);
3495 if (Token.is(AsmToken::Identifier)) {
3496 DEBUG(dbgs() << ".. identifier\n");
3497 StringRef Identifier = Token.getIdentifier();
3498 OperandMatchResultTy ResTy =
3499 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3501 } else if (Token.is(AsmToken::Integer)) {
3502 DEBUG(dbgs() << ".. integer\n");
3503 Operands.push_back(MipsOperand::createNumericReg(
3504 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3506 return MatchOperand_Success;
3509 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3511 return MatchOperand_NoMatch;
3514 MipsAsmParser::OperandMatchResultTy
3515 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3516 MCAsmParser &Parser = getParser();
3517 DEBUG(dbgs() << "parseAnyRegister\n");
3519 auto Token = Parser.getTok();
3521 SMLoc S = Token.getLoc();
3523 if (Token.isNot(AsmToken::Dollar)) {
3524 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3525 if (Token.is(AsmToken::Identifier)) {
3526 if (searchSymbolAlias(Operands))
3527 return MatchOperand_Success;
3529 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3530 return MatchOperand_NoMatch;
3532 DEBUG(dbgs() << ".. $\n");
3534 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3535 if (ResTy == MatchOperand_Success) {
3537 Parser.Lex(); // identifier
3542 MipsAsmParser::OperandMatchResultTy
3543 MipsAsmParser::parseImm(OperandVector &Operands) {
3544 MCAsmParser &Parser = getParser();
3545 switch (getLexer().getKind()) {
3547 return MatchOperand_NoMatch;
3548 case AsmToken::LParen:
3549 case AsmToken::Minus:
3550 case AsmToken::Plus:
3551 case AsmToken::Integer:
3552 case AsmToken::Tilde:
3553 case AsmToken::String:
3557 const MCExpr *IdVal;
3558 SMLoc S = Parser.getTok().getLoc();
3559 if (getParser().parseExpression(IdVal))
3560 return MatchOperand_ParseFail;
3562 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3563 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3564 return MatchOperand_Success;
3567 MipsAsmParser::OperandMatchResultTy
3568 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3569 MCAsmParser &Parser = getParser();
3570 DEBUG(dbgs() << "parseJumpTarget\n");
3572 SMLoc S = getLexer().getLoc();
3574 // Integers and expressions are acceptable
3575 OperandMatchResultTy ResTy = parseImm(Operands);
3576 if (ResTy != MatchOperand_NoMatch)
3579 // Registers are a valid target and have priority over symbols.
3580 ResTy = parseAnyRegister(Operands);
3581 if (ResTy != MatchOperand_NoMatch)
3584 const MCExpr *Expr = nullptr;
3585 if (Parser.parseExpression(Expr)) {
3586 // We have no way of knowing if a symbol was consumed so we must ParseFail
3587 return MatchOperand_ParseFail;
3590 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3591 return MatchOperand_Success;
3594 MipsAsmParser::OperandMatchResultTy
3595 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3596 MCAsmParser &Parser = getParser();
3597 const MCExpr *IdVal;
3598 // If the first token is '$' we may have register operand.
3599 if (Parser.getTok().is(AsmToken::Dollar))
3600 return MatchOperand_NoMatch;
3601 SMLoc S = Parser.getTok().getLoc();
3602 if (getParser().parseExpression(IdVal))
3603 return MatchOperand_ParseFail;
3604 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3605 assert(MCE && "Unexpected MCExpr type.");
3606 int64_t Val = MCE->getValue();
3607 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3608 Operands.push_back(MipsOperand::CreateImm(
3609 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3610 return MatchOperand_Success;
3613 MipsAsmParser::OperandMatchResultTy
3614 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3615 MCAsmParser &Parser = getParser();
3616 switch (getLexer().getKind()) {
3618 return MatchOperand_NoMatch;
3619 case AsmToken::LParen:
3620 case AsmToken::Plus:
3621 case AsmToken::Minus:
3622 case AsmToken::Integer:
3627 SMLoc S = Parser.getTok().getLoc();
3629 if (getParser().parseExpression(Expr))
3630 return MatchOperand_ParseFail;
3633 if (!Expr->evaluateAsAbsolute(Val)) {
3634 Error(S, "expected immediate value");
3635 return MatchOperand_ParseFail;
3638 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3639 // and because the CPU always adds one to the immediate field, the allowed
3640 // range becomes 1..4. We'll only check the range here and will deal
3641 // with the addition/subtraction when actually decoding/encoding
3643 if (Val < 1 || Val > 4) {
3644 Error(S, "immediate not in range (1..4)");
3645 return MatchOperand_ParseFail;
3649 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3650 return MatchOperand_Success;
3653 MipsAsmParser::OperandMatchResultTy
3654 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3655 MCAsmParser &Parser = getParser();
3656 SmallVector<unsigned, 10> Regs;
3658 unsigned PrevReg = Mips::NoRegister;
3659 bool RegRange = false;
3660 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3662 if (Parser.getTok().isNot(AsmToken::Dollar))
3663 return MatchOperand_ParseFail;
3665 SMLoc S = Parser.getTok().getLoc();
3666 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3667 SMLoc E = getLexer().getLoc();
3668 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3669 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3671 // Remove last register operand because registers from register range
3672 // should be inserted first.
3673 if (RegNo == Mips::RA) {
3674 Regs.push_back(RegNo);
3676 unsigned TmpReg = PrevReg + 1;
3677 while (TmpReg <= RegNo) {
3678 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3679 Error(E, "invalid register operand");
3680 return MatchOperand_ParseFail;
3684 Regs.push_back(TmpReg++);
3690 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3691 (RegNo != Mips::RA)) {
3692 Error(E, "$16 or $31 expected");
3693 return MatchOperand_ParseFail;
3694 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3695 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3696 Error(E, "invalid register operand");
3697 return MatchOperand_ParseFail;
3698 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3699 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3700 Error(E, "consecutive register numbers expected");
3701 return MatchOperand_ParseFail;
3704 Regs.push_back(RegNo);
3707 if (Parser.getTok().is(AsmToken::Minus))
3710 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3711 !Parser.getTok().isNot(AsmToken::Comma)) {
3712 Error(E, "',' or '-' expected");
3713 return MatchOperand_ParseFail;
3716 Lex(); // Consume comma or minus
3717 if (Parser.getTok().isNot(AsmToken::Dollar))
3723 SMLoc E = Parser.getTok().getLoc();
3724 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3725 parseMemOperand(Operands);
3726 return MatchOperand_Success;
3729 MipsAsmParser::OperandMatchResultTy
3730 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3731 MCAsmParser &Parser = getParser();
3733 SMLoc S = Parser.getTok().getLoc();
3734 if (parseAnyRegister(Operands) != MatchOperand_Success)
3735 return MatchOperand_ParseFail;
3737 SMLoc E = Parser.getTok().getLoc();
3738 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3739 unsigned Reg = Op.getGPR32Reg();
3740 Operands.pop_back();
3741 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3742 return MatchOperand_Success;
3745 MipsAsmParser::OperandMatchResultTy
3746 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3747 MCAsmParser &Parser = getParser();
3748 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3749 SmallVector<unsigned, 10> Regs;
3751 if (Parser.getTok().isNot(AsmToken::Dollar))
3752 return MatchOperand_ParseFail;
3754 SMLoc S = Parser.getTok().getLoc();
3756 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3757 return MatchOperand_ParseFail;
3759 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3760 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3761 Regs.push_back(RegNo);
3763 SMLoc E = Parser.getTok().getLoc();
3764 if (Parser.getTok().isNot(AsmToken::Comma)) {
3765 Error(E, "',' expected");
3766 return MatchOperand_ParseFail;
3772 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3773 return MatchOperand_ParseFail;
3775 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3776 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3777 Regs.push_back(RegNo);
3779 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3781 return MatchOperand_Success;
3784 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3786 MCSymbolRefExpr::VariantKind VK =
3787 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3788 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3789 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3790 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3791 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3792 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3793 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3794 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3795 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3796 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3797 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3798 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3799 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3800 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3801 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3802 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3803 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3804 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3805 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3806 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3807 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3808 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3809 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3810 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3811 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3812 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3813 .Default(MCSymbolRefExpr::VK_None);
3815 assert(VK != MCSymbolRefExpr::VK_None);
3820 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3822 /// ::= '(', register, ')'
3823 /// handle it before we iterate so we don't get tripped up by the lack of
3825 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3826 MCAsmParser &Parser = getParser();
3827 if (getLexer().is(AsmToken::LParen)) {
3829 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3831 if (parseOperand(Operands, Name)) {
3832 SMLoc Loc = getLexer().getLoc();
3833 Parser.eatToEndOfStatement();
3834 return Error(Loc, "unexpected token in argument list");
3836 if (Parser.getTok().isNot(AsmToken::RParen)) {
3837 SMLoc Loc = getLexer().getLoc();
3838 Parser.eatToEndOfStatement();
3839 return Error(Loc, "unexpected token, expected ')'");
3842 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3848 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3849 /// either one of these.
3850 /// ::= '[', register, ']'
3851 /// ::= '[', integer, ']'
3852 /// handle it before we iterate so we don't get tripped up by the lack of
3854 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3855 OperandVector &Operands) {
3856 MCAsmParser &Parser = getParser();
3857 if (getLexer().is(AsmToken::LBrac)) {
3859 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3861 if (parseOperand(Operands, Name)) {
3862 SMLoc Loc = getLexer().getLoc();
3863 Parser.eatToEndOfStatement();
3864 return Error(Loc, "unexpected token in argument list");
3866 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3867 SMLoc Loc = getLexer().getLoc();
3868 Parser.eatToEndOfStatement();
3869 return Error(Loc, "unexpected token, expected ']'");
3872 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3878 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3879 SMLoc NameLoc, OperandVector &Operands) {
3880 MCAsmParser &Parser = getParser();
3881 DEBUG(dbgs() << "ParseInstruction\n");
3883 // We have reached first instruction, module directive are now forbidden.
3884 getTargetStreamer().forbidModuleDirective();
3886 // Check if we have valid mnemonic
3887 if (!mnemonicIsValid(Name, 0)) {
3888 Parser.eatToEndOfStatement();
3889 return Error(NameLoc, "unknown instruction");
3891 // First operand in MCInst is instruction mnemonic.
3892 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3894 // Read the remaining operands.
3895 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3896 // Read the first operand.
3897 if (parseOperand(Operands, Name)) {
3898 SMLoc Loc = getLexer().getLoc();
3899 Parser.eatToEndOfStatement();
3900 return Error(Loc, "unexpected token in argument list");
3902 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3904 // AFAIK, parenthesis suffixes are never on the first operand
3906 while (getLexer().is(AsmToken::Comma)) {
3907 Parser.Lex(); // Eat the comma.
3908 // Parse and remember the operand.
3909 if (parseOperand(Operands, Name)) {
3910 SMLoc Loc = getLexer().getLoc();
3911 Parser.eatToEndOfStatement();
3912 return Error(Loc, "unexpected token in argument list");
3914 // Parse bracket and parenthesis suffixes before we iterate
3915 if (getLexer().is(AsmToken::LBrac)) {
3916 if (parseBracketSuffix(Name, Operands))
3918 } else if (getLexer().is(AsmToken::LParen) &&
3919 parseParenSuffix(Name, Operands))
3923 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3924 SMLoc Loc = getLexer().getLoc();
3925 Parser.eatToEndOfStatement();
3926 return Error(Loc, "unexpected token in argument list");
3928 Parser.Lex(); // Consume the EndOfStatement.
3932 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3933 MCAsmParser &Parser = getParser();
3934 SMLoc Loc = getLexer().getLoc();
3935 Parser.eatToEndOfStatement();
3936 return Error(Loc, ErrorMsg);
3939 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3940 return Error(Loc, ErrorMsg);
3943 bool MipsAsmParser::parseSetNoAtDirective() {
3944 MCAsmParser &Parser = getParser();
3945 // Line should look like: ".set noat".
3947 // Set the $at register to $0.
3948 AssemblerOptions.back()->setATRegIndex(0);
3950 Parser.Lex(); // Eat "noat".
3952 // If this is not the end of the statement, report an error.
3953 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3954 reportParseError("unexpected token, expected end of statement");
3958 getTargetStreamer().emitDirectiveSetNoAt();
3959 Parser.Lex(); // Consume the EndOfStatement.
3963 bool MipsAsmParser::parseSetAtDirective() {
3964 // Line can be: ".set at", which sets $at to $1
3965 // or ".set at=$reg", which sets $at to $reg.
3966 MCAsmParser &Parser = getParser();
3967 Parser.Lex(); // Eat "at".
3969 if (getLexer().is(AsmToken::EndOfStatement)) {
3970 // No register was specified, so we set $at to $1.
3971 AssemblerOptions.back()->setATRegIndex(1);
3973 getTargetStreamer().emitDirectiveSetAt();
3974 Parser.Lex(); // Consume the EndOfStatement.
3978 if (getLexer().isNot(AsmToken::Equal)) {
3979 reportParseError("unexpected token, expected equals sign");
3982 Parser.Lex(); // Eat "=".
3984 if (getLexer().isNot(AsmToken::Dollar)) {
3985 if (getLexer().is(AsmToken::EndOfStatement)) {
3986 reportParseError("no register specified");
3989 reportParseError("unexpected token, expected dollar sign '$'");
3993 Parser.Lex(); // Eat "$".
3995 // Find out what "reg" is.
3997 const AsmToken &Reg = Parser.getTok();
3998 if (Reg.is(AsmToken::Identifier)) {
3999 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4000 } else if (Reg.is(AsmToken::Integer)) {
4001 AtRegNo = Reg.getIntVal();
4003 reportParseError("unexpected token, expected identifier or integer");
4007 // Check if $reg is a valid register. If it is, set $at to $reg.
4008 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4009 reportParseError("invalid register");
4012 Parser.Lex(); // Eat "reg".
4014 // If this is not the end of the statement, report an error.
4015 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4016 reportParseError("unexpected token, expected end of statement");
4020 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4022 Parser.Lex(); // Consume the EndOfStatement.
4026 bool MipsAsmParser::parseSetReorderDirective() {
4027 MCAsmParser &Parser = getParser();
4029 // If this is not the end of the statement, report an error.
4030 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4031 reportParseError("unexpected token, expected end of statement");
4034 AssemblerOptions.back()->setReorder();
4035 getTargetStreamer().emitDirectiveSetReorder();
4036 Parser.Lex(); // Consume the EndOfStatement.
4040 bool MipsAsmParser::parseSetNoReorderDirective() {
4041 MCAsmParser &Parser = getParser();
4043 // If this is not the end of the statement, report an error.
4044 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4045 reportParseError("unexpected token, expected end of statement");
4048 AssemblerOptions.back()->setNoReorder();
4049 getTargetStreamer().emitDirectiveSetNoReorder();
4050 Parser.Lex(); // Consume the EndOfStatement.
4054 bool MipsAsmParser::parseSetMacroDirective() {
4055 MCAsmParser &Parser = getParser();
4057 // If this is not the end of the statement, report an error.
4058 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4059 reportParseError("unexpected token, expected end of statement");
4062 AssemblerOptions.back()->setMacro();
4063 getTargetStreamer().emitDirectiveSetMacro();
4064 Parser.Lex(); // Consume the EndOfStatement.
4068 bool MipsAsmParser::parseSetNoMacroDirective() {
4069 MCAsmParser &Parser = getParser();
4071 // If this is not the end of the statement, report an error.
4072 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4073 reportParseError("unexpected token, expected end of statement");
4076 if (AssemblerOptions.back()->isReorder()) {
4077 reportParseError("`noreorder' must be set before `nomacro'");
4080 AssemblerOptions.back()->setNoMacro();
4081 getTargetStreamer().emitDirectiveSetNoMacro();
4082 Parser.Lex(); // Consume the EndOfStatement.
4086 bool MipsAsmParser::parseSetMsaDirective() {
4087 MCAsmParser &Parser = getParser();
4090 // If this is not the end of the statement, report an error.
4091 if (getLexer().isNot(AsmToken::EndOfStatement))
4092 return reportParseError("unexpected token, expected end of statement");
4094 setFeatureBits(Mips::FeatureMSA, "msa");
4095 getTargetStreamer().emitDirectiveSetMsa();
4099 bool MipsAsmParser::parseSetNoMsaDirective() {
4100 MCAsmParser &Parser = getParser();
4103 // If this is not the end of the statement, report an error.
4104 if (getLexer().isNot(AsmToken::EndOfStatement))
4105 return reportParseError("unexpected token, expected end of statement");
4107 clearFeatureBits(Mips::FeatureMSA, "msa");
4108 getTargetStreamer().emitDirectiveSetNoMsa();
4112 bool MipsAsmParser::parseSetNoDspDirective() {
4113 MCAsmParser &Parser = getParser();
4114 Parser.Lex(); // Eat "nodsp".
4116 // If this is not the end of the statement, report an error.
4117 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4118 reportParseError("unexpected token, expected end of statement");
4122 clearFeatureBits(Mips::FeatureDSP, "dsp");
4123 getTargetStreamer().emitDirectiveSetNoDsp();
4127 bool MipsAsmParser::parseSetMips16Directive() {
4128 MCAsmParser &Parser = getParser();
4129 Parser.Lex(); // Eat "mips16".
4131 // If this is not the end of the statement, report an error.
4132 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4133 reportParseError("unexpected token, expected end of statement");
4137 setFeatureBits(Mips::FeatureMips16, "mips16");
4138 getTargetStreamer().emitDirectiveSetMips16();
4139 Parser.Lex(); // Consume the EndOfStatement.
4143 bool MipsAsmParser::parseSetNoMips16Directive() {
4144 MCAsmParser &Parser = getParser();
4145 Parser.Lex(); // Eat "nomips16".
4147 // If this is not the end of the statement, report an error.
4148 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4149 reportParseError("unexpected token, expected end of statement");
4153 clearFeatureBits(Mips::FeatureMips16, "mips16");
4154 getTargetStreamer().emitDirectiveSetNoMips16();
4155 Parser.Lex(); // Consume the EndOfStatement.
4159 bool MipsAsmParser::parseSetFpDirective() {
4160 MCAsmParser &Parser = getParser();
4161 MipsABIFlagsSection::FpABIKind FpAbiVal;
4162 // Line can be: .set fp=32
4165 Parser.Lex(); // Eat fp token
4166 AsmToken Tok = Parser.getTok();
4167 if (Tok.isNot(AsmToken::Equal)) {
4168 reportParseError("unexpected token, expected equals sign '='");
4171 Parser.Lex(); // Eat '=' token.
4172 Tok = Parser.getTok();
4174 if (!parseFpABIValue(FpAbiVal, ".set"))
4177 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4178 reportParseError("unexpected token, expected end of statement");
4181 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4182 Parser.Lex(); // Consume the EndOfStatement.
4186 bool MipsAsmParser::parseSetOddSPRegDirective() {
4187 MCAsmParser &Parser = getParser();
4189 Parser.Lex(); // Eat "oddspreg".
4190 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4191 reportParseError("unexpected token, expected end of statement");
4195 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4196 getTargetStreamer().emitDirectiveSetOddSPReg();
4200 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4201 MCAsmParser &Parser = getParser();
4203 Parser.Lex(); // Eat "nooddspreg".
4204 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4205 reportParseError("unexpected token, expected end of statement");
4209 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4210 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4214 bool MipsAsmParser::parseSetPopDirective() {
4215 MCAsmParser &Parser = getParser();
4216 SMLoc Loc = getLexer().getLoc();
4219 if (getLexer().isNot(AsmToken::EndOfStatement))
4220 return reportParseError("unexpected token, expected end of statement");
4222 // Always keep an element on the options "stack" to prevent the user
4223 // from changing the initial options. This is how we remember them.
4224 if (AssemblerOptions.size() == 2)
4225 return reportParseError(Loc, ".set pop with no .set push");
4227 AssemblerOptions.pop_back();
4228 setAvailableFeatures(
4229 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4230 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4232 getTargetStreamer().emitDirectiveSetPop();
4236 bool MipsAsmParser::parseSetPushDirective() {
4237 MCAsmParser &Parser = getParser();
4239 if (getLexer().isNot(AsmToken::EndOfStatement))
4240 return reportParseError("unexpected token, expected end of statement");
4242 // Create a copy of the current assembler options environment and push it.
4243 AssemblerOptions.push_back(
4244 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4246 getTargetStreamer().emitDirectiveSetPush();
4250 bool MipsAsmParser::parseSetSoftFloatDirective() {
4251 MCAsmParser &Parser = getParser();
4253 if (getLexer().isNot(AsmToken::EndOfStatement))
4254 return reportParseError("unexpected token, expected end of statement");
4256 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4257 getTargetStreamer().emitDirectiveSetSoftFloat();
4261 bool MipsAsmParser::parseSetHardFloatDirective() {
4262 MCAsmParser &Parser = getParser();
4264 if (getLexer().isNot(AsmToken::EndOfStatement))
4265 return reportParseError("unexpected token, expected end of statement");
4267 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4268 getTargetStreamer().emitDirectiveSetHardFloat();
4272 bool MipsAsmParser::parseSetAssignment() {
4274 const MCExpr *Value;
4275 MCAsmParser &Parser = getParser();
4277 if (Parser.parseIdentifier(Name))
4278 reportParseError("expected identifier after .set");
4280 if (getLexer().isNot(AsmToken::Comma))
4281 return reportParseError("unexpected token, expected comma");
4284 if (Parser.parseExpression(Value))
4285 return reportParseError("expected valid expression after comma");
4287 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4288 Sym->setVariableValue(Value);
4293 bool MipsAsmParser::parseSetMips0Directive() {
4294 MCAsmParser &Parser = getParser();
4296 if (getLexer().isNot(AsmToken::EndOfStatement))
4297 return reportParseError("unexpected token, expected end of statement");
4299 // Reset assembler options to their initial values.
4300 setAvailableFeatures(
4301 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4302 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4303 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4305 getTargetStreamer().emitDirectiveSetMips0();
4309 bool MipsAsmParser::parseSetArchDirective() {
4310 MCAsmParser &Parser = getParser();
4312 if (getLexer().isNot(AsmToken::Equal))
4313 return reportParseError("unexpected token, expected equals sign");
4317 if (Parser.parseIdentifier(Arch))
4318 return reportParseError("expected arch identifier");
4320 StringRef ArchFeatureName =
4321 StringSwitch<StringRef>(Arch)
4322 .Case("mips1", "mips1")
4323 .Case("mips2", "mips2")
4324 .Case("mips3", "mips3")
4325 .Case("mips4", "mips4")
4326 .Case("mips5", "mips5")
4327 .Case("mips32", "mips32")
4328 .Case("mips32r2", "mips32r2")
4329 .Case("mips32r3", "mips32r3")
4330 .Case("mips32r5", "mips32r5")
4331 .Case("mips32r6", "mips32r6")
4332 .Case("mips64", "mips64")
4333 .Case("mips64r2", "mips64r2")
4334 .Case("mips64r3", "mips64r3")
4335 .Case("mips64r5", "mips64r5")
4336 .Case("mips64r6", "mips64r6")
4337 .Case("cnmips", "cnmips")
4338 .Case("r4000", "mips3") // This is an implementation of Mips3.
4341 if (ArchFeatureName.empty())
4342 return reportParseError("unsupported architecture");
4344 selectArch(ArchFeatureName);
4345 getTargetStreamer().emitDirectiveSetArch(Arch);
4349 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4350 MCAsmParser &Parser = getParser();
4352 if (getLexer().isNot(AsmToken::EndOfStatement))
4353 return reportParseError("unexpected token, expected end of statement");
4357 llvm_unreachable("Unimplemented feature");
4358 case Mips::FeatureDSP:
4359 setFeatureBits(Mips::FeatureDSP, "dsp");
4360 getTargetStreamer().emitDirectiveSetDsp();
4362 case Mips::FeatureMicroMips:
4363 getTargetStreamer().emitDirectiveSetMicroMips();
4365 case Mips::FeatureMips1:
4366 selectArch("mips1");
4367 getTargetStreamer().emitDirectiveSetMips1();
4369 case Mips::FeatureMips2:
4370 selectArch("mips2");
4371 getTargetStreamer().emitDirectiveSetMips2();
4373 case Mips::FeatureMips3:
4374 selectArch("mips3");
4375 getTargetStreamer().emitDirectiveSetMips3();
4377 case Mips::FeatureMips4:
4378 selectArch("mips4");
4379 getTargetStreamer().emitDirectiveSetMips4();
4381 case Mips::FeatureMips5:
4382 selectArch("mips5");
4383 getTargetStreamer().emitDirectiveSetMips5();
4385 case Mips::FeatureMips32:
4386 selectArch("mips32");
4387 getTargetStreamer().emitDirectiveSetMips32();
4389 case Mips::FeatureMips32r2:
4390 selectArch("mips32r2");
4391 getTargetStreamer().emitDirectiveSetMips32R2();
4393 case Mips::FeatureMips32r3:
4394 selectArch("mips32r3");
4395 getTargetStreamer().emitDirectiveSetMips32R3();
4397 case Mips::FeatureMips32r5:
4398 selectArch("mips32r5");
4399 getTargetStreamer().emitDirectiveSetMips32R5();
4401 case Mips::FeatureMips32r6:
4402 selectArch("mips32r6");
4403 getTargetStreamer().emitDirectiveSetMips32R6();
4405 case Mips::FeatureMips64:
4406 selectArch("mips64");
4407 getTargetStreamer().emitDirectiveSetMips64();
4409 case Mips::FeatureMips64r2:
4410 selectArch("mips64r2");
4411 getTargetStreamer().emitDirectiveSetMips64R2();
4413 case Mips::FeatureMips64r3:
4414 selectArch("mips64r3");
4415 getTargetStreamer().emitDirectiveSetMips64R3();
4417 case Mips::FeatureMips64r5:
4418 selectArch("mips64r5");
4419 getTargetStreamer().emitDirectiveSetMips64R5();
4421 case Mips::FeatureMips64r6:
4422 selectArch("mips64r6");
4423 getTargetStreamer().emitDirectiveSetMips64R6();
4429 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4430 MCAsmParser &Parser = getParser();
4431 if (getLexer().isNot(AsmToken::Comma)) {
4432 SMLoc Loc = getLexer().getLoc();
4433 Parser.eatToEndOfStatement();
4434 return Error(Loc, ErrorStr);
4437 Parser.Lex(); // Eat the comma.
4441 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4442 if (AssemblerOptions.back()->isReorder())
4443 Warning(Loc, ".cpload should be inside a noreorder section");
4445 if (inMips16Mode()) {
4446 reportParseError(".cpload is not supported in Mips16 mode");
4450 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4451 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4452 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4453 reportParseError("expected register containing function address");
4457 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4458 if (!RegOpnd.isGPRAsmReg()) {
4459 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4463 // If this is not the end of the statement, report an error.
4464 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4465 reportParseError("unexpected token, expected end of statement");
4469 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4473 bool MipsAsmParser::parseDirectiveCPSetup() {
4474 MCAsmParser &Parser = getParser();
4477 bool SaveIsReg = true;
4479 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4480 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4481 if (ResTy == MatchOperand_NoMatch) {
4482 reportParseError("expected register containing function address");
4483 Parser.eatToEndOfStatement();
4487 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4488 if (!FuncRegOpnd.isGPRAsmReg()) {
4489 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4490 Parser.eatToEndOfStatement();
4494 FuncReg = FuncRegOpnd.getGPR32Reg();
4497 if (!eatComma("unexpected token, expected comma"))
4500 ResTy = parseAnyRegister(TmpReg);
4501 if (ResTy == MatchOperand_NoMatch) {
4502 const AsmToken &Tok = Parser.getTok();
4503 if (Tok.is(AsmToken::Integer)) {
4504 Save = Tok.getIntVal();
4508 reportParseError("expected save register or stack offset");
4509 Parser.eatToEndOfStatement();
4513 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4514 if (!SaveOpnd.isGPRAsmReg()) {
4515 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4516 Parser.eatToEndOfStatement();
4519 Save = SaveOpnd.getGPR32Reg();
4522 if (!eatComma("unexpected token, expected comma"))
4526 if (Parser.parseExpression(Expr)) {
4527 reportParseError("expected expression");
4531 if (Expr->getKind() != MCExpr::SymbolRef) {
4532 reportParseError("expected symbol");
4535 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4537 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4542 bool MipsAsmParser::parseDirectiveNaN() {
4543 MCAsmParser &Parser = getParser();
4544 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4545 const AsmToken &Tok = Parser.getTok();
4547 if (Tok.getString() == "2008") {
4549 getTargetStreamer().emitDirectiveNaN2008();
4551 } else if (Tok.getString() == "legacy") {
4553 getTargetStreamer().emitDirectiveNaNLegacy();
4557 // If we don't recognize the option passed to the .nan
4558 // directive (e.g. no option or unknown option), emit an error.
4559 reportParseError("invalid option in .nan directive");
4563 bool MipsAsmParser::parseDirectiveSet() {
4564 MCAsmParser &Parser = getParser();
4565 // Get the next token.
4566 const AsmToken &Tok = Parser.getTok();
4568 if (Tok.getString() == "noat") {
4569 return parseSetNoAtDirective();
4570 } else if (Tok.getString() == "at") {
4571 return parseSetAtDirective();
4572 } else if (Tok.getString() == "arch") {
4573 return parseSetArchDirective();
4574 } else if (Tok.getString() == "fp") {
4575 return parseSetFpDirective();
4576 } else if (Tok.getString() == "oddspreg") {
4577 return parseSetOddSPRegDirective();
4578 } else if (Tok.getString() == "nooddspreg") {
4579 return parseSetNoOddSPRegDirective();
4580 } else if (Tok.getString() == "pop") {
4581 return parseSetPopDirective();
4582 } else if (Tok.getString() == "push") {
4583 return parseSetPushDirective();
4584 } else if (Tok.getString() == "reorder") {
4585 return parseSetReorderDirective();
4586 } else if (Tok.getString() == "noreorder") {
4587 return parseSetNoReorderDirective();
4588 } else if (Tok.getString() == "macro") {
4589 return parseSetMacroDirective();
4590 } else if (Tok.getString() == "nomacro") {
4591 return parseSetNoMacroDirective();
4592 } else if (Tok.getString() == "mips16") {
4593 return parseSetMips16Directive();
4594 } else if (Tok.getString() == "nomips16") {
4595 return parseSetNoMips16Directive();
4596 } else if (Tok.getString() == "nomicromips") {
4597 getTargetStreamer().emitDirectiveSetNoMicroMips();
4598 Parser.eatToEndOfStatement();
4600 } else if (Tok.getString() == "micromips") {
4601 return parseSetFeature(Mips::FeatureMicroMips);
4602 } else if (Tok.getString() == "mips0") {
4603 return parseSetMips0Directive();
4604 } else if (Tok.getString() == "mips1") {
4605 return parseSetFeature(Mips::FeatureMips1);
4606 } else if (Tok.getString() == "mips2") {
4607 return parseSetFeature(Mips::FeatureMips2);
4608 } else if (Tok.getString() == "mips3") {
4609 return parseSetFeature(Mips::FeatureMips3);
4610 } else if (Tok.getString() == "mips4") {
4611 return parseSetFeature(Mips::FeatureMips4);
4612 } else if (Tok.getString() == "mips5") {
4613 return parseSetFeature(Mips::FeatureMips5);
4614 } else if (Tok.getString() == "mips32") {
4615 return parseSetFeature(Mips::FeatureMips32);
4616 } else if (Tok.getString() == "mips32r2") {
4617 return parseSetFeature(Mips::FeatureMips32r2);
4618 } else if (Tok.getString() == "mips32r3") {
4619 return parseSetFeature(Mips::FeatureMips32r3);
4620 } else if (Tok.getString() == "mips32r5") {
4621 return parseSetFeature(Mips::FeatureMips32r5);
4622 } else if (Tok.getString() == "mips32r6") {
4623 return parseSetFeature(Mips::FeatureMips32r6);
4624 } else if (Tok.getString() == "mips64") {
4625 return parseSetFeature(Mips::FeatureMips64);
4626 } else if (Tok.getString() == "mips64r2") {
4627 return parseSetFeature(Mips::FeatureMips64r2);
4628 } else if (Tok.getString() == "mips64r3") {
4629 return parseSetFeature(Mips::FeatureMips64r3);
4630 } else if (Tok.getString() == "mips64r5") {
4631 return parseSetFeature(Mips::FeatureMips64r5);
4632 } else if (Tok.getString() == "mips64r6") {
4633 return parseSetFeature(Mips::FeatureMips64r6);
4634 } else if (Tok.getString() == "dsp") {
4635 return parseSetFeature(Mips::FeatureDSP);
4636 } else if (Tok.getString() == "nodsp") {
4637 return parseSetNoDspDirective();
4638 } else if (Tok.getString() == "msa") {
4639 return parseSetMsaDirective();
4640 } else if (Tok.getString() == "nomsa") {
4641 return parseSetNoMsaDirective();
4642 } else if (Tok.getString() == "softfloat") {
4643 return parseSetSoftFloatDirective();
4644 } else if (Tok.getString() == "hardfloat") {
4645 return parseSetHardFloatDirective();
4647 // It is just an identifier, look for an assignment.
4648 parseSetAssignment();
4655 /// parseDataDirective
4656 /// ::= .word [ expression (, expression)* ]
4657 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4658 MCAsmParser &Parser = getParser();
4659 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4661 const MCExpr *Value;
4662 if (getParser().parseExpression(Value))
4665 getParser().getStreamer().EmitValue(Value, Size);
4667 if (getLexer().is(AsmToken::EndOfStatement))
4670 if (getLexer().isNot(AsmToken::Comma))
4671 return Error(L, "unexpected token, expected comma");
4680 /// parseDirectiveGpWord
4681 /// ::= .gpword local_sym
4682 bool MipsAsmParser::parseDirectiveGpWord() {
4683 MCAsmParser &Parser = getParser();
4684 const MCExpr *Value;
4685 // EmitGPRel32Value requires an expression, so we are using base class
4686 // method to evaluate the expression.
4687 if (getParser().parseExpression(Value))
4689 getParser().getStreamer().EmitGPRel32Value(Value);
4691 if (getLexer().isNot(AsmToken::EndOfStatement))
4692 return Error(getLexer().getLoc(),
4693 "unexpected token, expected end of statement");
4694 Parser.Lex(); // Eat EndOfStatement token.
4698 /// parseDirectiveGpDWord
4699 /// ::= .gpdword local_sym
4700 bool MipsAsmParser::parseDirectiveGpDWord() {
4701 MCAsmParser &Parser = getParser();
4702 const MCExpr *Value;
4703 // EmitGPRel64Value requires an expression, so we are using base class
4704 // method to evaluate the expression.
4705 if (getParser().parseExpression(Value))
4707 getParser().getStreamer().EmitGPRel64Value(Value);
4709 if (getLexer().isNot(AsmToken::EndOfStatement))
4710 return Error(getLexer().getLoc(),
4711 "unexpected token, expected end of statement");
4712 Parser.Lex(); // Eat EndOfStatement token.
4716 bool MipsAsmParser::parseDirectiveOption() {
4717 MCAsmParser &Parser = getParser();
4718 // Get the option token.
4719 AsmToken Tok = Parser.getTok();
4720 // At the moment only identifiers are supported.
4721 if (Tok.isNot(AsmToken::Identifier)) {
4722 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4723 Parser.eatToEndOfStatement();
4727 StringRef Option = Tok.getIdentifier();
4729 if (Option == "pic0") {
4730 // MipsAsmParser needs to know if the current PIC mode changes.
4731 IsPicEnabled = false;
4733 getTargetStreamer().emitDirectiveOptionPic0();
4735 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4736 Error(Parser.getTok().getLoc(),
4737 "unexpected token, expected end of statement");
4738 Parser.eatToEndOfStatement();
4743 if (Option == "pic2") {
4744 // MipsAsmParser needs to know if the current PIC mode changes.
4745 IsPicEnabled = true;
4747 getTargetStreamer().emitDirectiveOptionPic2();
4749 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4750 Error(Parser.getTok().getLoc(),
4751 "unexpected token, expected end of statement");
4752 Parser.eatToEndOfStatement();
4758 Warning(Parser.getTok().getLoc(),
4759 "unknown option, expected 'pic0' or 'pic2'");
4760 Parser.eatToEndOfStatement();
4764 /// parseInsnDirective
4766 bool MipsAsmParser::parseInsnDirective() {
4767 // If this is not the end of the statement, report an error.
4768 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4769 reportParseError("unexpected token, expected end of statement");
4773 // The actual label marking happens in
4774 // MipsELFStreamer::createPendingLabelRelocs().
4775 getTargetStreamer().emitDirectiveInsn();
4777 getParser().Lex(); // Eat EndOfStatement token.
4781 /// parseDirectiveModule
4782 /// ::= .module oddspreg
4783 /// ::= .module nooddspreg
4784 /// ::= .module fp=value
4785 /// ::= .module softfloat
4786 /// ::= .module hardfloat
4787 bool MipsAsmParser::parseDirectiveModule() {
4788 MCAsmParser &Parser = getParser();
4789 MCAsmLexer &Lexer = getLexer();
4790 SMLoc L = Lexer.getLoc();
4792 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4793 // TODO : get a better message.
4794 reportParseError(".module directive must appear before any code");
4799 if (Parser.parseIdentifier(Option)) {
4800 reportParseError("expected .module option identifier");
4804 if (Option == "oddspreg") {
4805 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4807 // Synchronize the abiflags information with the FeatureBits information we
4809 getTargetStreamer().updateABIInfo(*this);
4811 // If printing assembly, use the recently updated abiflags information.
4812 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4813 // emitted at the end).
4814 getTargetStreamer().emitDirectiveModuleOddSPReg();
4816 // If this is not the end of the statement, report an error.
4817 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4818 reportParseError("unexpected token, expected end of statement");
4822 return false; // parseDirectiveModule has finished successfully.
4823 } else if (Option == "nooddspreg") {
4825 Error(L, "'.module nooddspreg' requires the O32 ABI");
4829 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4831 // Synchronize the abiflags information with the FeatureBits information we
4833 getTargetStreamer().updateABIInfo(*this);
4835 // If printing assembly, use the recently updated abiflags information.
4836 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4837 // emitted at the end).
4838 getTargetStreamer().emitDirectiveModuleOddSPReg();
4840 // If this is not the end of the statement, report an error.
4841 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4842 reportParseError("unexpected token, expected end of statement");
4846 return false; // parseDirectiveModule has finished successfully.
4847 } else if (Option == "fp") {
4848 return parseDirectiveModuleFP();
4849 } else if (Option == "softfloat") {
4850 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4852 // Synchronize the ABI Flags information with the FeatureBits information we
4854 getTargetStreamer().updateABIInfo(*this);
4856 // If printing assembly, use the recently updated ABI Flags information.
4857 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4859 getTargetStreamer().emitDirectiveModuleSoftFloat();
4861 // If this is not the end of the statement, report an error.
4862 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4863 reportParseError("unexpected token, expected end of statement");
4867 return false; // parseDirectiveModule has finished successfully.
4868 } else if (Option == "hardfloat") {
4869 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4871 // Synchronize the ABI Flags information with the FeatureBits information we
4873 getTargetStreamer().updateABIInfo(*this);
4875 // If printing assembly, use the recently updated ABI Flags information.
4876 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4878 getTargetStreamer().emitDirectiveModuleHardFloat();
4880 // If this is not the end of the statement, report an error.
4881 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4882 reportParseError("unexpected token, expected end of statement");
4886 return false; // parseDirectiveModule has finished successfully.
4888 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4892 /// parseDirectiveModuleFP
4896 bool MipsAsmParser::parseDirectiveModuleFP() {
4897 MCAsmParser &Parser = getParser();
4898 MCAsmLexer &Lexer = getLexer();
4900 if (Lexer.isNot(AsmToken::Equal)) {
4901 reportParseError("unexpected token, expected equals sign '='");
4904 Parser.Lex(); // Eat '=' token.
4906 MipsABIFlagsSection::FpABIKind FpABI;
4907 if (!parseFpABIValue(FpABI, ".module"))
4910 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4911 reportParseError("unexpected token, expected end of statement");
4915 // Synchronize the abiflags information with the FeatureBits information we
4917 getTargetStreamer().updateABIInfo(*this);
4919 // If printing assembly, use the recently updated abiflags information.
4920 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4921 // emitted at the end).
4922 getTargetStreamer().emitDirectiveModuleFP();
4924 Parser.Lex(); // Consume the EndOfStatement.
4928 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4929 StringRef Directive) {
4930 MCAsmParser &Parser = getParser();
4931 MCAsmLexer &Lexer = getLexer();
4932 bool ModuleLevelOptions = Directive == ".module";
4934 if (Lexer.is(AsmToken::Identifier)) {
4935 StringRef Value = Parser.getTok().getString();
4938 if (Value != "xx") {
4939 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4944 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4948 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4949 if (ModuleLevelOptions) {
4950 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4951 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4953 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4954 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4959 if (Lexer.is(AsmToken::Integer)) {
4960 unsigned Value = Parser.getTok().getIntVal();
4963 if (Value != 32 && Value != 64) {
4964 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4970 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4974 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4975 if (ModuleLevelOptions) {
4976 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4977 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4979 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4980 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4983 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4984 if (ModuleLevelOptions) {
4985 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4986 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4988 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4989 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4999 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5000 MCAsmParser &Parser = getParser();
5001 StringRef IDVal = DirectiveID.getString();
5003 if (IDVal == ".cpload")
5004 return parseDirectiveCpLoad(DirectiveID.getLoc());
5005 if (IDVal == ".dword") {
5006 parseDataDirective(8, DirectiveID.getLoc());
5009 if (IDVal == ".ent") {
5010 StringRef SymbolName;
5012 if (Parser.parseIdentifier(SymbolName)) {
5013 reportParseError("expected identifier after .ent");
5017 // There's an undocumented extension that allows an integer to
5018 // follow the name of the procedure which AFAICS is ignored by GAS.
5019 // Example: .ent foo,2
5020 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5021 if (getLexer().isNot(AsmToken::Comma)) {
5022 // Even though we accept this undocumented extension for compatibility
5023 // reasons, the additional integer argument does not actually change
5024 // the behaviour of the '.ent' directive, so we would like to discourage
5025 // its use. We do this by not referring to the extended version in
5026 // error messages which are not directly related to its use.
5027 reportParseError("unexpected token, expected end of statement");
5030 Parser.Lex(); // Eat the comma.
5031 const MCExpr *DummyNumber;
5032 int64_t DummyNumberVal;
5033 // If the user was explicitly trying to use the extended version,
5034 // we still give helpful extension-related error messages.
5035 if (Parser.parseExpression(DummyNumber)) {
5036 reportParseError("expected number after comma");
5039 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5040 reportParseError("expected an absolute expression after comma");
5045 // If this is not the end of the statement, report an error.
5046 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5047 reportParseError("unexpected token, expected end of statement");
5051 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5053 getTargetStreamer().emitDirectiveEnt(*Sym);
5058 if (IDVal == ".end") {
5059 StringRef SymbolName;
5061 if (Parser.parseIdentifier(SymbolName)) {
5062 reportParseError("expected identifier after .end");
5066 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5067 reportParseError("unexpected token, expected end of statement");
5071 if (CurrentFn == nullptr) {
5072 reportParseError(".end used without .ent");
5076 if ((SymbolName != CurrentFn->getName())) {
5077 reportParseError(".end symbol does not match .ent symbol");
5081 getTargetStreamer().emitDirectiveEnd(SymbolName);
5082 CurrentFn = nullptr;
5086 if (IDVal == ".frame") {
5087 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5088 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5089 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5090 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5091 reportParseError("expected stack register");
5095 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5096 if (!StackRegOpnd.isGPRAsmReg()) {
5097 reportParseError(StackRegOpnd.getStartLoc(),
5098 "expected general purpose register");
5101 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5103 if (Parser.getTok().is(AsmToken::Comma))
5106 reportParseError("unexpected token, expected comma");
5110 // Parse the frame size.
5111 const MCExpr *FrameSize;
5112 int64_t FrameSizeVal;
5114 if (Parser.parseExpression(FrameSize)) {
5115 reportParseError("expected frame size value");
5119 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5120 reportParseError("frame size not an absolute expression");
5124 if (Parser.getTok().is(AsmToken::Comma))
5127 reportParseError("unexpected token, expected comma");
5131 // Parse the return register.
5133 ResTy = parseAnyRegister(TmpReg);
5134 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5135 reportParseError("expected return register");
5139 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5140 if (!ReturnRegOpnd.isGPRAsmReg()) {
5141 reportParseError(ReturnRegOpnd.getStartLoc(),
5142 "expected general purpose register");
5146 // If this is not the end of the statement, report an error.
5147 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5148 reportParseError("unexpected token, expected end of statement");
5152 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5153 ReturnRegOpnd.getGPR32Reg());
5157 if (IDVal == ".set") {
5158 return parseDirectiveSet();
5161 if (IDVal == ".mask" || IDVal == ".fmask") {
5162 // .mask bitmask, frame_offset
5163 // bitmask: One bit for each register used.
5164 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5165 // first register is expected to be saved.
5167 // .mask 0x80000000, -4
5168 // .fmask 0x80000000, -4
5171 // Parse the bitmask
5172 const MCExpr *BitMask;
5175 if (Parser.parseExpression(BitMask)) {
5176 reportParseError("expected bitmask value");
5180 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5181 reportParseError("bitmask not an absolute expression");
5185 if (Parser.getTok().is(AsmToken::Comma))
5188 reportParseError("unexpected token, expected comma");
5192 // Parse the frame_offset
5193 const MCExpr *FrameOffset;
5194 int64_t FrameOffsetVal;
5196 if (Parser.parseExpression(FrameOffset)) {
5197 reportParseError("expected frame offset value");
5201 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5202 reportParseError("frame offset not an absolute expression");
5206 // If this is not the end of the statement, report an error.
5207 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5208 reportParseError("unexpected token, expected end of statement");
5212 if (IDVal == ".mask")
5213 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5215 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5219 if (IDVal == ".nan")
5220 return parseDirectiveNaN();
5222 if (IDVal == ".gpword") {
5223 parseDirectiveGpWord();
5227 if (IDVal == ".gpdword") {
5228 parseDirectiveGpDWord();
5232 if (IDVal == ".word") {
5233 parseDataDirective(4, DirectiveID.getLoc());
5237 if (IDVal == ".option")
5238 return parseDirectiveOption();
5240 if (IDVal == ".abicalls") {
5241 getTargetStreamer().emitDirectiveAbiCalls();
5242 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5243 Error(Parser.getTok().getLoc(),
5244 "unexpected token, expected end of statement");
5246 Parser.eatToEndOfStatement();
5251 if (IDVal == ".cpsetup")
5252 return parseDirectiveCPSetup();
5254 if (IDVal == ".module")
5255 return parseDirectiveModule();
5257 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5258 return parseInternalDirectiveReallowModule();
5260 if (IDVal == ".insn")
5261 return parseInsnDirective();
5266 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5267 // If this is not the end of the statement, report an error.
5268 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5269 reportParseError("unexpected token, expected end of statement");
5273 getTargetStreamer().reallowModuleDirective();
5275 getParser().Lex(); // Eat EndOfStatement token.
5279 extern "C" void LLVMInitializeMipsAsmParser() {
5280 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5281 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5282 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5283 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5286 #define GET_REGISTER_MATCHER
5287 #define GET_MATCHER_IMPLEMENTATION
5288 #include "MipsGenAsmMatcher.inc"