1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(const FeatureBitset &Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 const FeatureBitset &getFeatures() const { return Features; }
74 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const FeatureBitset AllArchRelatedMask;
87 FeatureBitset Features;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
118 // Print a warning along with its fix-it message at the given range.
119 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
120 SMRange Range, bool ShowColors = true);
122 #define GET_ASSEMBLER_HEADER
123 #include "MipsGenAsmMatcher.inc"
125 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
127 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
128 OperandVector &Operands, MCStreamer &Out,
130 bool MatchingInlineAsm) override;
132 /// Parse a register as used in CFI directives
133 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
135 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
137 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
139 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
140 SMLoc NameLoc, OperandVector &Operands) override;
142 bool ParseDirective(AsmToken DirectiveID) override;
144 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
148 StringRef Identifier, SMLoc S);
150 MipsAsmParser::OperandMatchResultTy
151 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
153 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
161 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
163 MipsAsmParser::OperandMatchResultTy
164 parseRegisterPair (OperandVector &Operands);
166 MipsAsmParser::OperandMatchResultTy
167 parseMovePRegPair(OperandVector &Operands);
169 MipsAsmParser::OperandMatchResultTy
170 parseRegisterList (OperandVector &Operands);
172 bool searchSymbolAlias(OperandVector &Operands);
174 bool parseOperand(OperandVector &, StringRef Mnemonic);
176 bool needsExpansion(MCInst &Inst);
178 // Expands assembly pseudo instructions.
179 // Returns false on success, true otherwise.
180 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions);
183 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
184 SmallVectorImpl<MCInst> &Instructions);
186 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
187 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
188 SmallVectorImpl<MCInst> &Instructions);
190 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
191 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
192 SmallVectorImpl<MCInst> &Instructions);
194 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
195 SmallVectorImpl<MCInst> &Instructions);
197 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
198 const MCOperand &Offset, bool Is32BitAddress,
199 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
201 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
202 SmallVectorImpl<MCInst> &Instructions);
204 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
208 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
209 SmallVectorImpl<MCInst> &Instructions);
211 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
215 SmallVectorImpl<MCInst> &Instructions);
217 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
218 SmallVectorImpl<MCInst> &Instructions);
220 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
221 SmallVectorImpl<MCInst> &Instructions);
223 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
224 SmallVectorImpl<MCInst> &Instructions);
226 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
227 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
229 bool reportParseError(Twine ErrorMsg);
230 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
232 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
233 bool parseRelocOperand(const MCExpr *&Res);
235 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
237 bool isEvaluated(const MCExpr *Expr);
238 bool parseSetMips0Directive();
239 bool parseSetArchDirective();
240 bool parseSetFeature(uint64_t Feature);
241 bool parseDirectiveCpLoad(SMLoc Loc);
242 bool parseDirectiveCPSetup();
243 bool parseDirectiveNaN();
244 bool parseDirectiveSet();
245 bool parseDirectiveOption();
246 bool parseInsnDirective();
248 bool parseSetAtDirective();
249 bool parseSetNoAtDirective();
250 bool parseSetMacroDirective();
251 bool parseSetNoMacroDirective();
252 bool parseSetMsaDirective();
253 bool parseSetNoMsaDirective();
254 bool parseSetNoDspDirective();
255 bool parseSetReorderDirective();
256 bool parseSetNoReorderDirective();
257 bool parseSetMips16Directive();
258 bool parseSetNoMips16Directive();
259 bool parseSetFpDirective();
260 bool parseSetOddSPRegDirective();
261 bool parseSetNoOddSPRegDirective();
262 bool parseSetPopDirective();
263 bool parseSetPushDirective();
264 bool parseSetSoftFloatDirective();
265 bool parseSetHardFloatDirective();
267 bool parseSetAssignment();
269 bool parseDataDirective(unsigned Size, SMLoc L);
270 bool parseDirectiveGpWord();
271 bool parseDirectiveGpDWord();
272 bool parseDirectiveModule();
273 bool parseDirectiveModuleFP();
274 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
275 StringRef Directive);
277 bool parseInternalDirectiveReallowModule();
279 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
281 bool eatComma(StringRef ErrorStr);
283 int matchCPURegisterName(StringRef Symbol);
285 int matchHWRegsRegisterName(StringRef Symbol);
287 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
289 int matchFPURegisterName(StringRef Name);
291 int matchFCCRegisterName(StringRef Name);
293 int matchACRegisterName(StringRef Name);
295 int matchMSA128RegisterName(StringRef Name);
297 int matchMSA128CtrlRegisterName(StringRef Name);
299 unsigned getReg(int RC, int RegNo);
301 unsigned getGPR(int RegNo);
303 /// Returns the internal register number for the current AT. Also checks if
304 /// the current AT is unavailable (set to $0) and gives an error if it is.
305 /// This should be used in pseudo-instruction expansions which need AT.
306 unsigned getATReg(SMLoc Loc);
308 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
309 SmallVectorImpl<MCInst> &Instructions);
311 // Helper function that checks if the value of a vector index is within the
312 // boundaries of accepted values for each RegisterKind
313 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
314 bool validateMSAIndex(int Val, int RegKind);
316 // Selects a new architecture by updating the FeatureBits with the necessary
317 // info including implied dependencies.
318 // Internally, it clears all the feature bits related to *any* architecture
319 // and selects the new one using the ToggleFeature functionality of the
320 // MCSubtargetInfo object that handles implied dependencies. The reason we
321 // clear all the arch related bits manually is because ToggleFeature only
322 // clears the features that imply the feature being cleared and not the
323 // features implied by the feature being cleared. This is easier to see
325 // --------------------------------------------------
326 // | Feature | Implies |
327 // | -------------------------------------------------|
328 // | FeatureMips1 | None |
329 // | FeatureMips2 | FeatureMips1 |
330 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
331 // | FeatureMips4 | FeatureMips3 |
333 // --------------------------------------------------
335 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
336 // FeatureMipsGP64 | FeatureMips1)
337 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
338 void selectArch(StringRef ArchFeature) {
339 FeatureBitset FeatureBits = STI.getFeatureBits();
340 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
341 STI.setFeatureBits(FeatureBits);
342 setAvailableFeatures(
343 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
344 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
347 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
348 if (!(STI.getFeatureBits()[Feature])) {
349 setAvailableFeatures(
350 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
351 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
355 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
356 if (STI.getFeatureBits()[Feature]) {
357 setAvailableFeatures(
358 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
359 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
363 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
364 setFeatureBits(Feature, FeatureString);
365 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
368 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
369 clearFeatureBits(Feature, FeatureString);
370 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
374 enum MipsMatchResultTy {
375 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
376 #define GET_OPERAND_DIAGNOSTIC_TYPES
377 #include "MipsGenAsmMatcher.inc"
378 #undef GET_OPERAND_DIAGNOSTIC_TYPES
382 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
383 const MCInstrInfo &MII, const MCTargetOptions &Options)
384 : MCTargetAsmParser(Options), STI(sti),
385 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
386 sti.getCPU(), Options)) {
387 MCAsmParserExtension::Initialize(parser);
389 parser.addAliasForDirective(".asciiz", ".asciz");
391 // Initialize the set of available features.
392 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
394 // Remember the initial assembler options. The user can not modify these.
395 AssemblerOptions.push_back(
396 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
398 // Create an assembler options environment for the user to modify.
399 AssemblerOptions.push_back(
400 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
402 getTargetStreamer().updateABIInfo(*this);
404 if (!isABI_O32() && !useOddSPReg() != 0)
405 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
409 Triple TheTriple(sti.getTargetTriple());
410 if ((TheTriple.getArch() == Triple::mips) ||
411 (TheTriple.getArch() == Triple::mips64))
412 IsLittleEndian = false;
414 IsLittleEndian = true;
417 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
418 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
420 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
421 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
422 const MipsABIInfo &getABI() const { return ABI; }
423 bool isABI_N32() const { return ABI.IsN32(); }
424 bool isABI_N64() const { return ABI.IsN64(); }
425 bool isABI_O32() const { return ABI.IsO32(); }
426 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
428 bool useOddSPReg() const {
429 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
432 bool inMicroMipsMode() const {
433 return STI.getFeatureBits()[Mips::FeatureMicroMips];
435 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
436 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
437 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
438 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
439 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
440 bool hasMips32() const {
441 return STI.getFeatureBits()[Mips::FeatureMips32];
443 bool hasMips64() const {
444 return STI.getFeatureBits()[Mips::FeatureMips64];
446 bool hasMips32r2() const {
447 return STI.getFeatureBits()[Mips::FeatureMips32r2];
449 bool hasMips64r2() const {
450 return STI.getFeatureBits()[Mips::FeatureMips64r2];
452 bool hasMips32r3() const {
453 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
455 bool hasMips64r3() const {
456 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
458 bool hasMips32r5() const {
459 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
461 bool hasMips64r5() const {
462 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
464 bool hasMips32r6() const {
465 return STI.getFeatureBits()[Mips::FeatureMips32r6];
467 bool hasMips64r6() const {
468 return STI.getFeatureBits()[Mips::FeatureMips64r6];
471 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
472 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
473 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
474 bool hasCnMips() const {
475 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
478 bool inMips16Mode() const {
479 return STI.getFeatureBits()[Mips::FeatureMips16];
482 bool useSoftFloat() const {
483 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
486 /// Warn if RegIndex is the same as the current AT.
487 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
489 void warnIfNoMacro(SMLoc Loc);
491 bool isLittle() const { return IsLittleEndian; }
497 /// MipsOperand - Instances of this class represent a parsed Mips machine
499 class MipsOperand : public MCParsedAsmOperand {
501 /// Broad categories of register classes
502 /// The exact class is finalized by the render method.
504 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
505 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
507 RegKind_FCC = 4, /// FCC
508 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
509 RegKind_MSACtrl = 16, /// MSA control registers
510 RegKind_COP2 = 32, /// COP2
511 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
513 RegKind_CCR = 128, /// CCR
514 RegKind_HWRegs = 256, /// HWRegs
515 RegKind_COP3 = 512, /// COP3
516 RegKind_COP0 = 1024, /// COP0
517 /// Potentially any (e.g. $1)
518 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
519 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
520 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
525 k_Immediate, /// An immediate (possibly involving symbol references)
526 k_Memory, /// Base + Offset Memory Address
527 k_PhysRegister, /// A physical register from the Mips namespace
528 k_RegisterIndex, /// A register index in one or more RegKind.
529 k_Token, /// A simple token
530 k_RegList, /// A physical register list
531 k_RegPair /// A pair of physical register
535 MipsOperand(KindTy K, MipsAsmParser &Parser)
536 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
539 /// For diagnostics, and checking the assembler temporary
540 MipsAsmParser &AsmParser;
548 unsigned Num; /// Register Number
552 unsigned Index; /// Index into the register class
553 RegKind Kind; /// Bitfield of the kinds it could possibly be
554 const MCRegisterInfo *RegInfo;
567 SmallVector<unsigned, 10> *List;
572 struct PhysRegOp PhysReg;
573 struct RegIdxOp RegIdx;
576 struct RegListOp RegList;
579 SMLoc StartLoc, EndLoc;
581 /// Internal constructor for register kinds
582 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
583 const MCRegisterInfo *RegInfo,
585 MipsAsmParser &Parser) {
586 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
587 Op->RegIdx.Index = Index;
588 Op->RegIdx.RegInfo = RegInfo;
589 Op->RegIdx.Kind = RegKind;
596 /// Coerce the register to GPR32 and return the real register for the current
598 unsigned getGPR32Reg() const {
599 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
600 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
601 unsigned ClassID = Mips::GPR32RegClassID;
602 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
605 /// Coerce the register to GPR32 and return the real register for the current
607 unsigned getGPRMM16Reg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
609 unsigned ClassID = Mips::GPR32RegClassID;
610 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
613 /// Coerce the register to GPR64 and return the real register for the current
615 unsigned getGPR64Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
617 unsigned ClassID = Mips::GPR64RegClassID;
618 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
622 /// Coerce the register to AFGR64 and return the real register for the current
624 unsigned getAFGR64Reg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
626 if (RegIdx.Index % 2 != 0)
627 AsmParser.Warning(StartLoc, "Float register should be even.");
628 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
629 .getRegister(RegIdx.Index / 2);
632 /// Coerce the register to FGR64 and return the real register for the current
634 unsigned getFGR64Reg() const {
635 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
636 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
637 .getRegister(RegIdx.Index);
640 /// Coerce the register to FGR32 and return the real register for the current
642 unsigned getFGR32Reg() const {
643 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
644 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
645 .getRegister(RegIdx.Index);
648 /// Coerce the register to FGRH32 and return the real register for the current
650 unsigned getFGRH32Reg() const {
651 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
652 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
653 .getRegister(RegIdx.Index);
656 /// Coerce the register to FCC and return the real register for the current
658 unsigned getFCCReg() const {
659 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
660 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
661 .getRegister(RegIdx.Index);
664 /// Coerce the register to MSA128 and return the real register for the current
666 unsigned getMSA128Reg() const {
667 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
668 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
670 unsigned ClassID = Mips::MSA128BRegClassID;
671 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
674 /// Coerce the register to MSACtrl and return the real register for the
676 unsigned getMSACtrlReg() const {
677 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
678 unsigned ClassID = Mips::MSACtrlRegClassID;
679 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
682 /// Coerce the register to COP0 and return the real register for the
684 unsigned getCOP0Reg() const {
685 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
686 unsigned ClassID = Mips::COP0RegClassID;
687 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
690 /// Coerce the register to COP2 and return the real register for the
692 unsigned getCOP2Reg() const {
693 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
694 unsigned ClassID = Mips::COP2RegClassID;
695 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
698 /// Coerce the register to COP3 and return the real register for the
700 unsigned getCOP3Reg() const {
701 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
702 unsigned ClassID = Mips::COP3RegClassID;
703 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
706 /// Coerce the register to ACC64DSP and return the real register for the
708 unsigned getACC64DSPReg() const {
709 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
710 unsigned ClassID = Mips::ACC64DSPRegClassID;
711 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
714 /// Coerce the register to HI32DSP and return the real register for the
716 unsigned getHI32DSPReg() const {
717 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
718 unsigned ClassID = Mips::HI32DSPRegClassID;
719 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
722 /// Coerce the register to LO32DSP and return the real register for the
724 unsigned getLO32DSPReg() const {
725 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
726 unsigned ClassID = Mips::LO32DSPRegClassID;
727 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
730 /// Coerce the register to CCR and return the real register for the
732 unsigned getCCRReg() const {
733 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
734 unsigned ClassID = Mips::CCRRegClassID;
735 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
738 /// Coerce the register to HWRegs and return the real register for the
740 unsigned getHWRegsReg() const {
741 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
742 unsigned ClassID = Mips::HWRegsRegClassID;
743 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
747 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
748 // Add as immediate when possible. Null MCExpr = 0.
750 Inst.addOperand(MCOperand::createImm(0));
751 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
752 Inst.addOperand(MCOperand::createImm(CE->getValue()));
754 Inst.addOperand(MCOperand::createExpr(Expr));
757 void addRegOperands(MCInst &Inst, unsigned N) const {
758 llvm_unreachable("Use a custom parser instead");
761 /// Render the operand to an MCInst as a GPR32
762 /// Asserts if the wrong number of operands are requested, or the operand
763 /// is not a k_RegisterIndex compatible with RegKind_GPR
764 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
769 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
770 assert(N == 1 && "Invalid number of operands!");
771 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
774 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 1 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
779 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
784 /// Render the operand to an MCInst as a GPR64
785 /// Asserts if the wrong number of operands are requested, or the operand
786 /// is not a k_RegisterIndex compatible with RegKind_GPR
787 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
788 assert(N == 1 && "Invalid number of operands!");
789 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
792 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
793 assert(N == 1 && "Invalid number of operands!");
794 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
797 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
798 assert(N == 1 && "Invalid number of operands!");
799 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
802 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
803 assert(N == 1 && "Invalid number of operands!");
804 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
805 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
806 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
807 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
811 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
812 assert(N == 1 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
816 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
817 assert(N == 1 && "Invalid number of operands!");
818 Inst.addOperand(MCOperand::createReg(getFCCReg()));
821 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
822 assert(N == 1 && "Invalid number of operands!");
823 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
826 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
827 assert(N == 1 && "Invalid number of operands!");
828 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
831 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
832 assert(N == 1 && "Invalid number of operands!");
833 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
836 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
837 assert(N == 1 && "Invalid number of operands!");
838 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
841 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
842 assert(N == 1 && "Invalid number of operands!");
843 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
846 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
847 assert(N == 1 && "Invalid number of operands!");
848 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
851 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
852 assert(N == 1 && "Invalid number of operands!");
853 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
856 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
857 assert(N == 1 && "Invalid number of operands!");
858 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
861 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
862 assert(N == 1 && "Invalid number of operands!");
863 Inst.addOperand(MCOperand::createReg(getCCRReg()));
866 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
867 assert(N == 1 && "Invalid number of operands!");
868 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
871 void addImmOperands(MCInst &Inst, unsigned N) const {
872 assert(N == 1 && "Invalid number of operands!");
873 const MCExpr *Expr = getImm();
877 void addMemOperands(MCInst &Inst, unsigned N) const {
878 assert(N == 2 && "Invalid number of operands!");
880 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
881 ? getMemBase()->getGPR64Reg()
882 : getMemBase()->getGPR32Reg()));
884 const MCExpr *Expr = getMemOff();
888 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
889 assert(N == 2 && "Invalid number of operands!");
891 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
893 const MCExpr *Expr = getMemOff();
897 void addRegListOperands(MCInst &Inst, unsigned N) const {
898 assert(N == 1 && "Invalid number of operands!");
900 for (auto RegNo : getRegList())
901 Inst.addOperand(MCOperand::createReg(RegNo));
904 void addRegPairOperands(MCInst &Inst, unsigned N) const {
905 assert(N == 2 && "Invalid number of operands!");
906 unsigned RegNo = getRegPair();
907 Inst.addOperand(MCOperand::createReg(RegNo++));
908 Inst.addOperand(MCOperand::createReg(RegNo));
911 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
912 assert(N == 2 && "Invalid number of operands!");
913 for (auto RegNo : getRegList())
914 Inst.addOperand(MCOperand::createReg(RegNo));
917 bool isReg() const override {
918 // As a special case until we sort out the definition of div/divu, pretend
919 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
920 if (isGPRAsmReg() && RegIdx.Index == 0)
923 return Kind == k_PhysRegister;
925 bool isRegIdx() const { return Kind == k_RegisterIndex; }
926 bool isImm() const override { return Kind == k_Immediate; }
927 bool isConstantImm() const {
928 return isImm() && dyn_cast<MCConstantExpr>(getImm());
930 template <unsigned Bits> bool isUImm() const {
931 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
933 bool isToken() const override {
934 // Note: It's not possible to pretend that other operand kinds are tokens.
935 // The matcher emitter checks tokens first.
936 return Kind == k_Token;
938 bool isMem() const override { return Kind == k_Memory; }
939 bool isConstantMemOff() const {
940 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
942 template <unsigned Bits> bool isMemWithSimmOffset() const {
943 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
945 bool isMemWithGRPMM16Base() const {
946 return isMem() && getMemBase()->isMM16AsmReg();
948 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
949 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
950 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
952 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
953 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
954 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
955 && (getMemBase()->getGPR32Reg() == Mips::SP);
957 bool isRegList16() const {
961 int Size = RegList.List->size();
962 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
963 RegList.List->back() != Mips::RA)
966 int PrevReg = *RegList.List->begin();
967 for (int i = 1; i < Size - 1; i++) {
968 int Reg = (*(RegList.List))[i];
969 if ( Reg != PrevReg + 1)
976 bool isInvNum() const { return Kind == k_Immediate; }
977 bool isLSAImm() const {
978 if (!isConstantImm())
980 int64_t Val = getConstantImm();
981 return 1 <= Val && Val <= 4;
983 bool isRegList() const { return Kind == k_RegList; }
984 bool isMovePRegPair() const {
985 if (Kind != k_RegList || RegList.List->size() != 2)
988 unsigned R0 = RegList.List->front();
989 unsigned R1 = RegList.List->back();
991 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
992 (R0 == Mips::A1 && R1 == Mips::A3) ||
993 (R0 == Mips::A2 && R1 == Mips::A3) ||
994 (R0 == Mips::A0 && R1 == Mips::S5) ||
995 (R0 == Mips::A0 && R1 == Mips::S6) ||
996 (R0 == Mips::A0 && R1 == Mips::A1) ||
997 (R0 == Mips::A0 && R1 == Mips::A2) ||
998 (R0 == Mips::A0 && R1 == Mips::A3))
1004 StringRef getToken() const {
1005 assert(Kind == k_Token && "Invalid access!");
1006 return StringRef(Tok.Data, Tok.Length);
1008 bool isRegPair() const { return Kind == k_RegPair; }
1010 unsigned getReg() const override {
1011 // As a special case until we sort out the definition of div/divu, pretend
1012 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1013 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1014 RegIdx.Kind & RegKind_GPR)
1015 return getGPR32Reg(); // FIXME: GPR64 too
1017 assert(Kind == k_PhysRegister && "Invalid access!");
1021 const MCExpr *getImm() const {
1022 assert((Kind == k_Immediate) && "Invalid access!");
1026 int64_t getConstantImm() const {
1027 const MCExpr *Val = getImm();
1028 return static_cast<const MCConstantExpr *>(Val)->getValue();
1031 MipsOperand *getMemBase() const {
1032 assert((Kind == k_Memory) && "Invalid access!");
1036 const MCExpr *getMemOff() const {
1037 assert((Kind == k_Memory) && "Invalid access!");
1041 int64_t getConstantMemOff() const {
1042 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1045 const SmallVectorImpl<unsigned> &getRegList() const {
1046 assert((Kind == k_RegList) && "Invalid access!");
1047 return *(RegList.List);
1050 unsigned getRegPair() const {
1051 assert((Kind == k_RegPair) && "Invalid access!");
1052 return RegIdx.Index;
1055 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1056 MipsAsmParser &Parser) {
1057 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1058 Op->Tok.Data = Str.data();
1059 Op->Tok.Length = Str.size();
1065 /// Create a numeric register (e.g. $1). The exact register remains
1066 /// unresolved until an instruction successfully matches
1067 static std::unique_ptr<MipsOperand>
1068 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1069 SMLoc E, MipsAsmParser &Parser) {
1070 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1071 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1074 /// Create a register that is definitely a GPR.
1075 /// This is typically only used for named registers such as $gp.
1076 static std::unique_ptr<MipsOperand>
1077 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1078 MipsAsmParser &Parser) {
1079 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1082 /// Create a register that is definitely a FGR.
1083 /// This is typically only used for named registers such as $f0.
1084 static std::unique_ptr<MipsOperand>
1085 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1086 MipsAsmParser &Parser) {
1087 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1090 /// Create a register that is definitely a HWReg.
1091 /// This is typically only used for named registers such as $hwr_cpunum.
1092 static std::unique_ptr<MipsOperand>
1093 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1094 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1095 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1098 /// Create a register that is definitely an FCC.
1099 /// This is typically only used for named registers such as $fcc0.
1100 static std::unique_ptr<MipsOperand>
1101 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1102 MipsAsmParser &Parser) {
1103 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1106 /// Create a register that is definitely an ACC.
1107 /// This is typically only used for named registers such as $ac0.
1108 static std::unique_ptr<MipsOperand>
1109 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1110 MipsAsmParser &Parser) {
1111 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1114 /// Create a register that is definitely an MSA128.
1115 /// This is typically only used for named registers such as $w0.
1116 static std::unique_ptr<MipsOperand>
1117 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1118 SMLoc E, MipsAsmParser &Parser) {
1119 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1122 /// Create a register that is definitely an MSACtrl.
1123 /// This is typically only used for named registers such as $msaaccess.
1124 static std::unique_ptr<MipsOperand>
1125 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1126 SMLoc E, MipsAsmParser &Parser) {
1127 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1130 static std::unique_ptr<MipsOperand>
1131 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1132 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1139 static std::unique_ptr<MipsOperand>
1140 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1141 SMLoc E, MipsAsmParser &Parser) {
1142 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1143 Op->Mem.Base = Base.release();
1150 static std::unique_ptr<MipsOperand>
1151 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1152 MipsAsmParser &Parser) {
1153 assert (Regs.size() > 0 && "Empty list not allowed");
1155 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1156 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1157 Op->StartLoc = StartLoc;
1158 Op->EndLoc = EndLoc;
1162 static std::unique_ptr<MipsOperand>
1163 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1164 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1165 Op->RegIdx.Index = RegNo;
1171 bool isGPRAsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1174 bool isMM16AsmReg() const {
1175 if (!(isRegIdx() && RegIdx.Kind))
1177 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1178 || RegIdx.Index == 16 || RegIdx.Index == 17);
1180 bool isMM16AsmRegZero() const {
1181 if (!(isRegIdx() && RegIdx.Kind))
1183 return (RegIdx.Index == 0 ||
1184 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1185 RegIdx.Index == 17);
1187 bool isMM16AsmRegMoveP() const {
1188 if (!(isRegIdx() && RegIdx.Kind))
1190 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1191 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1193 bool isFGRAsmReg() const {
1194 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1195 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1197 bool isHWRegsAsmReg() const {
1198 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1200 bool isCCRAsmReg() const {
1201 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1203 bool isFCCAsmReg() const {
1204 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1206 if (!AsmParser.hasEightFccRegisters())
1207 return RegIdx.Index == 0;
1208 return RegIdx.Index <= 7;
1210 bool isACCAsmReg() const {
1211 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1213 bool isCOP0AsmReg() const {
1214 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1216 bool isCOP2AsmReg() const {
1217 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1219 bool isCOP3AsmReg() const {
1220 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1222 bool isMSA128AsmReg() const {
1223 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1225 bool isMSACtrlAsmReg() const {
1226 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1229 /// getStartLoc - Get the location of the first token of this operand.
1230 SMLoc getStartLoc() const override { return StartLoc; }
1231 /// getEndLoc - Get the location of the last token of this operand.
1232 SMLoc getEndLoc() const override { return EndLoc; }
1234 virtual ~MipsOperand() {
1242 delete RegList.List;
1243 case k_PhysRegister:
1244 case k_RegisterIndex:
1251 void print(raw_ostream &OS) const override {
1260 Mem.Base->print(OS);
1265 case k_PhysRegister:
1266 OS << "PhysReg<" << PhysReg.Num << ">";
1268 case k_RegisterIndex:
1269 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1276 for (auto Reg : (*RegList.List))
1281 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1285 }; // class MipsOperand
1289 extern const MCInstrDesc MipsInsts[];
1291 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1292 return MipsInsts[Opcode];
1295 static bool hasShortDelaySlot(unsigned Opcode) {
1298 case Mips::JALRS_MM:
1299 case Mips::JALRS16_MM:
1300 case Mips::BGEZALS_MM:
1301 case Mips::BLTZALS_MM:
1308 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1309 SmallVectorImpl<MCInst> &Instructions) {
1310 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1314 if (MCID.isBranch() || MCID.isCall()) {
1315 const unsigned Opcode = Inst.getOpcode();
1325 assert(hasCnMips() && "instruction only valid for octeon cpus");
1332 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1333 Offset = Inst.getOperand(2);
1334 if (!Offset.isImm())
1335 break; // We'll deal with this situation later on when applying fixups.
1336 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1337 return Error(IDLoc, "branch target out of range");
1338 if (OffsetToAlignment(Offset.getImm(),
1339 1LL << (inMicroMipsMode() ? 1 : 2)))
1340 return Error(IDLoc, "branch to misaligned address");
1354 case Mips::BGEZAL_MM:
1355 case Mips::BLTZAL_MM:
1358 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1359 Offset = Inst.getOperand(1);
1360 if (!Offset.isImm())
1361 break; // We'll deal with this situation later on when applying fixups.
1362 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1363 return Error(IDLoc, "branch target out of range");
1364 if (OffsetToAlignment(Offset.getImm(),
1365 1LL << (inMicroMipsMode() ? 1 : 2)))
1366 return Error(IDLoc, "branch to misaligned address");
1368 case Mips::BEQZ16_MM:
1369 case Mips::BNEZ16_MM:
1370 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1371 Offset = Inst.getOperand(1);
1372 if (!Offset.isImm())
1373 break; // We'll deal with this situation later on when applying fixups.
1374 if (!isIntN(8, Offset.getImm()))
1375 return Error(IDLoc, "branch target out of range");
1376 if (OffsetToAlignment(Offset.getImm(), 2LL))
1377 return Error(IDLoc, "branch to misaligned address");
1382 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1383 // We still accept it but it is a normal nop.
1384 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1385 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1386 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1391 const unsigned Opcode = Inst.getOpcode();
1403 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1404 // The offset is handled above
1405 Opnd = Inst.getOperand(1);
1407 return Error(IDLoc, "expected immediate operand kind");
1408 Imm = Opnd.getImm();
1409 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1410 Opcode == Mips::BBIT1 ? 63 : 31))
1411 return Error(IDLoc, "immediate operand value out of range");
1413 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1415 Inst.getOperand(1).setImm(Imm - 32);
1423 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1425 Opnd = Inst.getOperand(3);
1427 return Error(IDLoc, "expected immediate operand kind");
1428 Imm = Opnd.getImm();
1429 if (Imm < 0 || Imm > 31)
1430 return Error(IDLoc, "immediate operand value out of range");
1432 Opnd = Inst.getOperand(2);
1434 return Error(IDLoc, "expected immediate operand kind");
1435 Imm = Opnd.getImm();
1436 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1437 Opcode == Mips::EXTS ? 63 : 31))
1438 return Error(IDLoc, "immediate operand value out of range");
1440 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1441 Inst.getOperand(2).setImm(Imm - 32);
1447 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1448 Opnd = Inst.getOperand(2);
1450 return Error(IDLoc, "expected immediate operand kind");
1451 Imm = Opnd.getImm();
1452 if (!isInt<10>(Imm))
1453 return Error(IDLoc, "immediate operand value out of range");
1458 if (MCID.mayLoad() || MCID.mayStore()) {
1459 // Check the offset of memory operand, if it is a symbol
1460 // reference or immediate we may have to expand instructions.
1461 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1462 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1463 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1464 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1465 MCOperand &Op = Inst.getOperand(i);
1467 int MemOffset = Op.getImm();
1468 if (MemOffset < -32768 || MemOffset > 32767) {
1469 // Offset can't exceed 16bit value.
1470 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1473 } else if (Op.isExpr()) {
1474 const MCExpr *Expr = Op.getExpr();
1475 if (Expr->getKind() == MCExpr::SymbolRef) {
1476 const MCSymbolRefExpr *SR =
1477 static_cast<const MCSymbolRefExpr *>(Expr);
1478 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1480 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1483 } else if (!isEvaluated(Expr)) {
1484 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1492 if (inMicroMipsMode()) {
1493 if (MCID.mayLoad()) {
1494 // Try to create 16-bit GP relative load instruction.
1495 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1496 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1497 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1498 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1499 MCOperand &Op = Inst.getOperand(i);
1501 int MemOffset = Op.getImm();
1502 MCOperand &DstReg = Inst.getOperand(0);
1503 MCOperand &BaseReg = Inst.getOperand(1);
1504 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1505 getContext().getRegisterInfo()->getRegClass(
1506 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1507 BaseReg.getReg() == Mips::GP) {
1509 TmpInst.setLoc(IDLoc);
1510 TmpInst.setOpcode(Mips::LWGP_MM);
1511 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1512 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1513 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1514 Instructions.push_back(TmpInst);
1522 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1527 switch (Inst.getOpcode()) {
1530 case Mips::ADDIUS5_MM:
1531 Opnd = Inst.getOperand(2);
1533 return Error(IDLoc, "expected immediate operand kind");
1534 Imm = Opnd.getImm();
1535 if (Imm < -8 || Imm > 7)
1536 return Error(IDLoc, "immediate operand value out of range");
1538 case Mips::ADDIUSP_MM:
1539 Opnd = Inst.getOperand(0);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1545 return Error(IDLoc, "immediate operand value out of range");
1547 case Mips::SLL16_MM:
1548 case Mips::SRL16_MM:
1549 Opnd = Inst.getOperand(2);
1551 return Error(IDLoc, "expected immediate operand kind");
1552 Imm = Opnd.getImm();
1553 if (Imm < 1 || Imm > 8)
1554 return Error(IDLoc, "immediate operand value out of range");
1557 Opnd = Inst.getOperand(1);
1559 return Error(IDLoc, "expected immediate operand kind");
1560 Imm = Opnd.getImm();
1561 if (Imm < -1 || Imm > 126)
1562 return Error(IDLoc, "immediate operand value out of range");
1564 case Mips::ADDIUR2_MM:
1565 Opnd = Inst.getOperand(2);
1567 return Error(IDLoc, "expected immediate operand kind");
1568 Imm = Opnd.getImm();
1569 if (!(Imm == 1 || Imm == -1 ||
1570 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1571 return Error(IDLoc, "immediate operand value out of range");
1573 case Mips::ADDIUR1SP_MM:
1574 Opnd = Inst.getOperand(1);
1576 return Error(IDLoc, "expected immediate operand kind");
1577 Imm = Opnd.getImm();
1578 if (OffsetToAlignment(Imm, 4LL))
1579 return Error(IDLoc, "misaligned immediate operand value");
1580 if (Imm < 0 || Imm > 255)
1581 return Error(IDLoc, "immediate operand value out of range");
1583 case Mips::ANDI16_MM:
1584 Opnd = Inst.getOperand(2);
1586 return Error(IDLoc, "expected immediate operand kind");
1587 Imm = Opnd.getImm();
1588 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1589 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1590 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1591 return Error(IDLoc, "immediate operand value out of range");
1593 case Mips::LBU16_MM:
1594 Opnd = Inst.getOperand(2);
1596 return Error(IDLoc, "expected immediate operand kind");
1597 Imm = Opnd.getImm();
1598 if (Imm < -1 || Imm > 14)
1599 return Error(IDLoc, "immediate operand value out of range");
1602 Opnd = Inst.getOperand(2);
1604 return Error(IDLoc, "expected immediate operand kind");
1605 Imm = Opnd.getImm();
1606 if (Imm < 0 || Imm > 15)
1607 return Error(IDLoc, "immediate operand value out of range");
1609 case Mips::LHU16_MM:
1611 Opnd = Inst.getOperand(2);
1613 return Error(IDLoc, "expected immediate operand kind");
1614 Imm = Opnd.getImm();
1615 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1616 return Error(IDLoc, "immediate operand value out of range");
1620 Opnd = Inst.getOperand(2);
1622 return Error(IDLoc, "expected immediate operand kind");
1623 Imm = Opnd.getImm();
1624 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1625 return Error(IDLoc, "immediate operand value out of range");
1629 Opnd = Inst.getOperand(2);
1631 return Error(IDLoc, "expected immediate operand kind");
1632 Imm = Opnd.getImm();
1633 if (!isUInt<5>(Imm))
1634 return Error(IDLoc, "immediate operand value out of range");
1636 case Mips::ADDIUPC_MM:
1637 MCOperand Opnd = Inst.getOperand(1);
1639 return Error(IDLoc, "expected immediate operand kind");
1640 int Imm = Opnd.getImm();
1641 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1642 return Error(IDLoc, "immediate operand value out of range");
1647 if (needsExpansion(Inst)) {
1648 if (expandInstruction(Inst, IDLoc, Instructions))
1651 Instructions.push_back(Inst);
1653 // If this instruction has a delay slot and .set reorder is active,
1654 // emit a NOP after it.
1655 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1656 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1661 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1663 switch (Inst.getOpcode()) {
1664 case Mips::LoadImm32:
1665 case Mips::LoadImm64:
1666 case Mips::LoadAddrImm32:
1667 case Mips::LoadAddrImm64:
1668 case Mips::LoadAddrReg32:
1669 case Mips::LoadAddrReg64:
1670 case Mips::B_MM_Pseudo:
1673 case Mips::JalOneReg:
1674 case Mips::JalTwoReg:
1693 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1694 SmallVectorImpl<MCInst> &Instructions) {
1695 switch (Inst.getOpcode()) {
1696 default: llvm_unreachable("unimplemented expansion");
1697 case Mips::LoadImm32:
1698 return expandLoadImm(Inst, true, IDLoc, Instructions);
1699 case Mips::LoadImm64:
1700 return expandLoadImm(Inst, false, IDLoc, Instructions);
1701 case Mips::LoadAddrImm32:
1702 case Mips::LoadAddrImm64:
1703 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1704 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1705 "expected immediate operand kind");
1707 return expandLoadAddress(
1708 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1709 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1710 case Mips::LoadAddrReg32:
1711 case Mips::LoadAddrReg64:
1712 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1713 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1714 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1715 "expected immediate operand kind");
1717 return expandLoadAddress(
1718 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1719 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1720 case Mips::B_MM_Pseudo:
1721 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1724 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1725 case Mips::JalOneReg:
1726 case Mips::JalTwoReg:
1727 return expandJalWithRegs(Inst, IDLoc, Instructions);
1730 return expandBranchImm(Inst, IDLoc, Instructions);
1739 return expandCondBranches(Inst, IDLoc, Instructions);
1741 return expandUlhu(Inst, IDLoc, Instructions);
1743 return expandUlw(Inst, IDLoc, Instructions);
1748 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1749 SmallVectorImpl<MCInst> &Instructions) {
1751 tmpInst.setOpcode(Opcode);
1752 tmpInst.addOperand(MCOperand::createReg(Reg0));
1753 tmpInst.addOperand(Op1);
1754 tmpInst.setLoc(IDLoc);
1755 Instructions.push_back(tmpInst);
1758 void emitRI(unsigned Opcode, unsigned Reg0, int16_t Imm, SMLoc IDLoc,
1759 SmallVectorImpl<MCInst> &Instructions) {
1760 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1763 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1764 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1766 tmpInst.setOpcode(Opcode);
1767 tmpInst.addOperand(MCOperand::createReg(Reg0));
1768 tmpInst.addOperand(MCOperand::createReg(Reg1));
1769 tmpInst.addOperand(Op2);
1770 tmpInst.setLoc(IDLoc);
1771 Instructions.push_back(tmpInst);
1774 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1775 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1776 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1780 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1781 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1782 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1786 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1787 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1788 if (ShiftAmount >= 32) {
1789 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1794 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1796 } // end anonymous namespace.
1798 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1799 SmallVectorImpl<MCInst> &Instructions) {
1800 // Create a JALR instruction which is going to replace the pseudo-JAL.
1802 JalrInst.setLoc(IDLoc);
1803 const MCOperand FirstRegOp = Inst.getOperand(0);
1804 const unsigned Opcode = Inst.getOpcode();
1806 if (Opcode == Mips::JalOneReg) {
1807 // jal $rs => jalr $rs
1808 if (inMicroMipsMode()) {
1809 JalrInst.setOpcode(Mips::JALR16_MM);
1810 JalrInst.addOperand(FirstRegOp);
1812 JalrInst.setOpcode(Mips::JALR);
1813 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1814 JalrInst.addOperand(FirstRegOp);
1816 } else if (Opcode == Mips::JalTwoReg) {
1817 // jal $rd, $rs => jalr $rd, $rs
1818 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1819 JalrInst.addOperand(FirstRegOp);
1820 const MCOperand SecondRegOp = Inst.getOperand(1);
1821 JalrInst.addOperand(SecondRegOp);
1823 Instructions.push_back(JalrInst);
1825 // If .set reorder is active, emit a NOP after it.
1826 if (AssemblerOptions.back()->isReorder()) {
1827 // This is a 32-bit NOP because these 2 pseudo-instructions
1828 // do not have a short delay slot.
1830 NopInst.setOpcode(Mips::SLL);
1831 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1832 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1833 NopInst.addOperand(MCOperand::createImm(0));
1834 Instructions.push_back(NopInst);
1840 /// Can the value be represented by a unsigned N-bit value and a shift left?
1841 template<unsigned N>
1842 bool isShiftedUIntAtAnyPosition(uint64_t x) {
1843 unsigned BitNum = findFirstSet(x);
1845 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
1848 /// Load (or add) an immediate into a register.
1850 /// @param ImmValue The immediate to load.
1851 /// @param DstReg The register that will hold the immediate.
1852 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
1853 /// for a simple initialization.
1854 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
1855 /// @param IsAddress True if the immediate represents an address. False if it
1857 /// @param IDLoc Location of the immediate in the source file.
1858 /// @param Instructions The instructions emitted by this expansion.
1859 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1860 unsigned SrcReg, bool Is32BitImm,
1861 bool IsAddress, SMLoc IDLoc,
1862 SmallVectorImpl<MCInst> &Instructions) {
1863 if (!Is32BitImm && !isGP64bit()) {
1864 Error(IDLoc, "instruction requires a 64-bit architecture");
1869 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1870 // Sign extend up to 64-bit so that the predicates match the hardware
1871 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
1873 ImmValue = SignExtend64<32>(ImmValue);
1875 Error(IDLoc, "instruction requires a 32-bit immediate");
1880 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
1881 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
1883 bool UseSrcReg = false;
1884 if (SrcReg != Mips::NoRegister)
1887 unsigned TmpReg = DstReg;
1888 if (UseSrcReg && (DstReg == SrcReg)) {
1889 // At this point we need AT to perform the expansions and we exit if it is
1891 unsigned ATReg = getATReg(IDLoc);
1897 if (isInt<16>(ImmValue)) {
1901 // This doesn't quite follow the usual ABI expectations for N32 but matches
1902 // traditional assembler behaviour. N32 would normally use addiu for both
1903 // integers and addresses.
1904 if (IsAddress && !Is32BitImm) {
1905 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1909 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
1913 if (isUInt<16>(ImmValue)) {
1914 unsigned TmpReg = DstReg;
1915 if (SrcReg == DstReg) {
1916 TmpReg = getATReg(IDLoc);
1921 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
1923 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1927 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1928 warnIfNoMacro(IDLoc);
1930 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1931 uint16_t Bits15To0 = ImmValue & 0xffff;
1933 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1934 // Traditional behaviour seems to special case this particular value. It's
1935 // not clear why other masks are handled differently.
1936 if (ImmValue == 0xffffffff) {
1937 emitRI(Mips::LUi, TmpReg, -1, IDLoc, Instructions);
1938 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
1940 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1944 // Expand to an ORi instead of a LUi to avoid sign-extending into the
1946 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
1947 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
1949 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
1951 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1955 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
1957 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
1959 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1963 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
1965 Error(IDLoc, "instruction requires a 32-bit immediate");
1969 // Traditionally, these immediates are shifted as little as possible and as
1970 // such we align the most significant bit to bit 15 of our temporary.
1971 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
1972 unsigned LastSet = findLastSet((uint64_t)ImmValue);
1973 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
1974 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
1975 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
1976 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
1979 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
1984 warnIfNoMacro(IDLoc);
1986 // The remaining case is packed with a sequence of dsll and ori with zeros
1987 // being omitted and any neighbouring dsll's being coalesced.
1988 // The highest 32-bit's are equivalent to a 32-bit immediate load.
1990 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
1991 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
1992 IDLoc, Instructions))
1995 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
1996 // skip it and defer the shift to the next chunk.
1997 unsigned ShiftCarriedForwards = 16;
1998 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
1999 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2001 if (ImmChunk != 0) {
2002 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2004 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2005 ShiftCarriedForwards = 0;
2008 ShiftCarriedForwards += 16;
2010 ShiftCarriedForwards -= 16;
2012 // Finish any remaining shifts left by trailing zeros.
2013 if (ShiftCarriedForwards)
2014 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2018 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2023 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2024 SmallVectorImpl<MCInst> &Instructions) {
2025 const MCOperand &ImmOp = Inst.getOperand(1);
2026 assert(ImmOp.isImm() && "expected immediate operand kind");
2027 const MCOperand &DstRegOp = Inst.getOperand(0);
2028 assert(DstRegOp.isReg() && "expected register operand kind");
2030 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2031 Is32BitImm, false, IDLoc, Instructions))
2037 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2038 const MCOperand &Offset,
2039 bool Is32BitAddress, SMLoc IDLoc,
2040 SmallVectorImpl<MCInst> &Instructions) {
2041 // la can't produce a usable address when addresses are 64-bit.
2042 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2043 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2044 // We currently can't do this because we depend on the equality
2045 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2046 Error(IDLoc, "la used to load 64-bit address");
2047 // Continue as if we had 'dla' instead.
2048 Is32BitAddress = false;
2051 // dla requires 64-bit addresses.
2052 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2053 Error(IDLoc, "instruction requires a 64-bit architecture");
2057 if (!Offset.isImm())
2058 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2059 Is32BitAddress, IDLoc, Instructions);
2061 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2062 IDLoc, Instructions);
2065 bool MipsAsmParser::loadAndAddSymbolAddress(
2066 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2067 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2068 warnIfNoMacro(IDLoc);
2070 // FIXME: The way we're handling symbols right now prevents simple expressions
2071 // like foo+8. We'll be able to fix this once our unary operators (%hi
2072 // and similar) are treated as operators rather than as fixup types.
2073 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2074 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2075 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2076 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2077 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2079 bool UseSrcReg = SrcReg != Mips::NoRegister;
2081 // This is the 64-bit symbol address expansion.
2082 if (ABI.ArePtrs64bit() && isGP64bit()) {
2083 // We always need AT for the 64-bit expansion.
2084 // If it is not available we exit.
2085 unsigned ATReg = getATReg(IDLoc);
2089 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2090 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2091 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2092 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2094 if (UseSrcReg && (DstReg == SrcReg)) {
2095 // If $rs is the same as $rd:
2096 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2097 // daddiu $at, $at, %higher(sym)
2098 // dsll $at, $at, 16
2099 // daddiu $at, $at, %hi(sym)
2100 // dsll $at, $at, 16
2101 // daddiu $at, $at, %lo(sym)
2102 // daddu $rd, $at, $rd
2103 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2105 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2106 IDLoc, Instructions);
2107 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2108 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2110 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2111 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2113 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2118 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2119 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2120 // lui $at, %hi(sym)
2121 // daddiu $rd, $rd, %higher(sym)
2122 // daddiu $at, $at, %lo(sym)
2123 // dsll32 $rd, $rd, 0
2124 // daddu $rd, $rd, $at
2125 // (daddu $rd, $rd, $rs)
2126 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2128 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2130 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2131 IDLoc, Instructions);
2132 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2134 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2135 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2137 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2142 // And now, the 32-bit symbol address expansion:
2143 // If $rs is the same as $rd:
2144 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2145 // ori $at, $at, %lo(sym)
2146 // addu $rd, $at, $rd
2147 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2148 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2149 // ori $rd, $rd, %lo(sym)
2150 // (addu $rd, $rd, $rs)
2151 unsigned TmpReg = DstReg;
2152 if (UseSrcReg && (DstReg == SrcReg)) {
2153 // If $rs is the same as $rd, we need to use AT.
2154 // If it is not available we exit.
2155 unsigned ATReg = getATReg(IDLoc);
2161 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2162 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2166 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2168 assert(DstReg == TmpReg);
2173 bool MipsAsmParser::expandUncondBranchMMPseudo(
2174 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2175 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2176 "unexpected number of operands");
2178 MCOperand Offset = Inst.getOperand(0);
2179 if (Offset.isExpr()) {
2181 Inst.setOpcode(Mips::BEQ_MM);
2182 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2183 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2184 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2186 assert(Offset.isImm() && "expected immediate operand kind");
2187 if (isIntN(11, Offset.getImm())) {
2188 // If offset fits into 11 bits then this instruction becomes microMIPS
2189 // 16-bit unconditional branch instruction.
2190 Inst.setOpcode(Mips::B16_MM);
2192 if (!isIntN(17, Offset.getImm()))
2193 Error(IDLoc, "branch target out of range");
2194 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2195 Error(IDLoc, "branch to misaligned address");
2197 Inst.setOpcode(Mips::BEQ_MM);
2198 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2199 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2200 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2203 Instructions.push_back(Inst);
2205 // If .set reorder is active, emit a NOP after the branch instruction.
2206 if (AssemblerOptions.back()->isReorder())
2207 createNop(true, IDLoc, Instructions);
2212 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2213 SmallVectorImpl<MCInst> &Instructions) {
2214 const MCOperand &DstRegOp = Inst.getOperand(0);
2215 assert(DstRegOp.isReg() && "expected register operand kind");
2217 const MCOperand &ImmOp = Inst.getOperand(1);
2218 assert(ImmOp.isImm() && "expected immediate operand kind");
2220 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2221 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2223 unsigned OpCode = 0;
2224 switch(Inst.getOpcode()) {
2232 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2236 int64_t ImmValue = ImmOp.getImm();
2237 if (ImmValue == 0) {
2239 BranchInst.setOpcode(OpCode);
2240 BranchInst.addOperand(DstRegOp);
2241 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2242 BranchInst.addOperand(MemOffsetOp);
2243 Instructions.push_back(BranchInst);
2245 warnIfNoMacro(IDLoc);
2247 unsigned ATReg = getATReg(IDLoc);
2251 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2252 IDLoc, Instructions))
2256 BranchInst.setOpcode(OpCode);
2257 BranchInst.addOperand(DstRegOp);
2258 BranchInst.addOperand(MCOperand::createReg(ATReg));
2259 BranchInst.addOperand(MemOffsetOp);
2260 Instructions.push_back(BranchInst);
2265 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2266 SmallVectorImpl<MCInst> &Instructions,
2267 bool isLoad, bool isImmOpnd) {
2269 unsigned ImmOffset, HiOffset, LoOffset;
2270 const MCExpr *ExprOffset;
2272 // 1st operand is either the source or destination register.
2273 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2274 unsigned RegOpNum = Inst.getOperand(0).getReg();
2275 // 2nd operand is the base register.
2276 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2277 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2278 // 3rd operand is either an immediate or expression.
2280 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2281 ImmOffset = Inst.getOperand(2).getImm();
2282 LoOffset = ImmOffset & 0x0000ffff;
2283 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2284 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2285 if (LoOffset & 0x8000)
2288 ExprOffset = Inst.getOperand(2).getExpr();
2289 // All instructions will have the same location.
2290 TempInst.setLoc(IDLoc);
2291 // These are some of the types of expansions we perform here:
2292 // 1) lw $8, sym => lui $8, %hi(sym)
2293 // lw $8, %lo(sym)($8)
2294 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2296 // lw $8, %lo(offset)($9)
2297 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2299 // lw $8, %lo(offset)($at)
2300 // 4) sw $8, sym => lui $at, %hi(sym)
2301 // sw $8, %lo(sym)($at)
2302 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2304 // sw $8, %lo(offset)($at)
2305 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2306 // ldc1 $f0, %lo(sym)($at)
2308 // For load instructions we can use the destination register as a temporary
2309 // if base and dst are different (examples 1 and 2) and if the base register
2310 // is general purpose otherwise we must use $at (example 6) and error if it's
2311 // not available. For stores we must use $at (examples 4 and 5) because we
2312 // must not clobber the source register setting up the offset.
2313 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2314 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2315 unsigned RegClassIDOp0 =
2316 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2317 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2318 (RegClassIDOp0 == Mips::GPR64RegClassID);
2319 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2320 TmpRegNum = RegOpNum;
2322 // At this point we need AT to perform the expansions and we exit if it is
2324 TmpRegNum = getATReg(IDLoc);
2329 TempInst.setOpcode(Mips::LUi);
2330 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2332 TempInst.addOperand(MCOperand::createImm(HiOffset));
2334 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2335 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2337 // Add the instruction to the list.
2338 Instructions.push_back(TempInst);
2339 // Prepare TempInst for next instruction.
2341 // Add temp register to base.
2342 if (BaseRegNum != Mips::ZERO) {
2343 TempInst.setOpcode(Mips::ADDu);
2344 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2345 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2346 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2347 Instructions.push_back(TempInst);
2350 // And finally, create original instruction with low part
2351 // of offset and new base.
2352 TempInst.setOpcode(Inst.getOpcode());
2353 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2354 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2356 TempInst.addOperand(MCOperand::createImm(LoOffset));
2358 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2359 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2361 Instructions.push_back(TempInst);
2366 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2367 SmallVectorImpl<MCInst> &Instructions) {
2368 unsigned OpNum = Inst.getNumOperands();
2369 unsigned Opcode = Inst.getOpcode();
2370 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2372 assert (Inst.getOperand(OpNum - 1).isImm() &&
2373 Inst.getOperand(OpNum - 2).isReg() &&
2374 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2376 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2377 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2378 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2379 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2380 // It can be implemented as SWM16 or LWM16 instruction.
2381 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2383 Inst.setOpcode(NewOpcode);
2384 Instructions.push_back(Inst);
2388 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2389 SmallVectorImpl<MCInst> &Instructions) {
2390 unsigned PseudoOpcode = Inst.getOpcode();
2391 unsigned SrcReg = Inst.getOperand(0).getReg();
2392 unsigned TrgReg = Inst.getOperand(1).getReg();
2393 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2395 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2396 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2398 switch (PseudoOpcode) {
2401 AcceptsEquality = false;
2402 ReverseOrderSLT = false;
2403 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2404 ZeroSrcOpcode = Mips::BGTZ;
2405 ZeroTrgOpcode = Mips::BLTZ;
2409 AcceptsEquality = true;
2410 ReverseOrderSLT = true;
2411 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2412 ZeroSrcOpcode = Mips::BGEZ;
2413 ZeroTrgOpcode = Mips::BLEZ;
2417 AcceptsEquality = true;
2418 ReverseOrderSLT = false;
2419 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2420 ZeroSrcOpcode = Mips::BLEZ;
2421 ZeroTrgOpcode = Mips::BGEZ;
2425 AcceptsEquality = false;
2426 ReverseOrderSLT = true;
2427 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2428 ZeroSrcOpcode = Mips::BLTZ;
2429 ZeroTrgOpcode = Mips::BGTZ;
2432 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2436 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2437 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2438 if (IsSrcRegZero && IsTrgRegZero) {
2439 // FIXME: All of these Opcode-specific if's are needed for compatibility
2440 // with GAS' behaviour. However, they may not generate the most efficient
2441 // code in some circumstances.
2442 if (PseudoOpcode == Mips::BLT) {
2443 BranchInst.setOpcode(Mips::BLTZ);
2444 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2445 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2446 Instructions.push_back(BranchInst);
2449 if (PseudoOpcode == Mips::BLE) {
2450 BranchInst.setOpcode(Mips::BLEZ);
2451 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2452 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2453 Instructions.push_back(BranchInst);
2454 Warning(IDLoc, "branch is always taken");
2457 if (PseudoOpcode == Mips::BGE) {
2458 BranchInst.setOpcode(Mips::BGEZ);
2459 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2460 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2461 Instructions.push_back(BranchInst);
2462 Warning(IDLoc, "branch is always taken");
2465 if (PseudoOpcode == Mips::BGT) {
2466 BranchInst.setOpcode(Mips::BGTZ);
2467 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2468 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2469 Instructions.push_back(BranchInst);
2472 if (PseudoOpcode == Mips::BGTU) {
2473 BranchInst.setOpcode(Mips::BNE);
2474 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2475 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2476 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2477 Instructions.push_back(BranchInst);
2480 if (AcceptsEquality) {
2481 // If both registers are $0 and the pseudo-branch accepts equality, it
2482 // will always be taken, so we emit an unconditional branch.
2483 BranchInst.setOpcode(Mips::BEQ);
2484 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2485 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2486 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2487 Instructions.push_back(BranchInst);
2488 Warning(IDLoc, "branch is always taken");
2491 // If both registers are $0 and the pseudo-branch does not accept
2492 // equality, it will never be taken, so we don't have to emit anything.
2495 if (IsSrcRegZero || IsTrgRegZero) {
2496 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2497 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2498 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2499 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2500 // the pseudo-branch will never be taken, so we don't emit anything.
2501 // This only applies to unsigned pseudo-branches.
2504 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2505 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2506 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2507 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2508 // the pseudo-branch will always be taken, so we emit an unconditional
2510 // This only applies to unsigned pseudo-branches.
2511 BranchInst.setOpcode(Mips::BEQ);
2512 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2513 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2514 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2515 Instructions.push_back(BranchInst);
2516 Warning(IDLoc, "branch is always taken");
2520 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2521 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2522 // the pseudo-branch will be taken only when the non-zero register is
2523 // different from 0, so we emit a BNEZ.
2525 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2526 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2527 // the pseudo-branch will be taken only when the non-zero register is
2528 // equal to 0, so we emit a BEQZ.
2530 // Because only BLEU and BGEU branch on equality, we can use the
2531 // AcceptsEquality variable to decide when to emit the BEQZ.
2532 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2533 BranchInst.addOperand(
2534 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2535 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2536 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2537 Instructions.push_back(BranchInst);
2540 // If we have a signed pseudo-branch and one of the registers is $0,
2541 // we can use an appropriate compare-to-zero branch. We select which one
2542 // to use in the switch statement above.
2543 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2544 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2545 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2546 Instructions.push_back(BranchInst);
2550 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2551 // expansions. If it is not available, we return.
2552 unsigned ATRegNum = getATReg(IDLoc);
2556 warnIfNoMacro(IDLoc);
2558 // SLT fits well with 2 of our 4 pseudo-branches:
2559 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2560 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2561 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2562 // This is accomplished by using a BNEZ with the result of the SLT.
2564 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2565 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2566 // Because only BGE and BLE branch on equality, we can use the
2567 // AcceptsEquality variable to decide when to emit the BEQZ.
2568 // Note that the order of the SLT arguments doesn't change between
2571 // The same applies to the unsigned variants, except that SLTu is used
2574 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2575 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2576 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2577 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2578 Instructions.push_back(SetInst);
2580 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2581 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2582 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2583 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2584 Instructions.push_back(BranchInst);
2588 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2589 SmallVectorImpl<MCInst> &Instructions) {
2590 if (hasMips32r6() || hasMips64r6()) {
2591 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2595 warnIfNoMacro(IDLoc);
2597 const MCOperand &DstRegOp = Inst.getOperand(0);
2598 assert(DstRegOp.isReg() && "expected register operand kind");
2600 const MCOperand &SrcRegOp = Inst.getOperand(1);
2601 assert(SrcRegOp.isReg() && "expected register operand kind");
2603 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2604 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2606 unsigned DstReg = DstRegOp.getReg();
2607 unsigned SrcReg = SrcRegOp.getReg();
2608 int64_t OffsetValue = OffsetImmOp.getImm();
2610 // NOTE: We always need AT for ULHU, as it is always used as the source
2611 // register for one of the LBu's.
2612 unsigned ATReg = getATReg(IDLoc);
2616 // When the value of offset+1 does not fit in 16 bits, we have to load the
2617 // offset in AT, (D)ADDu the original source register (if there was one), and
2618 // then use AT as the source register for the 2 generated LBu's.
2619 bool LoadedOffsetInAT = false;
2620 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2621 LoadedOffsetInAT = true;
2623 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2624 true, IDLoc, Instructions))
2627 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2628 // because it will make our output more similar to GAS'. For example,
2629 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2630 // instead of just an "ori $1, $9, 32768".
2631 // NOTE: If there is no source register specified in the ULHU, the parser
2632 // will interpret it as $0.
2633 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2634 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2637 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2638 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2639 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2641 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2643 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2644 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2646 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2647 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2650 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2653 TmpInst.setOpcode(Mips::LBu);
2654 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2655 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2656 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2657 Instructions.push_back(TmpInst);
2660 TmpInst.setOpcode(Mips::LBu);
2661 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2662 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2663 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2664 Instructions.push_back(TmpInst);
2667 TmpInst.setOpcode(Mips::SLL);
2668 TmpInst.addOperand(MCOperand::createReg(SllReg));
2669 TmpInst.addOperand(MCOperand::createReg(SllReg));
2670 TmpInst.addOperand(MCOperand::createImm(8));
2671 Instructions.push_back(TmpInst);
2674 TmpInst.setOpcode(Mips::OR);
2675 TmpInst.addOperand(MCOperand::createReg(DstReg));
2676 TmpInst.addOperand(MCOperand::createReg(DstReg));
2677 TmpInst.addOperand(MCOperand::createReg(ATReg));
2678 Instructions.push_back(TmpInst);
2683 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2684 SmallVectorImpl<MCInst> &Instructions) {
2685 if (hasMips32r6() || hasMips64r6()) {
2686 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2690 const MCOperand &DstRegOp = Inst.getOperand(0);
2691 assert(DstRegOp.isReg() && "expected register operand kind");
2693 const MCOperand &SrcRegOp = Inst.getOperand(1);
2694 assert(SrcRegOp.isReg() && "expected register operand kind");
2696 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2697 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2699 unsigned SrcReg = SrcRegOp.getReg();
2700 int64_t OffsetValue = OffsetImmOp.getImm();
2703 // When the value of offset+3 does not fit in 16 bits, we have to load the
2704 // offset in AT, (D)ADDu the original source register (if there was one), and
2705 // then use AT as the source register for the generated LWL and LWR.
2706 bool LoadedOffsetInAT = false;
2707 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2708 ATReg = getATReg(IDLoc);
2711 LoadedOffsetInAT = true;
2713 warnIfNoMacro(IDLoc);
2715 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2716 true, IDLoc, Instructions))
2719 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2720 // because it will make our output more similar to GAS'. For example,
2721 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2722 // instead of just an "ori $1, $9, 32768".
2723 // NOTE: If there is no source register specified in the ULW, the parser
2724 // will interpret it as $0.
2725 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2726 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2729 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2730 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2732 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2733 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2735 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2736 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2739 MCInst LeftLoadInst;
2740 LeftLoadInst.setOpcode(Mips::LWL);
2741 LeftLoadInst.addOperand(DstRegOp);
2742 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2743 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2744 Instructions.push_back(LeftLoadInst);
2746 MCInst RightLoadInst;
2747 RightLoadInst.setOpcode(Mips::LWR);
2748 RightLoadInst.addOperand(DstRegOp);
2749 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2750 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2751 Instructions.push_back(RightLoadInst);
2756 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2757 SmallVectorImpl<MCInst> &Instructions) {
2759 if (hasShortDelaySlot) {
2760 NopInst.setOpcode(Mips::MOVE16_MM);
2761 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2762 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2764 NopInst.setOpcode(Mips::SLL);
2765 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2766 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2767 NopInst.addOperand(MCOperand::createImm(0));
2769 Instructions.push_back(NopInst);
2772 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2773 unsigned TrgReg, bool Is64Bit,
2774 SmallVectorImpl<MCInst> &Instructions) {
2775 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
2779 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2780 // As described by the Mips32r2 spec, the registers Rd and Rs for
2781 // jalr.hb must be different.
2782 unsigned Opcode = Inst.getOpcode();
2784 if (Opcode == Mips::JALR_HB &&
2785 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2786 return Match_RequiresDifferentSrcAndDst;
2788 return Match_Success;
2791 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2792 OperandVector &Operands,
2794 uint64_t &ErrorInfo,
2795 bool MatchingInlineAsm) {
2798 SmallVector<MCInst, 8> Instructions;
2799 unsigned MatchResult =
2800 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2802 switch (MatchResult) {
2803 case Match_Success: {
2804 if (processInstruction(Inst, IDLoc, Instructions))
2806 for (unsigned i = 0; i < Instructions.size(); i++)
2807 Out.EmitInstruction(Instructions[i], STI);
2810 case Match_MissingFeature:
2811 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2813 case Match_InvalidOperand: {
2814 SMLoc ErrorLoc = IDLoc;
2815 if (ErrorInfo != ~0ULL) {
2816 if (ErrorInfo >= Operands.size())
2817 return Error(IDLoc, "too few operands for instruction");
2819 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2820 if (ErrorLoc == SMLoc())
2824 return Error(ErrorLoc, "invalid operand for instruction");
2826 case Match_MnemonicFail:
2827 return Error(IDLoc, "invalid instruction");
2828 case Match_RequiresDifferentSrcAndDst:
2829 return Error(IDLoc, "source and destination must be different");
2832 llvm_unreachable("Implement any new match types added!");
2835 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2836 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2837 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2838 ") without \".set noat\"");
2841 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2842 if (!AssemblerOptions.back()->isMacro())
2843 Warning(Loc, "macro instruction expanded into multiple instructions");
2847 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2848 SMRange Range, bool ShowColors) {
2849 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2850 Range, SMFixIt(Range, FixMsg),
2854 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2857 CC = StringSwitch<unsigned>(Name)
2893 if (!(isABI_N32() || isABI_N64()))
2896 if (12 <= CC && CC <= 15) {
2897 // Name is one of t4-t7
2898 AsmToken RegTok = getLexer().peekTok();
2899 SMRange RegRange = RegTok.getLocRange();
2901 StringRef FixedName = StringSwitch<StringRef>(Name)
2907 assert(FixedName != "" && "Register name is not one of t4-t7.");
2909 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2910 "Did you mean $" + FixedName + "?", RegRange);
2913 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2914 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2915 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2916 if (8 <= CC && CC <= 11)
2920 CC = StringSwitch<unsigned>(Name)
2932 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2935 CC = StringSwitch<unsigned>(Name)
2936 .Case("hwr_cpunum", 0)
2937 .Case("hwr_synci_step", 1)
2939 .Case("hwr_ccres", 3)
2940 .Case("hwr_ulr", 29)
2946 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2948 if (Name[0] == 'f') {
2949 StringRef NumString = Name.substr(1);
2951 if (NumString.getAsInteger(10, IntVal))
2952 return -1; // This is not an integer.
2953 if (IntVal > 31) // Maximum index for fpu register.
2960 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2962 if (Name.startswith("fcc")) {
2963 StringRef NumString = Name.substr(3);
2965 if (NumString.getAsInteger(10, IntVal))
2966 return -1; // This is not an integer.
2967 if (IntVal > 7) // There are only 8 fcc registers.
2974 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2976 if (Name.startswith("ac")) {
2977 StringRef NumString = Name.substr(2);
2979 if (NumString.getAsInteger(10, IntVal))
2980 return -1; // This is not an integer.
2981 if (IntVal > 3) // There are only 3 acc registers.
2988 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2991 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3000 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3003 CC = StringSwitch<unsigned>(Name)
3006 .Case("msaaccess", 2)
3008 .Case("msamodify", 4)
3009 .Case("msarequest", 5)
3011 .Case("msaunmap", 7)
3017 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3018 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3020 reportParseError(Loc,
3021 "pseudo-instruction requires $at, which is not available");
3024 unsigned AT = getReg(
3025 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3029 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3030 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3033 unsigned MipsAsmParser::getGPR(int RegNo) {
3034 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3038 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3040 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3043 return getReg(RegClass, RegNum);
3046 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3047 MCAsmParser &Parser = getParser();
3048 DEBUG(dbgs() << "parseOperand\n");
3050 // Check if the current operand has a custom associated parser, if so, try to
3051 // custom parse the operand, or fallback to the general approach.
3052 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3053 if (ResTy == MatchOperand_Success)
3055 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3056 // there was a match, but an error occurred, in which case, just return that
3057 // the operand parsing failed.
3058 if (ResTy == MatchOperand_ParseFail)
3061 DEBUG(dbgs() << ".. Generic Parser\n");
3063 switch (getLexer().getKind()) {
3065 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3067 case AsmToken::Dollar: {
3068 // Parse the register.
3069 SMLoc S = Parser.getTok().getLoc();
3071 // Almost all registers have been parsed by custom parsers. There is only
3072 // one exception to this. $zero (and it's alias $0) will reach this point
3073 // for div, divu, and similar instructions because it is not an operand
3074 // to the instruction definition but an explicit register. Special case
3075 // this situation for now.
3076 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3079 // Maybe it is a symbol reference.
3080 StringRef Identifier;
3081 if (Parser.parseIdentifier(Identifier))
3084 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3085 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3086 // Otherwise create a symbol reference.
3088 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3090 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3093 // Else drop to expression parsing.
3094 case AsmToken::LParen:
3095 case AsmToken::Minus:
3096 case AsmToken::Plus:
3097 case AsmToken::Integer:
3098 case AsmToken::Tilde:
3099 case AsmToken::String: {
3100 DEBUG(dbgs() << ".. generic integer\n");
3101 OperandMatchResultTy ResTy = parseImm(Operands);
3102 return ResTy != MatchOperand_Success;
3104 case AsmToken::Percent: {
3105 // It is a symbol reference or constant expression.
3106 const MCExpr *IdVal;
3107 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3108 if (parseRelocOperand(IdVal))
3111 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3113 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3115 } // case AsmToken::Percent
3116 } // switch(getLexer().getKind())
3120 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3121 StringRef RelocStr) {
3123 // Check the type of the expression.
3124 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3125 // It's a constant, evaluate reloc value.
3127 switch (getVariantKind(RelocStr)) {
3128 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3129 // Get the 1st 16-bits.
3130 Val = MCE->getValue() & 0xffff;
3132 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3133 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3134 // 16 bits being negative.
3135 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3137 case MCSymbolRefExpr::VK_Mips_HIGHER:
3138 // Get the 3rd 16-bits.
3139 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3141 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3142 // Get the 4th 16-bits.
3143 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3146 report_fatal_error("unsupported reloc value");
3148 return MCConstantExpr::create(Val, getContext());
3151 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3152 // It's a symbol, create a symbolic expression from the symbol.
3153 const MCSymbol *Symbol = &MSRE->getSymbol();
3154 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3155 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3159 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3160 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3162 // Try to create target expression.
3163 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3164 return MipsMCExpr::create(VK, Expr, getContext());
3166 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3167 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3168 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3172 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3173 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3174 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3177 // Just return the original expression.
3181 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3183 switch (Expr->getKind()) {
3184 case MCExpr::Constant:
3186 case MCExpr::SymbolRef:
3187 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3188 case MCExpr::Binary:
3189 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3190 if (!isEvaluated(BE->getLHS()))
3192 return isEvaluated(BE->getRHS());
3195 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3196 case MCExpr::Target:
3202 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3203 MCAsmParser &Parser = getParser();
3204 Parser.Lex(); // Eat the % token.
3205 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3206 if (Tok.isNot(AsmToken::Identifier))
3209 std::string Str = Tok.getIdentifier();
3211 Parser.Lex(); // Eat the identifier.
3212 // Now make an expression from the rest of the operand.
3213 const MCExpr *IdVal;
3216 if (getLexer().getKind() == AsmToken::LParen) {
3218 Parser.Lex(); // Eat the '(' token.
3219 if (getLexer().getKind() == AsmToken::Percent) {
3220 Parser.Lex(); // Eat the % token.
3221 const AsmToken &nextTok = Parser.getTok();
3222 if (nextTok.isNot(AsmToken::Identifier))
3225 Str += nextTok.getIdentifier();
3226 Parser.Lex(); // Eat the identifier.
3227 if (getLexer().getKind() != AsmToken::LParen)
3232 if (getParser().parseParenExpression(IdVal, EndLoc))
3235 while (getLexer().getKind() == AsmToken::RParen)
3236 Parser.Lex(); // Eat the ')' token.
3239 return true; // Parenthesis must follow the relocation operand.
3241 Res = evaluateRelocExpr(IdVal, Str);
3245 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3247 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3248 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3249 if (ResTy == MatchOperand_Success) {
3250 assert(Operands.size() == 1);
3251 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3252 StartLoc = Operand.getStartLoc();
3253 EndLoc = Operand.getEndLoc();
3255 // AFAIK, we only support numeric registers and named GPR's in CFI
3257 // Don't worry about eating tokens before failing. Using an unrecognised
3258 // register is a parse error.
3259 if (Operand.isGPRAsmReg()) {
3260 // Resolve to GPR32 or GPR64 appropriately.
3261 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3264 return (RegNo == (unsigned)-1);
3267 assert(Operands.size() == 0);
3268 return (RegNo == (unsigned)-1);
3271 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3272 MCAsmParser &Parser = getParser();
3275 unsigned NumOfLParen = 0;
3277 while (getLexer().getKind() == AsmToken::LParen) {
3282 switch (getLexer().getKind()) {
3285 case AsmToken::Identifier:
3286 case AsmToken::LParen:
3287 case AsmToken::Integer:
3288 case AsmToken::Minus:
3289 case AsmToken::Plus:
3291 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3293 Result = (getParser().parseExpression(Res));
3294 while (getLexer().getKind() == AsmToken::RParen)
3297 case AsmToken::Percent:
3298 Result = parseRelocOperand(Res);
3303 MipsAsmParser::OperandMatchResultTy
3304 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3305 MCAsmParser &Parser = getParser();
3306 DEBUG(dbgs() << "parseMemOperand\n");
3307 const MCExpr *IdVal = nullptr;
3309 bool isParenExpr = false;
3310 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3311 // First operand is the offset.
3312 S = Parser.getTok().getLoc();
3314 if (getLexer().getKind() == AsmToken::LParen) {
3319 if (getLexer().getKind() != AsmToken::Dollar) {
3320 if (parseMemOffset(IdVal, isParenExpr))
3321 return MatchOperand_ParseFail;
3323 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3324 if (Tok.isNot(AsmToken::LParen)) {
3325 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3326 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3328 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3329 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3330 return MatchOperand_Success;
3332 if (Tok.is(AsmToken::EndOfStatement)) {
3334 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3336 // Zero register assumed, add a memory operand with ZERO as its base.
3337 // "Base" will be managed by k_Memory.
3338 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3341 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3342 return MatchOperand_Success;
3344 Error(Parser.getTok().getLoc(), "'(' expected");
3345 return MatchOperand_ParseFail;
3348 Parser.Lex(); // Eat the '(' token.
3351 Res = parseAnyRegister(Operands);
3352 if (Res != MatchOperand_Success)
3355 if (Parser.getTok().isNot(AsmToken::RParen)) {
3356 Error(Parser.getTok().getLoc(), "')' expected");
3357 return MatchOperand_ParseFail;
3360 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3362 Parser.Lex(); // Eat the ')' token.
3365 IdVal = MCConstantExpr::create(0, getContext());
3367 // Replace the register operand with the memory operand.
3368 std::unique_ptr<MipsOperand> op(
3369 static_cast<MipsOperand *>(Operands.back().release()));
3370 // Remove the register from the operands.
3371 // "op" will be managed by k_Memory.
3372 Operands.pop_back();
3373 // Add the memory operand.
3374 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3376 if (IdVal->evaluateAsAbsolute(Imm))
3377 IdVal = MCConstantExpr::create(Imm, getContext());
3378 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3379 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3383 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3384 return MatchOperand_Success;
3387 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3388 MCAsmParser &Parser = getParser();
3389 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3391 SMLoc S = Parser.getTok().getLoc();
3393 if (Sym->isVariable())
3394 Expr = Sym->getVariableValue();
3397 if (Expr->getKind() == MCExpr::SymbolRef) {
3398 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3399 StringRef DefSymbol = Ref->getSymbol().getName();
3400 if (DefSymbol.startswith("$")) {
3401 OperandMatchResultTy ResTy =
3402 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3403 if (ResTy == MatchOperand_Success) {
3406 } else if (ResTy == MatchOperand_ParseFail)
3407 llvm_unreachable("Should never ParseFail");
3410 } else if (Expr->getKind() == MCExpr::Constant) {
3412 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3414 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3421 MipsAsmParser::OperandMatchResultTy
3422 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3423 StringRef Identifier,
3425 int Index = matchCPURegisterName(Identifier);
3427 Operands.push_back(MipsOperand::createGPRReg(
3428 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3429 return MatchOperand_Success;
3432 Index = matchHWRegsRegisterName(Identifier);
3434 Operands.push_back(MipsOperand::createHWRegsReg(
3435 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3436 return MatchOperand_Success;
3439 Index = matchFPURegisterName(Identifier);
3441 Operands.push_back(MipsOperand::createFGRReg(
3442 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3443 return MatchOperand_Success;
3446 Index = matchFCCRegisterName(Identifier);
3448 Operands.push_back(MipsOperand::createFCCReg(
3449 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3450 return MatchOperand_Success;
3453 Index = matchACRegisterName(Identifier);
3455 Operands.push_back(MipsOperand::createACCReg(
3456 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3457 return MatchOperand_Success;
3460 Index = matchMSA128RegisterName(Identifier);
3462 Operands.push_back(MipsOperand::createMSA128Reg(
3463 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3464 return MatchOperand_Success;
3467 Index = matchMSA128CtrlRegisterName(Identifier);
3469 Operands.push_back(MipsOperand::createMSACtrlReg(
3470 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3471 return MatchOperand_Success;
3474 return MatchOperand_NoMatch;
3477 MipsAsmParser::OperandMatchResultTy
3478 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3479 MCAsmParser &Parser = getParser();
3480 auto Token = Parser.getLexer().peekTok(false);
3482 if (Token.is(AsmToken::Identifier)) {
3483 DEBUG(dbgs() << ".. identifier\n");
3484 StringRef Identifier = Token.getIdentifier();
3485 OperandMatchResultTy ResTy =
3486 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3488 } else if (Token.is(AsmToken::Integer)) {
3489 DEBUG(dbgs() << ".. integer\n");
3490 Operands.push_back(MipsOperand::createNumericReg(
3491 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3493 return MatchOperand_Success;
3496 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3498 return MatchOperand_NoMatch;
3501 MipsAsmParser::OperandMatchResultTy
3502 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3503 MCAsmParser &Parser = getParser();
3504 DEBUG(dbgs() << "parseAnyRegister\n");
3506 auto Token = Parser.getTok();
3508 SMLoc S = Token.getLoc();
3510 if (Token.isNot(AsmToken::Dollar)) {
3511 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3512 if (Token.is(AsmToken::Identifier)) {
3513 if (searchSymbolAlias(Operands))
3514 return MatchOperand_Success;
3516 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3517 return MatchOperand_NoMatch;
3519 DEBUG(dbgs() << ".. $\n");
3521 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3522 if (ResTy == MatchOperand_Success) {
3524 Parser.Lex(); // identifier
3529 MipsAsmParser::OperandMatchResultTy
3530 MipsAsmParser::parseImm(OperandVector &Operands) {
3531 MCAsmParser &Parser = getParser();
3532 switch (getLexer().getKind()) {
3534 return MatchOperand_NoMatch;
3535 case AsmToken::LParen:
3536 case AsmToken::Minus:
3537 case AsmToken::Plus:
3538 case AsmToken::Integer:
3539 case AsmToken::Tilde:
3540 case AsmToken::String:
3544 const MCExpr *IdVal;
3545 SMLoc S = Parser.getTok().getLoc();
3546 if (getParser().parseExpression(IdVal))
3547 return MatchOperand_ParseFail;
3549 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3550 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3551 return MatchOperand_Success;
3554 MipsAsmParser::OperandMatchResultTy
3555 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3556 MCAsmParser &Parser = getParser();
3557 DEBUG(dbgs() << "parseJumpTarget\n");
3559 SMLoc S = getLexer().getLoc();
3561 // Integers and expressions are acceptable
3562 OperandMatchResultTy ResTy = parseImm(Operands);
3563 if (ResTy != MatchOperand_NoMatch)
3566 // Registers are a valid target and have priority over symbols.
3567 ResTy = parseAnyRegister(Operands);
3568 if (ResTy != MatchOperand_NoMatch)
3571 const MCExpr *Expr = nullptr;
3572 if (Parser.parseExpression(Expr)) {
3573 // We have no way of knowing if a symbol was consumed so we must ParseFail
3574 return MatchOperand_ParseFail;
3577 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3578 return MatchOperand_Success;
3581 MipsAsmParser::OperandMatchResultTy
3582 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3583 MCAsmParser &Parser = getParser();
3584 const MCExpr *IdVal;
3585 // If the first token is '$' we may have register operand.
3586 if (Parser.getTok().is(AsmToken::Dollar))
3587 return MatchOperand_NoMatch;
3588 SMLoc S = Parser.getTok().getLoc();
3589 if (getParser().parseExpression(IdVal))
3590 return MatchOperand_ParseFail;
3591 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3592 assert(MCE && "Unexpected MCExpr type.");
3593 int64_t Val = MCE->getValue();
3594 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3595 Operands.push_back(MipsOperand::CreateImm(
3596 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3597 return MatchOperand_Success;
3600 MipsAsmParser::OperandMatchResultTy
3601 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3602 MCAsmParser &Parser = getParser();
3603 switch (getLexer().getKind()) {
3605 return MatchOperand_NoMatch;
3606 case AsmToken::LParen:
3607 case AsmToken::Plus:
3608 case AsmToken::Minus:
3609 case AsmToken::Integer:
3614 SMLoc S = Parser.getTok().getLoc();
3616 if (getParser().parseExpression(Expr))
3617 return MatchOperand_ParseFail;
3620 if (!Expr->evaluateAsAbsolute(Val)) {
3621 Error(S, "expected immediate value");
3622 return MatchOperand_ParseFail;
3625 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3626 // and because the CPU always adds one to the immediate field, the allowed
3627 // range becomes 1..4. We'll only check the range here and will deal
3628 // with the addition/subtraction when actually decoding/encoding
3630 if (Val < 1 || Val > 4) {
3631 Error(S, "immediate not in range (1..4)");
3632 return MatchOperand_ParseFail;
3636 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3637 return MatchOperand_Success;
3640 MipsAsmParser::OperandMatchResultTy
3641 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3642 MCAsmParser &Parser = getParser();
3643 SmallVector<unsigned, 10> Regs;
3645 unsigned PrevReg = Mips::NoRegister;
3646 bool RegRange = false;
3647 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3649 if (Parser.getTok().isNot(AsmToken::Dollar))
3650 return MatchOperand_ParseFail;
3652 SMLoc S = Parser.getTok().getLoc();
3653 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3654 SMLoc E = getLexer().getLoc();
3655 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3656 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3658 // Remove last register operand because registers from register range
3659 // should be inserted first.
3660 if (RegNo == Mips::RA) {
3661 Regs.push_back(RegNo);
3663 unsigned TmpReg = PrevReg + 1;
3664 while (TmpReg <= RegNo) {
3665 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3666 Error(E, "invalid register operand");
3667 return MatchOperand_ParseFail;
3671 Regs.push_back(TmpReg++);
3677 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3678 (RegNo != Mips::RA)) {
3679 Error(E, "$16 or $31 expected");
3680 return MatchOperand_ParseFail;
3681 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3682 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3683 Error(E, "invalid register operand");
3684 return MatchOperand_ParseFail;
3685 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3686 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3687 Error(E, "consecutive register numbers expected");
3688 return MatchOperand_ParseFail;
3691 Regs.push_back(RegNo);
3694 if (Parser.getTok().is(AsmToken::Minus))
3697 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3698 !Parser.getTok().isNot(AsmToken::Comma)) {
3699 Error(E, "',' or '-' expected");
3700 return MatchOperand_ParseFail;
3703 Lex(); // Consume comma or minus
3704 if (Parser.getTok().isNot(AsmToken::Dollar))
3710 SMLoc E = Parser.getTok().getLoc();
3711 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3712 parseMemOperand(Operands);
3713 return MatchOperand_Success;
3716 MipsAsmParser::OperandMatchResultTy
3717 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3718 MCAsmParser &Parser = getParser();
3720 SMLoc S = Parser.getTok().getLoc();
3721 if (parseAnyRegister(Operands) != MatchOperand_Success)
3722 return MatchOperand_ParseFail;
3724 SMLoc E = Parser.getTok().getLoc();
3725 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3726 unsigned Reg = Op.getGPR32Reg();
3727 Operands.pop_back();
3728 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3729 return MatchOperand_Success;
3732 MipsAsmParser::OperandMatchResultTy
3733 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3734 MCAsmParser &Parser = getParser();
3735 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3736 SmallVector<unsigned, 10> Regs;
3738 if (Parser.getTok().isNot(AsmToken::Dollar))
3739 return MatchOperand_ParseFail;
3741 SMLoc S = Parser.getTok().getLoc();
3743 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3744 return MatchOperand_ParseFail;
3746 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3747 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3748 Regs.push_back(RegNo);
3750 SMLoc E = Parser.getTok().getLoc();
3751 if (Parser.getTok().isNot(AsmToken::Comma)) {
3752 Error(E, "',' expected");
3753 return MatchOperand_ParseFail;
3759 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3760 return MatchOperand_ParseFail;
3762 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3763 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3764 Regs.push_back(RegNo);
3766 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3768 return MatchOperand_Success;
3771 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3773 MCSymbolRefExpr::VariantKind VK =
3774 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3775 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3776 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3777 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3778 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3779 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3780 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3781 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3782 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3783 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3784 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3785 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3786 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3787 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3788 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3789 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3790 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3791 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3792 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3793 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3794 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3795 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3796 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3797 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3798 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3799 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3800 .Default(MCSymbolRefExpr::VK_None);
3802 assert(VK != MCSymbolRefExpr::VK_None);
3807 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3809 /// ::= '(', register, ')'
3810 /// handle it before we iterate so we don't get tripped up by the lack of
3812 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3813 MCAsmParser &Parser = getParser();
3814 if (getLexer().is(AsmToken::LParen)) {
3816 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3818 if (parseOperand(Operands, Name)) {
3819 SMLoc Loc = getLexer().getLoc();
3820 Parser.eatToEndOfStatement();
3821 return Error(Loc, "unexpected token in argument list");
3823 if (Parser.getTok().isNot(AsmToken::RParen)) {
3824 SMLoc Loc = getLexer().getLoc();
3825 Parser.eatToEndOfStatement();
3826 return Error(Loc, "unexpected token, expected ')'");
3829 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3835 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3836 /// either one of these.
3837 /// ::= '[', register, ']'
3838 /// ::= '[', integer, ']'
3839 /// handle it before we iterate so we don't get tripped up by the lack of
3841 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3842 OperandVector &Operands) {
3843 MCAsmParser &Parser = getParser();
3844 if (getLexer().is(AsmToken::LBrac)) {
3846 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3848 if (parseOperand(Operands, Name)) {
3849 SMLoc Loc = getLexer().getLoc();
3850 Parser.eatToEndOfStatement();
3851 return Error(Loc, "unexpected token in argument list");
3853 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3854 SMLoc Loc = getLexer().getLoc();
3855 Parser.eatToEndOfStatement();
3856 return Error(Loc, "unexpected token, expected ']'");
3859 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3865 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3866 SMLoc NameLoc, OperandVector &Operands) {
3867 MCAsmParser &Parser = getParser();
3868 DEBUG(dbgs() << "ParseInstruction\n");
3870 // We have reached first instruction, module directive are now forbidden.
3871 getTargetStreamer().forbidModuleDirective();
3873 // Check if we have valid mnemonic
3874 if (!mnemonicIsValid(Name, 0)) {
3875 Parser.eatToEndOfStatement();
3876 return Error(NameLoc, "unknown instruction");
3878 // First operand in MCInst is instruction mnemonic.
3879 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3881 // Read the remaining operands.
3882 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3883 // Read the first operand.
3884 if (parseOperand(Operands, Name)) {
3885 SMLoc Loc = getLexer().getLoc();
3886 Parser.eatToEndOfStatement();
3887 return Error(Loc, "unexpected token in argument list");
3889 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3891 // AFAIK, parenthesis suffixes are never on the first operand
3893 while (getLexer().is(AsmToken::Comma)) {
3894 Parser.Lex(); // Eat the comma.
3895 // Parse and remember the operand.
3896 if (parseOperand(Operands, Name)) {
3897 SMLoc Loc = getLexer().getLoc();
3898 Parser.eatToEndOfStatement();
3899 return Error(Loc, "unexpected token in argument list");
3901 // Parse bracket and parenthesis suffixes before we iterate
3902 if (getLexer().is(AsmToken::LBrac)) {
3903 if (parseBracketSuffix(Name, Operands))
3905 } else if (getLexer().is(AsmToken::LParen) &&
3906 parseParenSuffix(Name, Operands))
3910 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3911 SMLoc Loc = getLexer().getLoc();
3912 Parser.eatToEndOfStatement();
3913 return Error(Loc, "unexpected token in argument list");
3915 Parser.Lex(); // Consume the EndOfStatement.
3919 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3920 MCAsmParser &Parser = getParser();
3921 SMLoc Loc = getLexer().getLoc();
3922 Parser.eatToEndOfStatement();
3923 return Error(Loc, ErrorMsg);
3926 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3927 return Error(Loc, ErrorMsg);
3930 bool MipsAsmParser::parseSetNoAtDirective() {
3931 MCAsmParser &Parser = getParser();
3932 // Line should look like: ".set noat".
3934 // Set the $at register to $0.
3935 AssemblerOptions.back()->setATRegIndex(0);
3937 Parser.Lex(); // Eat "noat".
3939 // If this is not the end of the statement, report an error.
3940 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3941 reportParseError("unexpected token, expected end of statement");
3945 getTargetStreamer().emitDirectiveSetNoAt();
3946 Parser.Lex(); // Consume the EndOfStatement.
3950 bool MipsAsmParser::parseSetAtDirective() {
3951 // Line can be: ".set at", which sets $at to $1
3952 // or ".set at=$reg", which sets $at to $reg.
3953 MCAsmParser &Parser = getParser();
3954 Parser.Lex(); // Eat "at".
3956 if (getLexer().is(AsmToken::EndOfStatement)) {
3957 // No register was specified, so we set $at to $1.
3958 AssemblerOptions.back()->setATRegIndex(1);
3960 getTargetStreamer().emitDirectiveSetAt();
3961 Parser.Lex(); // Consume the EndOfStatement.
3965 if (getLexer().isNot(AsmToken::Equal)) {
3966 reportParseError("unexpected token, expected equals sign");
3969 Parser.Lex(); // Eat "=".
3971 if (getLexer().isNot(AsmToken::Dollar)) {
3972 if (getLexer().is(AsmToken::EndOfStatement)) {
3973 reportParseError("no register specified");
3976 reportParseError("unexpected token, expected dollar sign '$'");
3980 Parser.Lex(); // Eat "$".
3982 // Find out what "reg" is.
3984 const AsmToken &Reg = Parser.getTok();
3985 if (Reg.is(AsmToken::Identifier)) {
3986 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3987 } else if (Reg.is(AsmToken::Integer)) {
3988 AtRegNo = Reg.getIntVal();
3990 reportParseError("unexpected token, expected identifier or integer");
3994 // Check if $reg is a valid register. If it is, set $at to $reg.
3995 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3996 reportParseError("invalid register");
3999 Parser.Lex(); // Eat "reg".
4001 // If this is not the end of the statement, report an error.
4002 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4003 reportParseError("unexpected token, expected end of statement");
4007 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4009 Parser.Lex(); // Consume the EndOfStatement.
4013 bool MipsAsmParser::parseSetReorderDirective() {
4014 MCAsmParser &Parser = getParser();
4016 // If this is not the end of the statement, report an error.
4017 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4018 reportParseError("unexpected token, expected end of statement");
4021 AssemblerOptions.back()->setReorder();
4022 getTargetStreamer().emitDirectiveSetReorder();
4023 Parser.Lex(); // Consume the EndOfStatement.
4027 bool MipsAsmParser::parseSetNoReorderDirective() {
4028 MCAsmParser &Parser = getParser();
4030 // If this is not the end of the statement, report an error.
4031 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4032 reportParseError("unexpected token, expected end of statement");
4035 AssemblerOptions.back()->setNoReorder();
4036 getTargetStreamer().emitDirectiveSetNoReorder();
4037 Parser.Lex(); // Consume the EndOfStatement.
4041 bool MipsAsmParser::parseSetMacroDirective() {
4042 MCAsmParser &Parser = getParser();
4044 // If this is not the end of the statement, report an error.
4045 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4046 reportParseError("unexpected token, expected end of statement");
4049 AssemblerOptions.back()->setMacro();
4050 getTargetStreamer().emitDirectiveSetMacro();
4051 Parser.Lex(); // Consume the EndOfStatement.
4055 bool MipsAsmParser::parseSetNoMacroDirective() {
4056 MCAsmParser &Parser = getParser();
4058 // If this is not the end of the statement, report an error.
4059 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4060 reportParseError("unexpected token, expected end of statement");
4063 if (AssemblerOptions.back()->isReorder()) {
4064 reportParseError("`noreorder' must be set before `nomacro'");
4067 AssemblerOptions.back()->setNoMacro();
4068 getTargetStreamer().emitDirectiveSetNoMacro();
4069 Parser.Lex(); // Consume the EndOfStatement.
4073 bool MipsAsmParser::parseSetMsaDirective() {
4074 MCAsmParser &Parser = getParser();
4077 // If this is not the end of the statement, report an error.
4078 if (getLexer().isNot(AsmToken::EndOfStatement))
4079 return reportParseError("unexpected token, expected end of statement");
4081 setFeatureBits(Mips::FeatureMSA, "msa");
4082 getTargetStreamer().emitDirectiveSetMsa();
4086 bool MipsAsmParser::parseSetNoMsaDirective() {
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 clearFeatureBits(Mips::FeatureMSA, "msa");
4095 getTargetStreamer().emitDirectiveSetNoMsa();
4099 bool MipsAsmParser::parseSetNoDspDirective() {
4100 MCAsmParser &Parser = getParser();
4101 Parser.Lex(); // Eat "nodsp".
4103 // If this is not the end of the statement, report an error.
4104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4105 reportParseError("unexpected token, expected end of statement");
4109 clearFeatureBits(Mips::FeatureDSP, "dsp");
4110 getTargetStreamer().emitDirectiveSetNoDsp();
4114 bool MipsAsmParser::parseSetMips16Directive() {
4115 MCAsmParser &Parser = getParser();
4116 Parser.Lex(); // Eat "mips16".
4118 // If this is not the end of the statement, report an error.
4119 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4120 reportParseError("unexpected token, expected end of statement");
4124 setFeatureBits(Mips::FeatureMips16, "mips16");
4125 getTargetStreamer().emitDirectiveSetMips16();
4126 Parser.Lex(); // Consume the EndOfStatement.
4130 bool MipsAsmParser::parseSetNoMips16Directive() {
4131 MCAsmParser &Parser = getParser();
4132 Parser.Lex(); // Eat "nomips16".
4134 // If this is not the end of the statement, report an error.
4135 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4136 reportParseError("unexpected token, expected end of statement");
4140 clearFeatureBits(Mips::FeatureMips16, "mips16");
4141 getTargetStreamer().emitDirectiveSetNoMips16();
4142 Parser.Lex(); // Consume the EndOfStatement.
4146 bool MipsAsmParser::parseSetFpDirective() {
4147 MCAsmParser &Parser = getParser();
4148 MipsABIFlagsSection::FpABIKind FpAbiVal;
4149 // Line can be: .set fp=32
4152 Parser.Lex(); // Eat fp token
4153 AsmToken Tok = Parser.getTok();
4154 if (Tok.isNot(AsmToken::Equal)) {
4155 reportParseError("unexpected token, expected equals sign '='");
4158 Parser.Lex(); // Eat '=' token.
4159 Tok = Parser.getTok();
4161 if (!parseFpABIValue(FpAbiVal, ".set"))
4164 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4165 reportParseError("unexpected token, expected end of statement");
4168 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4169 Parser.Lex(); // Consume the EndOfStatement.
4173 bool MipsAsmParser::parseSetOddSPRegDirective() {
4174 MCAsmParser &Parser = getParser();
4176 Parser.Lex(); // Eat "oddspreg".
4177 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4178 reportParseError("unexpected token, expected end of statement");
4182 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4183 getTargetStreamer().emitDirectiveSetOddSPReg();
4187 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4188 MCAsmParser &Parser = getParser();
4190 Parser.Lex(); // Eat "nooddspreg".
4191 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4192 reportParseError("unexpected token, expected end of statement");
4196 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4197 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4201 bool MipsAsmParser::parseSetPopDirective() {
4202 MCAsmParser &Parser = getParser();
4203 SMLoc Loc = getLexer().getLoc();
4206 if (getLexer().isNot(AsmToken::EndOfStatement))
4207 return reportParseError("unexpected token, expected end of statement");
4209 // Always keep an element on the options "stack" to prevent the user
4210 // from changing the initial options. This is how we remember them.
4211 if (AssemblerOptions.size() == 2)
4212 return reportParseError(Loc, ".set pop with no .set push");
4214 AssemblerOptions.pop_back();
4215 setAvailableFeatures(
4216 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4217 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4219 getTargetStreamer().emitDirectiveSetPop();
4223 bool MipsAsmParser::parseSetPushDirective() {
4224 MCAsmParser &Parser = getParser();
4226 if (getLexer().isNot(AsmToken::EndOfStatement))
4227 return reportParseError("unexpected token, expected end of statement");
4229 // Create a copy of the current assembler options environment and push it.
4230 AssemblerOptions.push_back(
4231 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4233 getTargetStreamer().emitDirectiveSetPush();
4237 bool MipsAsmParser::parseSetSoftFloatDirective() {
4238 MCAsmParser &Parser = getParser();
4240 if (getLexer().isNot(AsmToken::EndOfStatement))
4241 return reportParseError("unexpected token, expected end of statement");
4243 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4244 getTargetStreamer().emitDirectiveSetSoftFloat();
4248 bool MipsAsmParser::parseSetHardFloatDirective() {
4249 MCAsmParser &Parser = getParser();
4251 if (getLexer().isNot(AsmToken::EndOfStatement))
4252 return reportParseError("unexpected token, expected end of statement");
4254 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4255 getTargetStreamer().emitDirectiveSetHardFloat();
4259 bool MipsAsmParser::parseSetAssignment() {
4261 const MCExpr *Value;
4262 MCAsmParser &Parser = getParser();
4264 if (Parser.parseIdentifier(Name))
4265 reportParseError("expected identifier after .set");
4267 if (getLexer().isNot(AsmToken::Comma))
4268 return reportParseError("unexpected token, expected comma");
4271 if (Parser.parseExpression(Value))
4272 return reportParseError("expected valid expression after comma");
4274 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4275 Sym->setVariableValue(Value);
4280 bool MipsAsmParser::parseSetMips0Directive() {
4281 MCAsmParser &Parser = getParser();
4283 if (getLexer().isNot(AsmToken::EndOfStatement))
4284 return reportParseError("unexpected token, expected end of statement");
4286 // Reset assembler options to their initial values.
4287 setAvailableFeatures(
4288 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4289 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4290 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4292 getTargetStreamer().emitDirectiveSetMips0();
4296 bool MipsAsmParser::parseSetArchDirective() {
4297 MCAsmParser &Parser = getParser();
4299 if (getLexer().isNot(AsmToken::Equal))
4300 return reportParseError("unexpected token, expected equals sign");
4304 if (Parser.parseIdentifier(Arch))
4305 return reportParseError("expected arch identifier");
4307 StringRef ArchFeatureName =
4308 StringSwitch<StringRef>(Arch)
4309 .Case("mips1", "mips1")
4310 .Case("mips2", "mips2")
4311 .Case("mips3", "mips3")
4312 .Case("mips4", "mips4")
4313 .Case("mips5", "mips5")
4314 .Case("mips32", "mips32")
4315 .Case("mips32r2", "mips32r2")
4316 .Case("mips32r3", "mips32r3")
4317 .Case("mips32r5", "mips32r5")
4318 .Case("mips32r6", "mips32r6")
4319 .Case("mips64", "mips64")
4320 .Case("mips64r2", "mips64r2")
4321 .Case("mips64r3", "mips64r3")
4322 .Case("mips64r5", "mips64r5")
4323 .Case("mips64r6", "mips64r6")
4324 .Case("cnmips", "cnmips")
4325 .Case("r4000", "mips3") // This is an implementation of Mips3.
4328 if (ArchFeatureName.empty())
4329 return reportParseError("unsupported architecture");
4331 selectArch(ArchFeatureName);
4332 getTargetStreamer().emitDirectiveSetArch(Arch);
4336 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4337 MCAsmParser &Parser = getParser();
4339 if (getLexer().isNot(AsmToken::EndOfStatement))
4340 return reportParseError("unexpected token, expected end of statement");
4344 llvm_unreachable("Unimplemented feature");
4345 case Mips::FeatureDSP:
4346 setFeatureBits(Mips::FeatureDSP, "dsp");
4347 getTargetStreamer().emitDirectiveSetDsp();
4349 case Mips::FeatureMicroMips:
4350 getTargetStreamer().emitDirectiveSetMicroMips();
4352 case Mips::FeatureMips1:
4353 selectArch("mips1");
4354 getTargetStreamer().emitDirectiveSetMips1();
4356 case Mips::FeatureMips2:
4357 selectArch("mips2");
4358 getTargetStreamer().emitDirectiveSetMips2();
4360 case Mips::FeatureMips3:
4361 selectArch("mips3");
4362 getTargetStreamer().emitDirectiveSetMips3();
4364 case Mips::FeatureMips4:
4365 selectArch("mips4");
4366 getTargetStreamer().emitDirectiveSetMips4();
4368 case Mips::FeatureMips5:
4369 selectArch("mips5");
4370 getTargetStreamer().emitDirectiveSetMips5();
4372 case Mips::FeatureMips32:
4373 selectArch("mips32");
4374 getTargetStreamer().emitDirectiveSetMips32();
4376 case Mips::FeatureMips32r2:
4377 selectArch("mips32r2");
4378 getTargetStreamer().emitDirectiveSetMips32R2();
4380 case Mips::FeatureMips32r3:
4381 selectArch("mips32r3");
4382 getTargetStreamer().emitDirectiveSetMips32R3();
4384 case Mips::FeatureMips32r5:
4385 selectArch("mips32r5");
4386 getTargetStreamer().emitDirectiveSetMips32R5();
4388 case Mips::FeatureMips32r6:
4389 selectArch("mips32r6");
4390 getTargetStreamer().emitDirectiveSetMips32R6();
4392 case Mips::FeatureMips64:
4393 selectArch("mips64");
4394 getTargetStreamer().emitDirectiveSetMips64();
4396 case Mips::FeatureMips64r2:
4397 selectArch("mips64r2");
4398 getTargetStreamer().emitDirectiveSetMips64R2();
4400 case Mips::FeatureMips64r3:
4401 selectArch("mips64r3");
4402 getTargetStreamer().emitDirectiveSetMips64R3();
4404 case Mips::FeatureMips64r5:
4405 selectArch("mips64r5");
4406 getTargetStreamer().emitDirectiveSetMips64R5();
4408 case Mips::FeatureMips64r6:
4409 selectArch("mips64r6");
4410 getTargetStreamer().emitDirectiveSetMips64R6();
4416 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4417 MCAsmParser &Parser = getParser();
4418 if (getLexer().isNot(AsmToken::Comma)) {
4419 SMLoc Loc = getLexer().getLoc();
4420 Parser.eatToEndOfStatement();
4421 return Error(Loc, ErrorStr);
4424 Parser.Lex(); // Eat the comma.
4428 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4429 if (AssemblerOptions.back()->isReorder())
4430 Warning(Loc, ".cpload should be inside a noreorder section");
4432 if (inMips16Mode()) {
4433 reportParseError(".cpload is not supported in Mips16 mode");
4437 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4438 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4439 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4440 reportParseError("expected register containing function address");
4444 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4445 if (!RegOpnd.isGPRAsmReg()) {
4446 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4450 // If this is not the end of the statement, report an error.
4451 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4452 reportParseError("unexpected token, expected end of statement");
4456 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4460 bool MipsAsmParser::parseDirectiveCPSetup() {
4461 MCAsmParser &Parser = getParser();
4464 bool SaveIsReg = true;
4466 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4467 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4468 if (ResTy == MatchOperand_NoMatch) {
4469 reportParseError("expected register containing function address");
4470 Parser.eatToEndOfStatement();
4474 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4475 if (!FuncRegOpnd.isGPRAsmReg()) {
4476 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4477 Parser.eatToEndOfStatement();
4481 FuncReg = FuncRegOpnd.getGPR32Reg();
4484 if (!eatComma("unexpected token, expected comma"))
4487 ResTy = parseAnyRegister(TmpReg);
4488 if (ResTy == MatchOperand_NoMatch) {
4489 const AsmToken &Tok = Parser.getTok();
4490 if (Tok.is(AsmToken::Integer)) {
4491 Save = Tok.getIntVal();
4495 reportParseError("expected save register or stack offset");
4496 Parser.eatToEndOfStatement();
4500 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4501 if (!SaveOpnd.isGPRAsmReg()) {
4502 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4503 Parser.eatToEndOfStatement();
4506 Save = SaveOpnd.getGPR32Reg();
4509 if (!eatComma("unexpected token, expected comma"))
4513 if (Parser.parseExpression(Expr)) {
4514 reportParseError("expected expression");
4518 if (Expr->getKind() != MCExpr::SymbolRef) {
4519 reportParseError("expected symbol");
4522 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4524 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4529 bool MipsAsmParser::parseDirectiveNaN() {
4530 MCAsmParser &Parser = getParser();
4531 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4532 const AsmToken &Tok = Parser.getTok();
4534 if (Tok.getString() == "2008") {
4536 getTargetStreamer().emitDirectiveNaN2008();
4538 } else if (Tok.getString() == "legacy") {
4540 getTargetStreamer().emitDirectiveNaNLegacy();
4544 // If we don't recognize the option passed to the .nan
4545 // directive (e.g. no option or unknown option), emit an error.
4546 reportParseError("invalid option in .nan directive");
4550 bool MipsAsmParser::parseDirectiveSet() {
4551 MCAsmParser &Parser = getParser();
4552 // Get the next token.
4553 const AsmToken &Tok = Parser.getTok();
4555 if (Tok.getString() == "noat") {
4556 return parseSetNoAtDirective();
4557 } else if (Tok.getString() == "at") {
4558 return parseSetAtDirective();
4559 } else if (Tok.getString() == "arch") {
4560 return parseSetArchDirective();
4561 } else if (Tok.getString() == "fp") {
4562 return parseSetFpDirective();
4563 } else if (Tok.getString() == "oddspreg") {
4564 return parseSetOddSPRegDirective();
4565 } else if (Tok.getString() == "nooddspreg") {
4566 return parseSetNoOddSPRegDirective();
4567 } else if (Tok.getString() == "pop") {
4568 return parseSetPopDirective();
4569 } else if (Tok.getString() == "push") {
4570 return parseSetPushDirective();
4571 } else if (Tok.getString() == "reorder") {
4572 return parseSetReorderDirective();
4573 } else if (Tok.getString() == "noreorder") {
4574 return parseSetNoReorderDirective();
4575 } else if (Tok.getString() == "macro") {
4576 return parseSetMacroDirective();
4577 } else if (Tok.getString() == "nomacro") {
4578 return parseSetNoMacroDirective();
4579 } else if (Tok.getString() == "mips16") {
4580 return parseSetMips16Directive();
4581 } else if (Tok.getString() == "nomips16") {
4582 return parseSetNoMips16Directive();
4583 } else if (Tok.getString() == "nomicromips") {
4584 getTargetStreamer().emitDirectiveSetNoMicroMips();
4585 Parser.eatToEndOfStatement();
4587 } else if (Tok.getString() == "micromips") {
4588 return parseSetFeature(Mips::FeatureMicroMips);
4589 } else if (Tok.getString() == "mips0") {
4590 return parseSetMips0Directive();
4591 } else if (Tok.getString() == "mips1") {
4592 return parseSetFeature(Mips::FeatureMips1);
4593 } else if (Tok.getString() == "mips2") {
4594 return parseSetFeature(Mips::FeatureMips2);
4595 } else if (Tok.getString() == "mips3") {
4596 return parseSetFeature(Mips::FeatureMips3);
4597 } else if (Tok.getString() == "mips4") {
4598 return parseSetFeature(Mips::FeatureMips4);
4599 } else if (Tok.getString() == "mips5") {
4600 return parseSetFeature(Mips::FeatureMips5);
4601 } else if (Tok.getString() == "mips32") {
4602 return parseSetFeature(Mips::FeatureMips32);
4603 } else if (Tok.getString() == "mips32r2") {
4604 return parseSetFeature(Mips::FeatureMips32r2);
4605 } else if (Tok.getString() == "mips32r3") {
4606 return parseSetFeature(Mips::FeatureMips32r3);
4607 } else if (Tok.getString() == "mips32r5") {
4608 return parseSetFeature(Mips::FeatureMips32r5);
4609 } else if (Tok.getString() == "mips32r6") {
4610 return parseSetFeature(Mips::FeatureMips32r6);
4611 } else if (Tok.getString() == "mips64") {
4612 return parseSetFeature(Mips::FeatureMips64);
4613 } else if (Tok.getString() == "mips64r2") {
4614 return parseSetFeature(Mips::FeatureMips64r2);
4615 } else if (Tok.getString() == "mips64r3") {
4616 return parseSetFeature(Mips::FeatureMips64r3);
4617 } else if (Tok.getString() == "mips64r5") {
4618 return parseSetFeature(Mips::FeatureMips64r5);
4619 } else if (Tok.getString() == "mips64r6") {
4620 return parseSetFeature(Mips::FeatureMips64r6);
4621 } else if (Tok.getString() == "dsp") {
4622 return parseSetFeature(Mips::FeatureDSP);
4623 } else if (Tok.getString() == "nodsp") {
4624 return parseSetNoDspDirective();
4625 } else if (Tok.getString() == "msa") {
4626 return parseSetMsaDirective();
4627 } else if (Tok.getString() == "nomsa") {
4628 return parseSetNoMsaDirective();
4629 } else if (Tok.getString() == "softfloat") {
4630 return parseSetSoftFloatDirective();
4631 } else if (Tok.getString() == "hardfloat") {
4632 return parseSetHardFloatDirective();
4634 // It is just an identifier, look for an assignment.
4635 parseSetAssignment();
4642 /// parseDataDirective
4643 /// ::= .word [ expression (, expression)* ]
4644 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4645 MCAsmParser &Parser = getParser();
4646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4648 const MCExpr *Value;
4649 if (getParser().parseExpression(Value))
4652 getParser().getStreamer().EmitValue(Value, Size);
4654 if (getLexer().is(AsmToken::EndOfStatement))
4657 if (getLexer().isNot(AsmToken::Comma))
4658 return Error(L, "unexpected token, expected comma");
4667 /// parseDirectiveGpWord
4668 /// ::= .gpword local_sym
4669 bool MipsAsmParser::parseDirectiveGpWord() {
4670 MCAsmParser &Parser = getParser();
4671 const MCExpr *Value;
4672 // EmitGPRel32Value requires an expression, so we are using base class
4673 // method to evaluate the expression.
4674 if (getParser().parseExpression(Value))
4676 getParser().getStreamer().EmitGPRel32Value(Value);
4678 if (getLexer().isNot(AsmToken::EndOfStatement))
4679 return Error(getLexer().getLoc(),
4680 "unexpected token, expected end of statement");
4681 Parser.Lex(); // Eat EndOfStatement token.
4685 /// parseDirectiveGpDWord
4686 /// ::= .gpdword local_sym
4687 bool MipsAsmParser::parseDirectiveGpDWord() {
4688 MCAsmParser &Parser = getParser();
4689 const MCExpr *Value;
4690 // EmitGPRel64Value requires an expression, so we are using base class
4691 // method to evaluate the expression.
4692 if (getParser().parseExpression(Value))
4694 getParser().getStreamer().EmitGPRel64Value(Value);
4696 if (getLexer().isNot(AsmToken::EndOfStatement))
4697 return Error(getLexer().getLoc(),
4698 "unexpected token, expected end of statement");
4699 Parser.Lex(); // Eat EndOfStatement token.
4703 bool MipsAsmParser::parseDirectiveOption() {
4704 MCAsmParser &Parser = getParser();
4705 // Get the option token.
4706 AsmToken Tok = Parser.getTok();
4707 // At the moment only identifiers are supported.
4708 if (Tok.isNot(AsmToken::Identifier)) {
4709 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4710 Parser.eatToEndOfStatement();
4714 StringRef Option = Tok.getIdentifier();
4716 if (Option == "pic0") {
4717 getTargetStreamer().emitDirectiveOptionPic0();
4719 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4720 Error(Parser.getTok().getLoc(),
4721 "unexpected token, expected end of statement");
4722 Parser.eatToEndOfStatement();
4727 if (Option == "pic2") {
4728 getTargetStreamer().emitDirectiveOptionPic2();
4730 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4731 Error(Parser.getTok().getLoc(),
4732 "unexpected token, expected end of statement");
4733 Parser.eatToEndOfStatement();
4739 Warning(Parser.getTok().getLoc(),
4740 "unknown option, expected 'pic0' or 'pic2'");
4741 Parser.eatToEndOfStatement();
4745 /// parseInsnDirective
4747 bool MipsAsmParser::parseInsnDirective() {
4748 // If this is not the end of the statement, report an error.
4749 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4750 reportParseError("unexpected token, expected end of statement");
4754 // The actual label marking happens in
4755 // MipsELFStreamer::createPendingLabelRelocs().
4756 getTargetStreamer().emitDirectiveInsn();
4758 getParser().Lex(); // Eat EndOfStatement token.
4762 /// parseDirectiveModule
4763 /// ::= .module oddspreg
4764 /// ::= .module nooddspreg
4765 /// ::= .module fp=value
4766 /// ::= .module softfloat
4767 /// ::= .module hardfloat
4768 bool MipsAsmParser::parseDirectiveModule() {
4769 MCAsmParser &Parser = getParser();
4770 MCAsmLexer &Lexer = getLexer();
4771 SMLoc L = Lexer.getLoc();
4773 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4774 // TODO : get a better message.
4775 reportParseError(".module directive must appear before any code");
4780 if (Parser.parseIdentifier(Option)) {
4781 reportParseError("expected .module option identifier");
4785 if (Option == "oddspreg") {
4786 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4788 // Synchronize the abiflags information with the FeatureBits information we
4790 getTargetStreamer().updateABIInfo(*this);
4792 // If printing assembly, use the recently updated abiflags information.
4793 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4794 // emitted at the end).
4795 getTargetStreamer().emitDirectiveModuleOddSPReg();
4797 // If this is not the end of the statement, report an error.
4798 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4799 reportParseError("unexpected token, expected end of statement");
4803 return false; // parseDirectiveModule has finished successfully.
4804 } else if (Option == "nooddspreg") {
4806 Error(L, "'.module nooddspreg' requires the O32 ABI");
4810 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4812 // Synchronize the abiflags information with the FeatureBits information we
4814 getTargetStreamer().updateABIInfo(*this);
4816 // If printing assembly, use the recently updated abiflags information.
4817 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4818 // emitted at the end).
4819 getTargetStreamer().emitDirectiveModuleOddSPReg();
4821 // If this is not the end of the statement, report an error.
4822 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4823 reportParseError("unexpected token, expected end of statement");
4827 return false; // parseDirectiveModule has finished successfully.
4828 } else if (Option == "fp") {
4829 return parseDirectiveModuleFP();
4830 } else if (Option == "softfloat") {
4831 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4833 // Synchronize the ABI Flags information with the FeatureBits information we
4835 getTargetStreamer().updateABIInfo(*this);
4837 // If printing assembly, use the recently updated ABI Flags information.
4838 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4840 getTargetStreamer().emitDirectiveModuleSoftFloat();
4842 // If this is not the end of the statement, report an error.
4843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4844 reportParseError("unexpected token, expected end of statement");
4848 return false; // parseDirectiveModule has finished successfully.
4849 } else if (Option == "hardfloat") {
4850 clearModuleFeatureBits(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().emitDirectiveModuleHardFloat();
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.
4869 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4873 /// parseDirectiveModuleFP
4877 bool MipsAsmParser::parseDirectiveModuleFP() {
4878 MCAsmParser &Parser = getParser();
4879 MCAsmLexer &Lexer = getLexer();
4881 if (Lexer.isNot(AsmToken::Equal)) {
4882 reportParseError("unexpected token, expected equals sign '='");
4885 Parser.Lex(); // Eat '=' token.
4887 MipsABIFlagsSection::FpABIKind FpABI;
4888 if (!parseFpABIValue(FpABI, ".module"))
4891 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4892 reportParseError("unexpected token, expected end of statement");
4896 // Synchronize the abiflags information with the FeatureBits information we
4898 getTargetStreamer().updateABIInfo(*this);
4900 // If printing assembly, use the recently updated abiflags information.
4901 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4902 // emitted at the end).
4903 getTargetStreamer().emitDirectiveModuleFP();
4905 Parser.Lex(); // Consume the EndOfStatement.
4909 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4910 StringRef Directive) {
4911 MCAsmParser &Parser = getParser();
4912 MCAsmLexer &Lexer = getLexer();
4913 bool ModuleLevelOptions = Directive == ".module";
4915 if (Lexer.is(AsmToken::Identifier)) {
4916 StringRef Value = Parser.getTok().getString();
4919 if (Value != "xx") {
4920 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4925 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4929 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4930 if (ModuleLevelOptions) {
4931 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4932 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4934 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4935 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4940 if (Lexer.is(AsmToken::Integer)) {
4941 unsigned Value = Parser.getTok().getIntVal();
4944 if (Value != 32 && Value != 64) {
4945 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4951 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4955 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4956 if (ModuleLevelOptions) {
4957 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4958 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4960 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4961 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4964 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4965 if (ModuleLevelOptions) {
4966 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
4967 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
4969 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4970 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4980 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4981 MCAsmParser &Parser = getParser();
4982 StringRef IDVal = DirectiveID.getString();
4984 if (IDVal == ".cpload")
4985 return parseDirectiveCpLoad(DirectiveID.getLoc());
4986 if (IDVal == ".dword") {
4987 parseDataDirective(8, DirectiveID.getLoc());
4990 if (IDVal == ".ent") {
4991 StringRef SymbolName;
4993 if (Parser.parseIdentifier(SymbolName)) {
4994 reportParseError("expected identifier after .ent");
4998 // There's an undocumented extension that allows an integer to
4999 // follow the name of the procedure which AFAICS is ignored by GAS.
5000 // Example: .ent foo,2
5001 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5002 if (getLexer().isNot(AsmToken::Comma)) {
5003 // Even though we accept this undocumented extension for compatibility
5004 // reasons, the additional integer argument does not actually change
5005 // the behaviour of the '.ent' directive, so we would like to discourage
5006 // its use. We do this by not referring to the extended version in
5007 // error messages which are not directly related to its use.
5008 reportParseError("unexpected token, expected end of statement");
5011 Parser.Lex(); // Eat the comma.
5012 const MCExpr *DummyNumber;
5013 int64_t DummyNumberVal;
5014 // If the user was explicitly trying to use the extended version,
5015 // we still give helpful extension-related error messages.
5016 if (Parser.parseExpression(DummyNumber)) {
5017 reportParseError("expected number after comma");
5020 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5021 reportParseError("expected an absolute expression after comma");
5026 // If this is not the end of the statement, report an error.
5027 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5028 reportParseError("unexpected token, expected end of statement");
5032 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5034 getTargetStreamer().emitDirectiveEnt(*Sym);
5039 if (IDVal == ".end") {
5040 StringRef SymbolName;
5042 if (Parser.parseIdentifier(SymbolName)) {
5043 reportParseError("expected identifier after .end");
5047 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5048 reportParseError("unexpected token, expected end of statement");
5052 if (CurrentFn == nullptr) {
5053 reportParseError(".end used without .ent");
5057 if ((SymbolName != CurrentFn->getName())) {
5058 reportParseError(".end symbol does not match .ent symbol");
5062 getTargetStreamer().emitDirectiveEnd(SymbolName);
5063 CurrentFn = nullptr;
5067 if (IDVal == ".frame") {
5068 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5069 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5070 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5071 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5072 reportParseError("expected stack register");
5076 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5077 if (!StackRegOpnd.isGPRAsmReg()) {
5078 reportParseError(StackRegOpnd.getStartLoc(),
5079 "expected general purpose register");
5082 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5084 if (Parser.getTok().is(AsmToken::Comma))
5087 reportParseError("unexpected token, expected comma");
5091 // Parse the frame size.
5092 const MCExpr *FrameSize;
5093 int64_t FrameSizeVal;
5095 if (Parser.parseExpression(FrameSize)) {
5096 reportParseError("expected frame size value");
5100 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5101 reportParseError("frame size not an absolute expression");
5105 if (Parser.getTok().is(AsmToken::Comma))
5108 reportParseError("unexpected token, expected comma");
5112 // Parse the return register.
5114 ResTy = parseAnyRegister(TmpReg);
5115 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5116 reportParseError("expected return register");
5120 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5121 if (!ReturnRegOpnd.isGPRAsmReg()) {
5122 reportParseError(ReturnRegOpnd.getStartLoc(),
5123 "expected general purpose register");
5127 // If this is not the end of the statement, report an error.
5128 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5129 reportParseError("unexpected token, expected end of statement");
5133 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5134 ReturnRegOpnd.getGPR32Reg());
5138 if (IDVal == ".set") {
5139 return parseDirectiveSet();
5142 if (IDVal == ".mask" || IDVal == ".fmask") {
5143 // .mask bitmask, frame_offset
5144 // bitmask: One bit for each register used.
5145 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5146 // first register is expected to be saved.
5148 // .mask 0x80000000, -4
5149 // .fmask 0x80000000, -4
5152 // Parse the bitmask
5153 const MCExpr *BitMask;
5156 if (Parser.parseExpression(BitMask)) {
5157 reportParseError("expected bitmask value");
5161 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5162 reportParseError("bitmask not an absolute expression");
5166 if (Parser.getTok().is(AsmToken::Comma))
5169 reportParseError("unexpected token, expected comma");
5173 // Parse the frame_offset
5174 const MCExpr *FrameOffset;
5175 int64_t FrameOffsetVal;
5177 if (Parser.parseExpression(FrameOffset)) {
5178 reportParseError("expected frame offset value");
5182 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5183 reportParseError("frame offset not an absolute expression");
5187 // If this is not the end of the statement, report an error.
5188 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5189 reportParseError("unexpected token, expected end of statement");
5193 if (IDVal == ".mask")
5194 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5196 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5200 if (IDVal == ".nan")
5201 return parseDirectiveNaN();
5203 if (IDVal == ".gpword") {
5204 parseDirectiveGpWord();
5208 if (IDVal == ".gpdword") {
5209 parseDirectiveGpDWord();
5213 if (IDVal == ".word") {
5214 parseDataDirective(4, DirectiveID.getLoc());
5218 if (IDVal == ".option")
5219 return parseDirectiveOption();
5221 if (IDVal == ".abicalls") {
5222 getTargetStreamer().emitDirectiveAbiCalls();
5223 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5224 Error(Parser.getTok().getLoc(),
5225 "unexpected token, expected end of statement");
5227 Parser.eatToEndOfStatement();
5232 if (IDVal == ".cpsetup")
5233 return parseDirectiveCPSetup();
5235 if (IDVal == ".module")
5236 return parseDirectiveModule();
5238 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5239 return parseInternalDirectiveReallowModule();
5241 if (IDVal == ".insn")
5242 return parseInsnDirective();
5247 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5248 // If this is not the end of the statement, report an error.
5249 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5250 reportParseError("unexpected token, expected end of statement");
5254 getTargetStreamer().reallowModuleDirective();
5256 getParser().Lex(); // Eat EndOfStatement token.
5260 extern "C" void LLVMInitializeMipsAsmParser() {
5261 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5262 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5263 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5264 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5267 #define GET_REGISTER_MATCHER
5268 #define GET_MATCHER_IMPLEMENTATION
5269 #include "MipsGenAsmMatcher.inc"