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, 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 expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 bool expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
202 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
203 SmallVectorImpl<MCInst> &Instructions);
205 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
206 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
209 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
210 SmallVectorImpl<MCInst> &Instructions);
212 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
213 SmallVectorImpl<MCInst> &Instructions);
215 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
225 SmallVectorImpl<MCInst> &Instructions);
227 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
228 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
230 bool reportParseError(Twine ErrorMsg);
231 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
233 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
234 bool parseRelocOperand(const MCExpr *&Res);
236 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
238 bool isEvaluated(const MCExpr *Expr);
239 bool parseSetMips0Directive();
240 bool parseSetArchDirective();
241 bool parseSetFeature(uint64_t Feature);
242 bool parseDirectiveCpLoad(SMLoc Loc);
243 bool parseDirectiveCPSetup();
244 bool parseDirectiveNaN();
245 bool parseDirectiveSet();
246 bool parseDirectiveOption();
247 bool parseInsnDirective();
249 bool parseSetAtDirective();
250 bool parseSetNoAtDirective();
251 bool parseSetMacroDirective();
252 bool parseSetNoMacroDirective();
253 bool parseSetMsaDirective();
254 bool parseSetNoMsaDirective();
255 bool parseSetNoDspDirective();
256 bool parseSetReorderDirective();
257 bool parseSetNoReorderDirective();
258 bool parseSetMips16Directive();
259 bool parseSetNoMips16Directive();
260 bool parseSetFpDirective();
261 bool parseSetPopDirective();
262 bool parseSetPushDirective();
263 bool parseSetSoftFloatDirective();
264 bool parseSetHardFloatDirective();
266 bool parseSetAssignment();
268 bool parseDataDirective(unsigned Size, SMLoc L);
269 bool parseDirectiveGpWord();
270 bool parseDirectiveGpDWord();
271 bool parseDirectiveModule();
272 bool parseDirectiveModuleFP();
273 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
274 StringRef Directive);
276 bool parseInternalDirectiveReallowModule();
278 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
280 bool eatComma(StringRef ErrorStr);
282 int matchCPURegisterName(StringRef Symbol);
284 int matchHWRegsRegisterName(StringRef Symbol);
286 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
288 int matchFPURegisterName(StringRef Name);
290 int matchFCCRegisterName(StringRef Name);
292 int matchACRegisterName(StringRef Name);
294 int matchMSA128RegisterName(StringRef Name);
296 int matchMSA128CtrlRegisterName(StringRef Name);
298 unsigned getReg(int RC, int RegNo);
300 unsigned getGPR(int RegNo);
302 /// Returns the internal register number for the current AT. Also checks if
303 /// the current AT is unavailable (set to $0) and gives an error if it is.
304 /// This should be used in pseudo-instruction expansions which need AT.
305 unsigned getATReg(SMLoc Loc);
307 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
308 SmallVectorImpl<MCInst> &Instructions);
310 // Helper function that checks if the value of a vector index is within the
311 // boundaries of accepted values for each RegisterKind
312 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
313 bool validateMSAIndex(int Val, int RegKind);
315 // Selects a new architecture by updating the FeatureBits with the necessary
316 // info including implied dependencies.
317 // Internally, it clears all the feature bits related to *any* architecture
318 // and selects the new one using the ToggleFeature functionality of the
319 // MCSubtargetInfo object that handles implied dependencies. The reason we
320 // clear all the arch related bits manually is because ToggleFeature only
321 // clears the features that imply the feature being cleared and not the
322 // features implied by the feature being cleared. This is easier to see
324 // --------------------------------------------------
325 // | Feature | Implies |
326 // | -------------------------------------------------|
327 // | FeatureMips1 | None |
328 // | FeatureMips2 | FeatureMips1 |
329 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
330 // | FeatureMips4 | FeatureMips3 |
332 // --------------------------------------------------
334 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
335 // FeatureMipsGP64 | FeatureMips1)
336 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
337 void selectArch(StringRef ArchFeature) {
338 FeatureBitset FeatureBits = STI.getFeatureBits();
339 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
340 STI.setFeatureBits(FeatureBits);
341 setAvailableFeatures(
342 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
343 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
346 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
347 if (!(STI.getFeatureBits()[Feature])) {
348 setAvailableFeatures(
349 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
350 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
354 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
355 if (STI.getFeatureBits()[Feature]) {
356 setAvailableFeatures(
357 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
358 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
363 enum MipsMatchResultTy {
364 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
365 #define GET_OPERAND_DIAGNOSTIC_TYPES
366 #include "MipsGenAsmMatcher.inc"
367 #undef GET_OPERAND_DIAGNOSTIC_TYPES
371 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
372 const MCInstrInfo &MII, const MCTargetOptions &Options)
373 : MCTargetAsmParser(), STI(sti),
374 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
375 sti.getCPU(), Options)) {
376 MCAsmParserExtension::Initialize(parser);
378 parser.addAliasForDirective(".asciiz", ".asciz");
380 // Initialize the set of available features.
381 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
383 // Remember the initial assembler options. The user can not modify these.
384 AssemblerOptions.push_back(
385 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
387 // Create an assembler options environment for the user to modify.
388 AssemblerOptions.push_back(
389 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
391 getTargetStreamer().updateABIInfo(*this);
393 if (!isABI_O32() && !useOddSPReg() != 0)
394 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
398 Triple TheTriple(sti.getTargetTriple());
399 if ((TheTriple.getArch() == Triple::mips) ||
400 (TheTriple.getArch() == Triple::mips64))
401 IsLittleEndian = false;
403 IsLittleEndian = true;
406 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
407 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
409 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
410 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
411 const MipsABIInfo &getABI() const { return ABI; }
412 bool isABI_N32() const { return ABI.IsN32(); }
413 bool isABI_N64() const { return ABI.IsN64(); }
414 bool isABI_O32() const { return ABI.IsO32(); }
415 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
417 bool useOddSPReg() const {
418 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
421 bool inMicroMipsMode() const {
422 return STI.getFeatureBits()[Mips::FeatureMicroMips];
424 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
425 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
426 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
427 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
428 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
429 bool hasMips32() const {
430 return STI.getFeatureBits()[Mips::FeatureMips32];
432 bool hasMips64() const {
433 return STI.getFeatureBits()[Mips::FeatureMips64];
435 bool hasMips32r2() const {
436 return STI.getFeatureBits()[Mips::FeatureMips32r2];
438 bool hasMips64r2() const {
439 return STI.getFeatureBits()[Mips::FeatureMips64r2];
441 bool hasMips32r3() const {
442 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
444 bool hasMips64r3() const {
445 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
447 bool hasMips32r5() const {
448 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
450 bool hasMips64r5() const {
451 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
453 bool hasMips32r6() const {
454 return STI.getFeatureBits()[Mips::FeatureMips32r6];
456 bool hasMips64r6() const {
457 return STI.getFeatureBits()[Mips::FeatureMips64r6];
460 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
461 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
462 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
463 bool hasCnMips() const {
464 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
467 bool inMips16Mode() const {
468 return STI.getFeatureBits()[Mips::FeatureMips16];
471 bool useSoftFloat() const {
472 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
475 /// Warn if RegIndex is the same as the current AT.
476 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
478 void warnIfNoMacro(SMLoc Loc);
480 bool isLittle() const { return IsLittleEndian; }
486 /// MipsOperand - Instances of this class represent a parsed Mips machine
488 class MipsOperand : public MCParsedAsmOperand {
490 /// Broad categories of register classes
491 /// The exact class is finalized by the render method.
493 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
494 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
496 RegKind_FCC = 4, /// FCC
497 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
498 RegKind_MSACtrl = 16, /// MSA control registers
499 RegKind_COP2 = 32, /// COP2
500 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
502 RegKind_CCR = 128, /// CCR
503 RegKind_HWRegs = 256, /// HWRegs
504 RegKind_COP3 = 512, /// COP3
506 /// Potentially any (e.g. $1)
507 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
508 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
509 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
514 k_Immediate, /// An immediate (possibly involving symbol references)
515 k_Memory, /// Base + Offset Memory Address
516 k_PhysRegister, /// A physical register from the Mips namespace
517 k_RegisterIndex, /// A register index in one or more RegKind.
518 k_Token, /// A simple token
519 k_RegList, /// A physical register list
520 k_RegPair /// A pair of physical register
524 MipsOperand(KindTy K, MipsAsmParser &Parser)
525 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
528 /// For diagnostics, and checking the assembler temporary
529 MipsAsmParser &AsmParser;
537 unsigned Num; /// Register Number
541 unsigned Index; /// Index into the register class
542 RegKind Kind; /// Bitfield of the kinds it could possibly be
543 const MCRegisterInfo *RegInfo;
556 SmallVector<unsigned, 10> *List;
561 struct PhysRegOp PhysReg;
562 struct RegIdxOp RegIdx;
565 struct RegListOp RegList;
568 SMLoc StartLoc, EndLoc;
570 /// Internal constructor for register kinds
571 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
572 const MCRegisterInfo *RegInfo,
574 MipsAsmParser &Parser) {
575 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
576 Op->RegIdx.Index = Index;
577 Op->RegIdx.RegInfo = RegInfo;
578 Op->RegIdx.Kind = RegKind;
585 /// Coerce the register to GPR32 and return the real register for the current
587 unsigned getGPR32Reg() const {
588 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
589 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
590 unsigned ClassID = Mips::GPR32RegClassID;
591 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
594 /// Coerce the register to GPR32 and return the real register for the current
596 unsigned getGPRMM16Reg() const {
597 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
598 unsigned ClassID = Mips::GPR32RegClassID;
599 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
602 /// Coerce the register to GPR64 and return the real register for the current
604 unsigned getGPR64Reg() const {
605 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
606 unsigned ClassID = Mips::GPR64RegClassID;
607 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
611 /// Coerce the register to AFGR64 and return the real register for the current
613 unsigned getAFGR64Reg() const {
614 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
615 if (RegIdx.Index % 2 != 0)
616 AsmParser.Warning(StartLoc, "Float register should be even.");
617 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
618 .getRegister(RegIdx.Index / 2);
621 /// Coerce the register to FGR64 and return the real register for the current
623 unsigned getFGR64Reg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
625 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
626 .getRegister(RegIdx.Index);
629 /// Coerce the register to FGR32 and return the real register for the current
631 unsigned getFGR32Reg() const {
632 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
633 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
634 .getRegister(RegIdx.Index);
637 /// Coerce the register to FGRH32 and return the real register for the current
639 unsigned getFGRH32Reg() const {
640 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
641 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
642 .getRegister(RegIdx.Index);
645 /// Coerce the register to FCC and return the real register for the current
647 unsigned getFCCReg() const {
648 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
649 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
650 .getRegister(RegIdx.Index);
653 /// Coerce the register to MSA128 and return the real register for the current
655 unsigned getMSA128Reg() const {
656 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
657 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
659 unsigned ClassID = Mips::MSA128BRegClassID;
660 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
663 /// Coerce the register to MSACtrl and return the real register for the
665 unsigned getMSACtrlReg() const {
666 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
667 unsigned ClassID = Mips::MSACtrlRegClassID;
668 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
671 /// Coerce the register to COP2 and return the real register for the
673 unsigned getCOP2Reg() const {
674 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
675 unsigned ClassID = Mips::COP2RegClassID;
676 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
679 /// Coerce the register to COP3 and return the real register for the
681 unsigned getCOP3Reg() const {
682 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
683 unsigned ClassID = Mips::COP3RegClassID;
684 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
687 /// Coerce the register to ACC64DSP and return the real register for the
689 unsigned getACC64DSPReg() const {
690 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
691 unsigned ClassID = Mips::ACC64DSPRegClassID;
692 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
695 /// Coerce the register to HI32DSP and return the real register for the
697 unsigned getHI32DSPReg() const {
698 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
699 unsigned ClassID = Mips::HI32DSPRegClassID;
700 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
703 /// Coerce the register to LO32DSP and return the real register for the
705 unsigned getLO32DSPReg() const {
706 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
707 unsigned ClassID = Mips::LO32DSPRegClassID;
708 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
711 /// Coerce the register to CCR and return the real register for the
713 unsigned getCCRReg() const {
714 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
715 unsigned ClassID = Mips::CCRRegClassID;
716 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
719 /// Coerce the register to HWRegs and return the real register for the
721 unsigned getHWRegsReg() const {
722 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
723 unsigned ClassID = Mips::HWRegsRegClassID;
724 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
728 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
729 // Add as immediate when possible. Null MCExpr = 0.
731 Inst.addOperand(MCOperand::createImm(0));
732 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
733 Inst.addOperand(MCOperand::createImm(CE->getValue()));
735 Inst.addOperand(MCOperand::createExpr(Expr));
738 void addRegOperands(MCInst &Inst, unsigned N) const {
739 llvm_unreachable("Use a custom parser instead");
742 /// Render the operand to an MCInst as a GPR32
743 /// Asserts if the wrong number of operands are requested, or the operand
744 /// is not a k_RegisterIndex compatible with RegKind_GPR
745 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
746 assert(N == 1 && "Invalid number of operands!");
747 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
750 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
751 assert(N == 1 && "Invalid number of operands!");
752 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
755 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
756 assert(N == 1 && "Invalid number of operands!");
757 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
760 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
761 assert(N == 1 && "Invalid number of operands!");
762 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
765 /// Render the operand to an MCInst as a GPR64
766 /// Asserts if the wrong number of operands are requested, or the operand
767 /// is not a k_RegisterIndex compatible with RegKind_GPR
768 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
769 assert(N == 1 && "Invalid number of operands!");
770 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
773 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
778 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
783 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
786 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
787 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
788 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
792 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
793 assert(N == 1 && "Invalid number of operands!");
794 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
797 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
798 assert(N == 1 && "Invalid number of operands!");
799 Inst.addOperand(MCOperand::createReg(getFCCReg()));
802 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
803 assert(N == 1 && "Invalid number of operands!");
804 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
807 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
808 assert(N == 1 && "Invalid number of operands!");
809 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
812 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
813 assert(N == 1 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
817 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
818 assert(N == 1 && "Invalid number of operands!");
819 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
822 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
823 assert(N == 1 && "Invalid number of operands!");
824 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
827 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
828 assert(N == 1 && "Invalid number of operands!");
829 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
832 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
833 assert(N == 1 && "Invalid number of operands!");
834 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
837 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!");
839 Inst.addOperand(MCOperand::createReg(getCCRReg()));
842 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 1 && "Invalid number of operands!");
844 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
847 void addImmOperands(MCInst &Inst, unsigned N) const {
848 assert(N == 1 && "Invalid number of operands!");
849 const MCExpr *Expr = getImm();
853 void addMemOperands(MCInst &Inst, unsigned N) const {
854 assert(N == 2 && "Invalid number of operands!");
856 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
858 const MCExpr *Expr = getMemOff();
862 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
863 assert(N == 2 && "Invalid number of operands!");
865 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
867 const MCExpr *Expr = getMemOff();
871 void addRegListOperands(MCInst &Inst, unsigned N) const {
872 assert(N == 1 && "Invalid number of operands!");
874 for (auto RegNo : getRegList())
875 Inst.addOperand(MCOperand::createReg(RegNo));
878 void addRegPairOperands(MCInst &Inst, unsigned N) const {
879 assert(N == 2 && "Invalid number of operands!");
880 unsigned RegNo = getRegPair();
881 Inst.addOperand(MCOperand::createReg(RegNo++));
882 Inst.addOperand(MCOperand::createReg(RegNo));
885 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
886 assert(N == 2 && "Invalid number of operands!");
887 for (auto RegNo : getRegList())
888 Inst.addOperand(MCOperand::createReg(RegNo));
891 bool isReg() const override {
892 // As a special case until we sort out the definition of div/divu, pretend
893 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
894 if (isGPRAsmReg() && RegIdx.Index == 0)
897 return Kind == k_PhysRegister;
899 bool isRegIdx() const { return Kind == k_RegisterIndex; }
900 bool isImm() const override { return Kind == k_Immediate; }
901 bool isConstantImm() const {
902 return isImm() && dyn_cast<MCConstantExpr>(getImm());
904 template <unsigned Bits> bool isUImm() const {
905 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
907 bool isToken() const override {
908 // Note: It's not possible to pretend that other operand kinds are tokens.
909 // The matcher emitter checks tokens first.
910 return Kind == k_Token;
912 bool isMem() const override { return Kind == k_Memory; }
913 bool isConstantMemOff() const {
914 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
916 template <unsigned Bits> bool isMemWithSimmOffset() const {
917 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
919 bool isMemWithGRPMM16Base() const {
920 return isMem() && getMemBase()->isMM16AsmReg();
922 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
923 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
924 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
926 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
927 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
928 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
929 && (getMemBase()->getGPR32Reg() == Mips::SP);
931 bool isRegList16() const {
935 int Size = RegList.List->size();
936 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
937 RegList.List->back() != Mips::RA)
940 int PrevReg = *RegList.List->begin();
941 for (int i = 1; i < Size - 1; i++) {
942 int Reg = (*(RegList.List))[i];
943 if ( Reg != PrevReg + 1)
950 bool isInvNum() const { return Kind == k_Immediate; }
951 bool isLSAImm() const {
952 if (!isConstantImm())
954 int64_t Val = getConstantImm();
955 return 1 <= Val && Val <= 4;
957 bool isRegList() const { return Kind == k_RegList; }
958 bool isMovePRegPair() const {
959 if (Kind != k_RegList || RegList.List->size() != 2)
962 unsigned R0 = RegList.List->front();
963 unsigned R1 = RegList.List->back();
965 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
966 (R0 == Mips::A1 && R1 == Mips::A3) ||
967 (R0 == Mips::A2 && R1 == Mips::A3) ||
968 (R0 == Mips::A0 && R1 == Mips::S5) ||
969 (R0 == Mips::A0 && R1 == Mips::S6) ||
970 (R0 == Mips::A0 && R1 == Mips::A1) ||
971 (R0 == Mips::A0 && R1 == Mips::A2) ||
972 (R0 == Mips::A0 && R1 == Mips::A3))
978 StringRef getToken() const {
979 assert(Kind == k_Token && "Invalid access!");
980 return StringRef(Tok.Data, Tok.Length);
982 bool isRegPair() const { return Kind == k_RegPair; }
984 unsigned getReg() const override {
985 // As a special case until we sort out the definition of div/divu, pretend
986 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
987 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
988 RegIdx.Kind & RegKind_GPR)
989 return getGPR32Reg(); // FIXME: GPR64 too
991 assert(Kind == k_PhysRegister && "Invalid access!");
995 const MCExpr *getImm() const {
996 assert((Kind == k_Immediate) && "Invalid access!");
1000 int64_t getConstantImm() const {
1001 const MCExpr *Val = getImm();
1002 return static_cast<const MCConstantExpr *>(Val)->getValue();
1005 MipsOperand *getMemBase() const {
1006 assert((Kind == k_Memory) && "Invalid access!");
1010 const MCExpr *getMemOff() const {
1011 assert((Kind == k_Memory) && "Invalid access!");
1015 int64_t getConstantMemOff() const {
1016 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1019 const SmallVectorImpl<unsigned> &getRegList() const {
1020 assert((Kind == k_RegList) && "Invalid access!");
1021 return *(RegList.List);
1024 unsigned getRegPair() const {
1025 assert((Kind == k_RegPair) && "Invalid access!");
1026 return RegIdx.Index;
1029 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1030 MipsAsmParser &Parser) {
1031 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1032 Op->Tok.Data = Str.data();
1033 Op->Tok.Length = Str.size();
1039 /// Create a numeric register (e.g. $1). The exact register remains
1040 /// unresolved until an instruction successfully matches
1041 static std::unique_ptr<MipsOperand>
1042 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1043 SMLoc E, MipsAsmParser &Parser) {
1044 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1045 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1048 /// Create a register that is definitely a GPR.
1049 /// This is typically only used for named registers such as $gp.
1050 static std::unique_ptr<MipsOperand>
1051 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1052 MipsAsmParser &Parser) {
1053 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1056 /// Create a register that is definitely a FGR.
1057 /// This is typically only used for named registers such as $f0.
1058 static std::unique_ptr<MipsOperand>
1059 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1060 MipsAsmParser &Parser) {
1061 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1064 /// Create a register that is definitely a HWReg.
1065 /// This is typically only used for named registers such as $hwr_cpunum.
1066 static std::unique_ptr<MipsOperand>
1067 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1068 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1069 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1072 /// Create a register that is definitely an FCC.
1073 /// This is typically only used for named registers such as $fcc0.
1074 static std::unique_ptr<MipsOperand>
1075 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1076 MipsAsmParser &Parser) {
1077 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1080 /// Create a register that is definitely an ACC.
1081 /// This is typically only used for named registers such as $ac0.
1082 static std::unique_ptr<MipsOperand>
1083 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1084 MipsAsmParser &Parser) {
1085 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1088 /// Create a register that is definitely an MSA128.
1089 /// This is typically only used for named registers such as $w0.
1090 static std::unique_ptr<MipsOperand>
1091 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1092 SMLoc E, MipsAsmParser &Parser) {
1093 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1096 /// Create a register that is definitely an MSACtrl.
1097 /// This is typically only used for named registers such as $msaaccess.
1098 static std::unique_ptr<MipsOperand>
1099 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1100 SMLoc E, MipsAsmParser &Parser) {
1101 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1104 static std::unique_ptr<MipsOperand>
1105 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1106 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1113 static std::unique_ptr<MipsOperand>
1114 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1115 SMLoc E, MipsAsmParser &Parser) {
1116 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1117 Op->Mem.Base = Base.release();
1124 static std::unique_ptr<MipsOperand>
1125 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1126 MipsAsmParser &Parser) {
1127 assert (Regs.size() > 0 && "Empty list not allowed");
1129 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1130 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1131 Op->StartLoc = StartLoc;
1132 Op->EndLoc = EndLoc;
1136 static std::unique_ptr<MipsOperand>
1137 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1138 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1139 Op->RegIdx.Index = RegNo;
1145 bool isGPRAsmReg() const {
1146 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1148 bool isMM16AsmReg() const {
1149 if (!(isRegIdx() && RegIdx.Kind))
1151 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1152 || RegIdx.Index == 16 || RegIdx.Index == 17);
1154 bool isMM16AsmRegZero() const {
1155 if (!(isRegIdx() && RegIdx.Kind))
1157 return (RegIdx.Index == 0 ||
1158 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1159 RegIdx.Index == 17);
1161 bool isMM16AsmRegMoveP() const {
1162 if (!(isRegIdx() && RegIdx.Kind))
1164 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1165 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1167 bool isFGRAsmReg() const {
1168 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1169 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1171 bool isHWRegsAsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1174 bool isCCRAsmReg() const {
1175 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1177 bool isFCCAsmReg() const {
1178 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1180 if (!AsmParser.hasEightFccRegisters())
1181 return RegIdx.Index == 0;
1182 return RegIdx.Index <= 7;
1184 bool isACCAsmReg() const {
1185 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1187 bool isCOP2AsmReg() const {
1188 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1190 bool isCOP3AsmReg() const {
1191 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1193 bool isMSA128AsmReg() const {
1194 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1196 bool isMSACtrlAsmReg() const {
1197 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1200 /// getStartLoc - Get the location of the first token of this operand.
1201 SMLoc getStartLoc() const override { return StartLoc; }
1202 /// getEndLoc - Get the location of the last token of this operand.
1203 SMLoc getEndLoc() const override { return EndLoc; }
1205 virtual ~MipsOperand() {
1213 delete RegList.List;
1214 case k_PhysRegister:
1215 case k_RegisterIndex:
1222 void print(raw_ostream &OS) const override {
1231 Mem.Base->print(OS);
1236 case k_PhysRegister:
1237 OS << "PhysReg<" << PhysReg.Num << ">";
1239 case k_RegisterIndex:
1240 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1247 for (auto Reg : (*RegList.List))
1252 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1256 }; // class MipsOperand
1260 extern const MCInstrDesc MipsInsts[];
1262 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1263 return MipsInsts[Opcode];
1266 static bool hasShortDelaySlot(unsigned Opcode) {
1269 case Mips::JALRS_MM:
1270 case Mips::JALRS16_MM:
1271 case Mips::BGEZALS_MM:
1272 case Mips::BLTZALS_MM:
1279 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1280 SmallVectorImpl<MCInst> &Instructions) {
1281 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1285 if (MCID.isBranch() || MCID.isCall()) {
1286 const unsigned Opcode = Inst.getOpcode();
1296 assert(hasCnMips() && "instruction only valid for octeon cpus");
1303 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1304 Offset = Inst.getOperand(2);
1305 if (!Offset.isImm())
1306 break; // We'll deal with this situation later on when applying fixups.
1307 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1308 return Error(IDLoc, "branch target out of range");
1309 if (OffsetToAlignment(Offset.getImm(),
1310 1LL << (inMicroMipsMode() ? 1 : 2)))
1311 return Error(IDLoc, "branch to misaligned address");
1325 case Mips::BGEZAL_MM:
1326 case Mips::BLTZAL_MM:
1329 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1330 Offset = Inst.getOperand(1);
1331 if (!Offset.isImm())
1332 break; // We'll deal with this situation later on when applying fixups.
1333 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1334 return Error(IDLoc, "branch target out of range");
1335 if (OffsetToAlignment(Offset.getImm(),
1336 1LL << (inMicroMipsMode() ? 1 : 2)))
1337 return Error(IDLoc, "branch to misaligned address");
1339 case Mips::BEQZ16_MM:
1340 case Mips::BNEZ16_MM:
1341 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1342 Offset = Inst.getOperand(1);
1343 if (!Offset.isImm())
1344 break; // We'll deal with this situation later on when applying fixups.
1345 if (!isIntN(8, Offset.getImm()))
1346 return Error(IDLoc, "branch target out of range");
1347 if (OffsetToAlignment(Offset.getImm(), 2LL))
1348 return Error(IDLoc, "branch to misaligned address");
1353 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1354 // We still accept it but it is a normal nop.
1355 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1356 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1357 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1362 const unsigned Opcode = Inst.getOpcode();
1374 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1375 // The offset is handled above
1376 Opnd = Inst.getOperand(1);
1378 return Error(IDLoc, "expected immediate operand kind");
1379 Imm = Opnd.getImm();
1380 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1381 Opcode == Mips::BBIT1 ? 63 : 31))
1382 return Error(IDLoc, "immediate operand value out of range");
1384 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1386 Inst.getOperand(1).setImm(Imm - 32);
1394 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1396 Opnd = Inst.getOperand(3);
1398 return Error(IDLoc, "expected immediate operand kind");
1399 Imm = Opnd.getImm();
1400 if (Imm < 0 || Imm > 31)
1401 return Error(IDLoc, "immediate operand value out of range");
1403 Opnd = Inst.getOperand(2);
1405 return Error(IDLoc, "expected immediate operand kind");
1406 Imm = Opnd.getImm();
1407 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1408 Opcode == Mips::EXTS ? 63 : 31))
1409 return Error(IDLoc, "immediate operand value out of range");
1411 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1412 Inst.getOperand(2).setImm(Imm - 32);
1418 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1419 Opnd = Inst.getOperand(2);
1421 return Error(IDLoc, "expected immediate operand kind");
1422 Imm = Opnd.getImm();
1423 if (!isInt<10>(Imm))
1424 return Error(IDLoc, "immediate operand value out of range");
1429 if (MCID.mayLoad() || MCID.mayStore()) {
1430 // Check the offset of memory operand, if it is a symbol
1431 // reference or immediate we may have to expand instructions.
1432 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1433 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1434 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1435 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1436 MCOperand &Op = Inst.getOperand(i);
1438 int MemOffset = Op.getImm();
1439 if (MemOffset < -32768 || MemOffset > 32767) {
1440 // Offset can't exceed 16bit value.
1441 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1444 } else if (Op.isExpr()) {
1445 const MCExpr *Expr = Op.getExpr();
1446 if (Expr->getKind() == MCExpr::SymbolRef) {
1447 const MCSymbolRefExpr *SR =
1448 static_cast<const MCSymbolRefExpr *>(Expr);
1449 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1451 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1454 } else if (!isEvaluated(Expr)) {
1455 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1463 if (inMicroMipsMode()) {
1464 if (MCID.mayLoad()) {
1465 // Try to create 16-bit GP relative load instruction.
1466 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1467 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1468 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1469 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1470 MCOperand &Op = Inst.getOperand(i);
1472 int MemOffset = Op.getImm();
1473 MCOperand &DstReg = Inst.getOperand(0);
1474 MCOperand &BaseReg = Inst.getOperand(1);
1475 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1476 getContext().getRegisterInfo()->getRegClass(
1477 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1478 BaseReg.getReg() == Mips::GP) {
1480 TmpInst.setLoc(IDLoc);
1481 TmpInst.setOpcode(Mips::LWGP_MM);
1482 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1483 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1484 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1485 Instructions.push_back(TmpInst);
1493 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1498 switch (Inst.getOpcode()) {
1501 case Mips::ADDIUS5_MM:
1502 Opnd = Inst.getOperand(2);
1504 return Error(IDLoc, "expected immediate operand kind");
1505 Imm = Opnd.getImm();
1506 if (Imm < -8 || Imm > 7)
1507 return Error(IDLoc, "immediate operand value out of range");
1509 case Mips::ADDIUSP_MM:
1510 Opnd = Inst.getOperand(0);
1512 return Error(IDLoc, "expected immediate operand kind");
1513 Imm = Opnd.getImm();
1514 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1516 return Error(IDLoc, "immediate operand value out of range");
1518 case Mips::SLL16_MM:
1519 case Mips::SRL16_MM:
1520 Opnd = Inst.getOperand(2);
1522 return Error(IDLoc, "expected immediate operand kind");
1523 Imm = Opnd.getImm();
1524 if (Imm < 1 || Imm > 8)
1525 return Error(IDLoc, "immediate operand value out of range");
1528 Opnd = Inst.getOperand(1);
1530 return Error(IDLoc, "expected immediate operand kind");
1531 Imm = Opnd.getImm();
1532 if (Imm < -1 || Imm > 126)
1533 return Error(IDLoc, "immediate operand value out of range");
1535 case Mips::ADDIUR2_MM:
1536 Opnd = Inst.getOperand(2);
1538 return Error(IDLoc, "expected immediate operand kind");
1539 Imm = Opnd.getImm();
1540 if (!(Imm == 1 || Imm == -1 ||
1541 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1542 return Error(IDLoc, "immediate operand value out of range");
1544 case Mips::ADDIUR1SP_MM:
1545 Opnd = Inst.getOperand(1);
1547 return Error(IDLoc, "expected immediate operand kind");
1548 Imm = Opnd.getImm();
1549 if (OffsetToAlignment(Imm, 4LL))
1550 return Error(IDLoc, "misaligned immediate operand value");
1551 if (Imm < 0 || Imm > 255)
1552 return Error(IDLoc, "immediate operand value out of range");
1554 case Mips::ANDI16_MM:
1555 Opnd = Inst.getOperand(2);
1557 return Error(IDLoc, "expected immediate operand kind");
1558 Imm = Opnd.getImm();
1559 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1560 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1561 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1562 return Error(IDLoc, "immediate operand value out of range");
1564 case Mips::LBU16_MM:
1565 Opnd = Inst.getOperand(2);
1567 return Error(IDLoc, "expected immediate operand kind");
1568 Imm = Opnd.getImm();
1569 if (Imm < -1 || Imm > 14)
1570 return Error(IDLoc, "immediate operand value out of range");
1573 Opnd = Inst.getOperand(2);
1575 return Error(IDLoc, "expected immediate operand kind");
1576 Imm = Opnd.getImm();
1577 if (Imm < 0 || Imm > 15)
1578 return Error(IDLoc, "immediate operand value out of range");
1580 case Mips::LHU16_MM:
1582 Opnd = Inst.getOperand(2);
1584 return Error(IDLoc, "expected immediate operand kind");
1585 Imm = Opnd.getImm();
1586 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1587 return Error(IDLoc, "immediate operand value out of range");
1591 Opnd = Inst.getOperand(2);
1593 return Error(IDLoc, "expected immediate operand kind");
1594 Imm = Opnd.getImm();
1595 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1596 return Error(IDLoc, "immediate operand value out of range");
1600 Opnd = Inst.getOperand(2);
1602 return Error(IDLoc, "expected immediate operand kind");
1603 Imm = Opnd.getImm();
1604 if (!isUInt<5>(Imm))
1605 return Error(IDLoc, "immediate operand value out of range");
1607 case Mips::ADDIUPC_MM:
1608 MCOperand Opnd = Inst.getOperand(1);
1610 return Error(IDLoc, "expected immediate operand kind");
1611 int Imm = Opnd.getImm();
1612 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1613 return Error(IDLoc, "immediate operand value out of range");
1618 if (needsExpansion(Inst)) {
1619 if (expandInstruction(Inst, IDLoc, Instructions))
1622 Instructions.push_back(Inst);
1624 // If this instruction has a delay slot and .set reorder is active,
1625 // emit a NOP after it.
1626 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1627 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1632 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1634 switch (Inst.getOpcode()) {
1635 case Mips::LoadImm32:
1636 case Mips::LoadImm64:
1637 case Mips::LoadAddrImm32:
1638 case Mips::LoadAddrReg32:
1639 case Mips::B_MM_Pseudo:
1642 case Mips::JalOneReg:
1643 case Mips::JalTwoReg:
1662 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1663 SmallVectorImpl<MCInst> &Instructions) {
1664 switch (Inst.getOpcode()) {
1665 default: llvm_unreachable("unimplemented expansion");
1666 case Mips::LoadImm32:
1667 return expandLoadImm(Inst, true, IDLoc, Instructions);
1668 case Mips::LoadImm64:
1669 return expandLoadImm(Inst, false, IDLoc, Instructions);
1670 case Mips::LoadAddrImm32:
1671 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1672 case Mips::LoadAddrReg32:
1673 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1674 case Mips::B_MM_Pseudo:
1675 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1678 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1679 case Mips::JalOneReg:
1680 case Mips::JalTwoReg:
1681 return expandJalWithRegs(Inst, IDLoc, Instructions);
1684 return expandBranchImm(Inst, IDLoc, Instructions);
1693 return expandCondBranches(Inst, IDLoc, Instructions);
1695 return expandUlhu(Inst, IDLoc, Instructions);
1697 return expandUlw(Inst, IDLoc, Instructions);
1702 template <unsigned ShiftAmount>
1703 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1704 SmallVectorImpl<MCInst> &Instructions) {
1706 if (ShiftAmount >= 32) {
1707 tmpInst.setOpcode(Mips::DSLL32);
1708 tmpInst.addOperand(MCOperand::createReg(RegNo));
1709 tmpInst.addOperand(MCOperand::createReg(RegNo));
1710 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1711 tmpInst.setLoc(IDLoc);
1712 Instructions.push_back(tmpInst);
1714 } else if (ShiftAmount > 0) {
1715 tmpInst.setOpcode(Mips::DSLL);
1716 tmpInst.addOperand(MCOperand::createReg(RegNo));
1717 tmpInst.addOperand(MCOperand::createReg(RegNo));
1718 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1719 tmpInst.setLoc(IDLoc);
1720 Instructions.push_back(tmpInst);
1723 // There's no need for an ORi if the immediate is 0.
1724 if (Operand.isImm() && Operand.getImm() == 0)
1727 tmpInst.setOpcode(Mips::ORi);
1728 tmpInst.addOperand(MCOperand::createReg(RegNo));
1729 tmpInst.addOperand(MCOperand::createReg(RegNo));
1730 tmpInst.addOperand(Operand);
1731 tmpInst.setLoc(IDLoc);
1732 Instructions.push_back(tmpInst);
1735 template <unsigned ShiftAmount>
1736 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1737 SmallVectorImpl<MCInst> &Instructions) {
1738 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1743 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1744 SmallVectorImpl<MCInst> &Instructions) {
1745 // Create a JALR instruction which is going to replace the pseudo-JAL.
1747 JalrInst.setLoc(IDLoc);
1748 const MCOperand FirstRegOp = Inst.getOperand(0);
1749 const unsigned Opcode = Inst.getOpcode();
1751 if (Opcode == Mips::JalOneReg) {
1752 // jal $rs => jalr $rs
1753 if (inMicroMipsMode()) {
1754 JalrInst.setOpcode(Mips::JALR16_MM);
1755 JalrInst.addOperand(FirstRegOp);
1757 JalrInst.setOpcode(Mips::JALR);
1758 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1759 JalrInst.addOperand(FirstRegOp);
1761 } else if (Opcode == Mips::JalTwoReg) {
1762 // jal $rd, $rs => jalr $rd, $rs
1763 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1764 JalrInst.addOperand(FirstRegOp);
1765 const MCOperand SecondRegOp = Inst.getOperand(1);
1766 JalrInst.addOperand(SecondRegOp);
1768 Instructions.push_back(JalrInst);
1770 // If .set reorder is active, emit a NOP after it.
1771 if (AssemblerOptions.back()->isReorder()) {
1772 // This is a 32-bit NOP because these 2 pseudo-instructions
1773 // do not have a short delay slot.
1775 NopInst.setOpcode(Mips::SLL);
1776 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1777 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1778 NopInst.addOperand(MCOperand::createImm(0));
1779 Instructions.push_back(NopInst);
1785 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1786 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1787 SmallVectorImpl<MCInst> &Instructions) {
1788 if (!Is32BitImm && !isGP64bit()) {
1789 Error(IDLoc, "instruction requires a 64-bit architecture");
1793 bool UseSrcReg = false;
1794 if (SrcReg != Mips::NoRegister)
1799 unsigned TmpReg = DstReg;
1800 if (UseSrcReg && (DstReg == SrcReg)) {
1801 // At this point we need AT to perform the expansions and we exit if it is
1803 unsigned ATReg = getATReg(IDLoc);
1809 tmpInst.setLoc(IDLoc);
1810 // FIXME: gas has a special case for values that are 000...1111, which
1811 // becomes a li -1 and then a dsrl
1812 if (0 <= ImmValue && ImmValue <= 65535) {
1813 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1814 // li d,j => ori d,$zero,j
1816 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1817 tmpInst.setOpcode(Mips::ORi);
1818 tmpInst.addOperand(MCOperand::createReg(DstReg));
1819 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1820 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1821 Instructions.push_back(tmpInst);
1822 } else if (ImmValue < 0 && ImmValue >= -32768) {
1823 // For negative signed 16-bit values (-32768 <= j < 0):
1824 // li d,j => addiu d,$zero,j
1826 SrcReg = Mips::ZERO;
1827 tmpInst.setOpcode(Mips::ADDiu);
1828 tmpInst.addOperand(MCOperand::createReg(DstReg));
1829 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1830 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1831 Instructions.push_back(tmpInst);
1832 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1833 warnIfNoMacro(IDLoc);
1835 // For all other values which are representable as a 32-bit integer:
1836 // li d,j => lui d,hi16(j)
1838 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1839 uint16_t Bits15To0 = ImmValue & 0xffff;
1841 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1842 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1844 tmpInst.setOpcode(Mips::ORi);
1845 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1846 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1847 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1848 tmpInst.setLoc(IDLoc);
1849 Instructions.push_back(tmpInst);
1850 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1851 createLShiftOri<16>(0, TmpReg, IDLoc, Instructions);
1853 tmpInst.setOpcode(Mips::LUi);
1854 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1855 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1856 Instructions.push_back(tmpInst);
1858 createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1861 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1863 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1865 Error(IDLoc, "instruction requires a 32-bit immediate");
1868 warnIfNoMacro(IDLoc);
1870 // <------- lo32 ------>
1871 // <------- hi32 ------>
1872 // <- hi16 -> <- lo16 ->
1873 // _________________________________
1875 // | 16-bits | 16-bits | 16-bits |
1876 // |__________|__________|__________|
1878 // For any 64-bit value that is representable as a 48-bit integer:
1879 // li d,j => lui d,hi16(j)
1880 // ori d,d,hi16(lo32(j))
1882 // ori d,d,lo16(lo32(j))
1883 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1884 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1885 uint16_t Bits15To0 = ImmValue & 0xffff;
1887 tmpInst.setOpcode(Mips::LUi);
1888 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1889 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1890 Instructions.push_back(tmpInst);
1891 createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1892 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1895 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1899 Error(IDLoc, "instruction requires a 32-bit immediate");
1902 warnIfNoMacro(IDLoc);
1904 // <------- hi32 ------> <------- lo32 ------>
1905 // <- hi16 -> <- lo16 ->
1906 // ___________________________________________
1908 // | 16-bits | 16-bits | 16-bits | 16-bits |
1909 // |__________|__________|__________|__________|
1911 // For all other values which are representable as a 64-bit integer:
1912 // li d,j => lui d,hi16(j)
1913 // ori d,d,lo16(hi32(j))
1915 // ori d,d,hi16(lo32(j))
1917 // ori d,d,lo16(lo32(j))
1918 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1919 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1920 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1921 uint16_t Bits15To0 = ImmValue & 0xffff;
1923 tmpInst.setOpcode(Mips::LUi);
1924 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1925 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1926 Instructions.push_back(tmpInst);
1927 createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1929 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1930 // two left shifts of 16 bits.
1931 if (Bits31To16 == 0) {
1932 createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1934 createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1935 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1939 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1944 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1945 SmallVectorImpl<MCInst> &Instructions) {
1946 const MCOperand &ImmOp = Inst.getOperand(1);
1947 assert(ImmOp.isImm() && "expected immediate operand kind");
1948 const MCOperand &DstRegOp = Inst.getOperand(0);
1949 assert(DstRegOp.isReg() && "expected register operand kind");
1951 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1952 Is32BitImm, IDLoc, Instructions))
1959 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1960 SmallVectorImpl<MCInst> &Instructions) {
1961 const MCOperand &DstRegOp = Inst.getOperand(0);
1962 assert(DstRegOp.isReg() && "expected register operand kind");
1964 const MCOperand &SrcRegOp = Inst.getOperand(1);
1965 assert(SrcRegOp.isReg() && "expected register operand kind");
1967 const MCOperand &ImmOp = Inst.getOperand(2);
1968 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1969 "expected immediate operand kind");
1970 if (!ImmOp.isImm()) {
1971 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1972 SrcRegOp.getReg(), Is32BitImm, IDLoc,
1979 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1980 Is32BitImm, IDLoc, Instructions))
1987 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1988 SmallVectorImpl<MCInst> &Instructions) {
1989 const MCOperand &DstRegOp = Inst.getOperand(0);
1990 assert(DstRegOp.isReg() && "expected register operand kind");
1992 const MCOperand &ImmOp = Inst.getOperand(1);
1993 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1994 "expected immediate operand kind");
1995 if (!ImmOp.isImm()) {
1996 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1997 Mips::NoRegister, Is32BitImm, IDLoc,
2004 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2005 Is32BitImm, IDLoc, Instructions))
2011 bool MipsAsmParser::loadAndAddSymbolAddress(
2012 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2013 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2014 warnIfNoMacro(IDLoc);
2016 if (Is32BitSym && isABI_N64())
2017 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
2020 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2021 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2022 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2023 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2024 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2026 bool UseSrcReg = SrcReg != Mips::NoRegister;
2028 unsigned TmpReg = DstReg;
2029 if (UseSrcReg && (DstReg == SrcReg)) {
2030 // At this point we need AT to perform the expansions and we exit if it is
2032 unsigned ATReg = getATReg(IDLoc);
2039 // If it's a 64-bit architecture, expand to:
2040 // la d,sym => lui d,highest(sym)
2041 // ori d,d,higher(sym)
2043 // ori d,d,hi16(sym)
2045 // ori d,d,lo16(sym)
2046 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2047 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2048 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2049 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2051 tmpInst.setOpcode(Mips::LUi);
2052 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2053 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2054 Instructions.push_back(tmpInst);
2056 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2058 createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2060 createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2063 // Otherwise, expand to:
2064 // la d,sym => lui d,hi16(sym)
2065 // ori d,d,lo16(sym)
2066 tmpInst.setOpcode(Mips::LUi);
2067 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2068 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2069 Instructions.push_back(tmpInst);
2071 createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2076 createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2081 bool MipsAsmParser::expandUncondBranchMMPseudo(
2082 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2083 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2084 "unexpected number of operands");
2086 MCOperand Offset = Inst.getOperand(0);
2087 if (Offset.isExpr()) {
2089 Inst.setOpcode(Mips::BEQ_MM);
2090 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2091 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2092 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2094 assert(Offset.isImm() && "expected immediate operand kind");
2095 if (isIntN(11, Offset.getImm())) {
2096 // If offset fits into 11 bits then this instruction becomes microMIPS
2097 // 16-bit unconditional branch instruction.
2098 Inst.setOpcode(Mips::B16_MM);
2100 if (!isIntN(17, Offset.getImm()))
2101 Error(IDLoc, "branch target out of range");
2102 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2103 Error(IDLoc, "branch to misaligned address");
2105 Inst.setOpcode(Mips::BEQ_MM);
2106 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2107 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2108 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2111 Instructions.push_back(Inst);
2113 // If .set reorder is active, emit a NOP after the branch instruction.
2114 if (AssemblerOptions.back()->isReorder())
2115 createNop(true, IDLoc, Instructions);
2120 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2121 SmallVectorImpl<MCInst> &Instructions) {
2122 const MCOperand &DstRegOp = Inst.getOperand(0);
2123 assert(DstRegOp.isReg() && "expected register operand kind");
2125 const MCOperand &ImmOp = Inst.getOperand(1);
2126 assert(ImmOp.isImm() && "expected immediate operand kind");
2128 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2129 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2131 unsigned OpCode = 0;
2132 switch(Inst.getOpcode()) {
2140 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2144 int64_t ImmValue = ImmOp.getImm();
2145 if (ImmValue == 0) {
2147 BranchInst.setOpcode(OpCode);
2148 BranchInst.addOperand(DstRegOp);
2149 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2150 BranchInst.addOperand(MemOffsetOp);
2151 Instructions.push_back(BranchInst);
2153 warnIfNoMacro(IDLoc);
2155 unsigned ATReg = getATReg(IDLoc);
2159 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2164 BranchInst.setOpcode(OpCode);
2165 BranchInst.addOperand(DstRegOp);
2166 BranchInst.addOperand(MCOperand::createReg(ATReg));
2167 BranchInst.addOperand(MemOffsetOp);
2168 Instructions.push_back(BranchInst);
2173 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2174 SmallVectorImpl<MCInst> &Instructions,
2175 bool isLoad, bool isImmOpnd) {
2177 unsigned ImmOffset, HiOffset, LoOffset;
2178 const MCExpr *ExprOffset;
2180 // 1st operand is either the source or destination register.
2181 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2182 unsigned RegOpNum = Inst.getOperand(0).getReg();
2183 // 2nd operand is the base register.
2184 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2185 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2186 // 3rd operand is either an immediate or expression.
2188 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2189 ImmOffset = Inst.getOperand(2).getImm();
2190 LoOffset = ImmOffset & 0x0000ffff;
2191 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2192 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2193 if (LoOffset & 0x8000)
2196 ExprOffset = Inst.getOperand(2).getExpr();
2197 // All instructions will have the same location.
2198 TempInst.setLoc(IDLoc);
2199 // These are some of the types of expansions we perform here:
2200 // 1) lw $8, sym => lui $8, %hi(sym)
2201 // lw $8, %lo(sym)($8)
2202 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2204 // lw $8, %lo(offset)($9)
2205 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2207 // lw $8, %lo(offset)($at)
2208 // 4) sw $8, sym => lui $at, %hi(sym)
2209 // sw $8, %lo(sym)($at)
2210 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2212 // sw $8, %lo(offset)($at)
2213 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2214 // ldc1 $f0, %lo(sym)($at)
2216 // For load instructions we can use the destination register as a temporary
2217 // if base and dst are different (examples 1 and 2) and if the base register
2218 // is general purpose otherwise we must use $at (example 6) and error if it's
2219 // not available. For stores we must use $at (examples 4 and 5) because we
2220 // must not clobber the source register setting up the offset.
2221 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2222 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2223 unsigned RegClassIDOp0 =
2224 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2225 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2226 (RegClassIDOp0 == Mips::GPR64RegClassID);
2227 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2228 TmpRegNum = RegOpNum;
2230 // At this point we need AT to perform the expansions and we exit if it is
2232 TmpRegNum = getATReg(IDLoc);
2237 TempInst.setOpcode(Mips::LUi);
2238 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2240 TempInst.addOperand(MCOperand::createImm(HiOffset));
2242 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2243 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2245 // Add the instruction to the list.
2246 Instructions.push_back(TempInst);
2247 // Prepare TempInst for next instruction.
2249 // Add temp register to base.
2250 if (BaseRegNum != Mips::ZERO) {
2251 TempInst.setOpcode(Mips::ADDu);
2252 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2253 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2254 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2255 Instructions.push_back(TempInst);
2258 // And finally, create original instruction with low part
2259 // of offset and new base.
2260 TempInst.setOpcode(Inst.getOpcode());
2261 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2262 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2264 TempInst.addOperand(MCOperand::createImm(LoOffset));
2266 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2267 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2269 Instructions.push_back(TempInst);
2274 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2275 SmallVectorImpl<MCInst> &Instructions) {
2276 unsigned OpNum = Inst.getNumOperands();
2277 unsigned Opcode = Inst.getOpcode();
2278 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2280 assert (Inst.getOperand(OpNum - 1).isImm() &&
2281 Inst.getOperand(OpNum - 2).isReg() &&
2282 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2284 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2285 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2286 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2287 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2288 // It can be implemented as SWM16 or LWM16 instruction.
2289 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2291 Inst.setOpcode(NewOpcode);
2292 Instructions.push_back(Inst);
2296 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2297 SmallVectorImpl<MCInst> &Instructions) {
2298 unsigned PseudoOpcode = Inst.getOpcode();
2299 unsigned SrcReg = Inst.getOperand(0).getReg();
2300 unsigned TrgReg = Inst.getOperand(1).getReg();
2301 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2303 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2304 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2306 switch (PseudoOpcode) {
2309 AcceptsEquality = false;
2310 ReverseOrderSLT = false;
2311 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2312 ZeroSrcOpcode = Mips::BGTZ;
2313 ZeroTrgOpcode = Mips::BLTZ;
2317 AcceptsEquality = true;
2318 ReverseOrderSLT = true;
2319 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2320 ZeroSrcOpcode = Mips::BGEZ;
2321 ZeroTrgOpcode = Mips::BLEZ;
2325 AcceptsEquality = true;
2326 ReverseOrderSLT = false;
2327 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2328 ZeroSrcOpcode = Mips::BLEZ;
2329 ZeroTrgOpcode = Mips::BGEZ;
2333 AcceptsEquality = false;
2334 ReverseOrderSLT = true;
2335 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2336 ZeroSrcOpcode = Mips::BLTZ;
2337 ZeroTrgOpcode = Mips::BGTZ;
2340 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2344 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2345 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2346 if (IsSrcRegZero && IsTrgRegZero) {
2347 // FIXME: All of these Opcode-specific if's are needed for compatibility
2348 // with GAS' behaviour. However, they may not generate the most efficient
2349 // code in some circumstances.
2350 if (PseudoOpcode == Mips::BLT) {
2351 BranchInst.setOpcode(Mips::BLTZ);
2352 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2353 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2354 Instructions.push_back(BranchInst);
2357 if (PseudoOpcode == Mips::BLE) {
2358 BranchInst.setOpcode(Mips::BLEZ);
2359 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2360 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2361 Instructions.push_back(BranchInst);
2362 Warning(IDLoc, "branch is always taken");
2365 if (PseudoOpcode == Mips::BGE) {
2366 BranchInst.setOpcode(Mips::BGEZ);
2367 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2368 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2369 Instructions.push_back(BranchInst);
2370 Warning(IDLoc, "branch is always taken");
2373 if (PseudoOpcode == Mips::BGT) {
2374 BranchInst.setOpcode(Mips::BGTZ);
2375 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2376 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2377 Instructions.push_back(BranchInst);
2380 if (PseudoOpcode == Mips::BGTU) {
2381 BranchInst.setOpcode(Mips::BNE);
2382 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2383 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2384 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2385 Instructions.push_back(BranchInst);
2388 if (AcceptsEquality) {
2389 // If both registers are $0 and the pseudo-branch accepts equality, it
2390 // will always be taken, so we emit an unconditional branch.
2391 BranchInst.setOpcode(Mips::BEQ);
2392 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2393 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2394 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2395 Instructions.push_back(BranchInst);
2396 Warning(IDLoc, "branch is always taken");
2399 // If both registers are $0 and the pseudo-branch does not accept
2400 // equality, it will never be taken, so we don't have to emit anything.
2403 if (IsSrcRegZero || IsTrgRegZero) {
2404 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2405 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2406 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2407 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2408 // the pseudo-branch will never be taken, so we don't emit anything.
2409 // This only applies to unsigned pseudo-branches.
2412 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2413 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2414 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2415 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2416 // the pseudo-branch will always be taken, so we emit an unconditional
2418 // This only applies to unsigned pseudo-branches.
2419 BranchInst.setOpcode(Mips::BEQ);
2420 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2421 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2422 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2423 Instructions.push_back(BranchInst);
2424 Warning(IDLoc, "branch is always taken");
2428 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2429 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2430 // the pseudo-branch will be taken only when the non-zero register is
2431 // different from 0, so we emit a BNEZ.
2433 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2434 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2435 // the pseudo-branch will be taken only when the non-zero register is
2436 // equal to 0, so we emit a BEQZ.
2438 // Because only BLEU and BGEU branch on equality, we can use the
2439 // AcceptsEquality variable to decide when to emit the BEQZ.
2440 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2441 BranchInst.addOperand(
2442 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2443 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2444 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2445 Instructions.push_back(BranchInst);
2448 // If we have a signed pseudo-branch and one of the registers is $0,
2449 // we can use an appropriate compare-to-zero branch. We select which one
2450 // to use in the switch statement above.
2451 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2452 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2453 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2454 Instructions.push_back(BranchInst);
2458 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2459 // expansions. If it is not available, we return.
2460 unsigned ATRegNum = getATReg(IDLoc);
2464 warnIfNoMacro(IDLoc);
2466 // SLT fits well with 2 of our 4 pseudo-branches:
2467 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2468 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2469 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2470 // This is accomplished by using a BNEZ with the result of the SLT.
2472 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2473 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2474 // Because only BGE and BLE branch on equality, we can use the
2475 // AcceptsEquality variable to decide when to emit the BEQZ.
2476 // Note that the order of the SLT arguments doesn't change between
2479 // The same applies to the unsigned variants, except that SLTu is used
2482 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2483 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2484 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2485 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2486 Instructions.push_back(SetInst);
2488 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2489 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2490 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2491 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2492 Instructions.push_back(BranchInst);
2496 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2497 SmallVectorImpl<MCInst> &Instructions) {
2498 if (hasMips32r6() || hasMips64r6()) {
2499 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2503 warnIfNoMacro(IDLoc);
2505 const MCOperand &DstRegOp = Inst.getOperand(0);
2506 assert(DstRegOp.isReg() && "expected register operand kind");
2508 const MCOperand &SrcRegOp = Inst.getOperand(1);
2509 assert(SrcRegOp.isReg() && "expected register operand kind");
2511 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2512 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2514 unsigned DstReg = DstRegOp.getReg();
2515 unsigned SrcReg = SrcRegOp.getReg();
2516 int64_t OffsetValue = OffsetImmOp.getImm();
2518 // NOTE: We always need AT for ULHU, as it is always used as the source
2519 // register for one of the LBu's.
2520 unsigned ATReg = getATReg(IDLoc);
2524 // When the value of offset+1 does not fit in 16 bits, we have to load the
2525 // offset in AT, (D)ADDu the original source register (if there was one), and
2526 // then use AT as the source register for the 2 generated LBu's.
2527 bool LoadedOffsetInAT = false;
2528 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2529 LoadedOffsetInAT = true;
2531 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2532 IDLoc, Instructions))
2535 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2536 // because it will make our output more similar to GAS'. For example,
2537 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2538 // instead of just an "ori $1, $9, 32768".
2539 // NOTE: If there is no source register specified in the ULHU, the parser
2540 // will interpret it as $0.
2541 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2542 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2545 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2546 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2547 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2549 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2551 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2552 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2554 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2555 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2558 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2561 TmpInst.setOpcode(Mips::LBu);
2562 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2563 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2564 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2565 Instructions.push_back(TmpInst);
2568 TmpInst.setOpcode(Mips::LBu);
2569 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2570 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2571 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2572 Instructions.push_back(TmpInst);
2575 TmpInst.setOpcode(Mips::SLL);
2576 TmpInst.addOperand(MCOperand::createReg(SllReg));
2577 TmpInst.addOperand(MCOperand::createReg(SllReg));
2578 TmpInst.addOperand(MCOperand::createImm(8));
2579 Instructions.push_back(TmpInst);
2582 TmpInst.setOpcode(Mips::OR);
2583 TmpInst.addOperand(MCOperand::createReg(DstReg));
2584 TmpInst.addOperand(MCOperand::createReg(DstReg));
2585 TmpInst.addOperand(MCOperand::createReg(ATReg));
2586 Instructions.push_back(TmpInst);
2591 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2592 SmallVectorImpl<MCInst> &Instructions) {
2593 if (hasMips32r6() || hasMips64r6()) {
2594 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2598 const MCOperand &DstRegOp = Inst.getOperand(0);
2599 assert(DstRegOp.isReg() && "expected register operand kind");
2601 const MCOperand &SrcRegOp = Inst.getOperand(1);
2602 assert(SrcRegOp.isReg() && "expected register operand kind");
2604 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2605 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2607 unsigned SrcReg = SrcRegOp.getReg();
2608 int64_t OffsetValue = OffsetImmOp.getImm();
2611 // When the value of offset+3 does not fit in 16 bits, we have to load the
2612 // offset in AT, (D)ADDu the original source register (if there was one), and
2613 // then use AT as the source register for the generated LWL and LWR.
2614 bool LoadedOffsetInAT = false;
2615 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
2616 ATReg = getATReg(IDLoc);
2619 LoadedOffsetInAT = true;
2621 warnIfNoMacro(IDLoc);
2623 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2624 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 ULW, 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 FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2638 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
2640 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2641 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2643 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2644 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
2647 MCInst LeftLoadInst;
2648 LeftLoadInst.setOpcode(Mips::LWL);
2649 LeftLoadInst.addOperand(DstRegOp);
2650 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2651 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
2652 Instructions.push_back(LeftLoadInst);
2654 MCInst RightLoadInst;
2655 RightLoadInst.setOpcode(Mips::LWR);
2656 RightLoadInst.addOperand(DstRegOp);
2657 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
2658 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
2659 Instructions.push_back(RightLoadInst);
2664 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2665 SmallVectorImpl<MCInst> &Instructions) {
2667 if (hasShortDelaySlot) {
2668 NopInst.setOpcode(Mips::MOVE16_MM);
2669 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2670 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2672 NopInst.setOpcode(Mips::SLL);
2673 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2674 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2675 NopInst.addOperand(MCOperand::createImm(0));
2677 Instructions.push_back(NopInst);
2680 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2681 unsigned TrgReg, bool Is64Bit,
2682 SmallVectorImpl<MCInst> &Instructions) {
2684 AdduInst.setOpcode(Is64Bit ? Mips::DADDu : Mips::ADDu);
2685 AdduInst.addOperand(MCOperand::createReg(DstReg));
2686 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2687 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2688 Instructions.push_back(AdduInst);
2691 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2692 // As described by the Mips32r2 spec, the registers Rd and Rs for
2693 // jalr.hb must be different.
2694 unsigned Opcode = Inst.getOpcode();
2696 if (Opcode == Mips::JALR_HB &&
2697 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2698 return Match_RequiresDifferentSrcAndDst;
2700 return Match_Success;
2703 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2704 OperandVector &Operands,
2706 uint64_t &ErrorInfo,
2707 bool MatchingInlineAsm) {
2710 SmallVector<MCInst, 8> Instructions;
2711 unsigned MatchResult =
2712 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2714 switch (MatchResult) {
2715 case Match_Success: {
2716 if (processInstruction(Inst, IDLoc, Instructions))
2718 for (unsigned i = 0; i < Instructions.size(); i++)
2719 Out.EmitInstruction(Instructions[i], STI);
2722 case Match_MissingFeature:
2723 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2725 case Match_InvalidOperand: {
2726 SMLoc ErrorLoc = IDLoc;
2727 if (ErrorInfo != ~0ULL) {
2728 if (ErrorInfo >= Operands.size())
2729 return Error(IDLoc, "too few operands for instruction");
2731 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2732 if (ErrorLoc == SMLoc())
2736 return Error(ErrorLoc, "invalid operand for instruction");
2738 case Match_MnemonicFail:
2739 return Error(IDLoc, "invalid instruction");
2740 case Match_RequiresDifferentSrcAndDst:
2741 return Error(IDLoc, "source and destination must be different");
2744 llvm_unreachable("Implement any new match types added!");
2747 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2748 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2749 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2750 ") without \".set noat\"");
2753 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2754 if (!AssemblerOptions.back()->isMacro())
2755 Warning(Loc, "macro instruction expanded into multiple instructions");
2759 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2760 SMRange Range, bool ShowColors) {
2761 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2762 Range, SMFixIt(Range, FixMsg),
2766 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2769 CC = StringSwitch<unsigned>(Name)
2805 if (!(isABI_N32() || isABI_N64()))
2808 if (12 <= CC && CC <= 15) {
2809 // Name is one of t4-t7
2810 AsmToken RegTok = getLexer().peekTok();
2811 SMRange RegRange = RegTok.getLocRange();
2813 StringRef FixedName = StringSwitch<StringRef>(Name)
2819 assert(FixedName != "" && "Register name is not one of t4-t7.");
2821 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2822 "Did you mean $" + FixedName + "?", RegRange);
2825 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2826 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2827 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2828 if (8 <= CC && CC <= 11)
2832 CC = StringSwitch<unsigned>(Name)
2844 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2847 CC = StringSwitch<unsigned>(Name)
2848 .Case("hwr_cpunum", 0)
2849 .Case("hwr_synci_step", 1)
2851 .Case("hwr_ccres", 3)
2852 .Case("hwr_ulr", 29)
2858 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2860 if (Name[0] == 'f') {
2861 StringRef NumString = Name.substr(1);
2863 if (NumString.getAsInteger(10, IntVal))
2864 return -1; // This is not an integer.
2865 if (IntVal > 31) // Maximum index for fpu register.
2872 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2874 if (Name.startswith("fcc")) {
2875 StringRef NumString = Name.substr(3);
2877 if (NumString.getAsInteger(10, IntVal))
2878 return -1; // This is not an integer.
2879 if (IntVal > 7) // There are only 8 fcc registers.
2886 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2888 if (Name.startswith("ac")) {
2889 StringRef NumString = Name.substr(2);
2891 if (NumString.getAsInteger(10, IntVal))
2892 return -1; // This is not an integer.
2893 if (IntVal > 3) // There are only 3 acc registers.
2900 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2903 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2912 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2915 CC = StringSwitch<unsigned>(Name)
2918 .Case("msaaccess", 2)
2920 .Case("msamodify", 4)
2921 .Case("msarequest", 5)
2923 .Case("msaunmap", 7)
2929 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2930 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2932 reportParseError(Loc,
2933 "pseudo-instruction requires $at, which is not available");
2936 unsigned AT = getReg(
2937 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2941 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2942 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2945 unsigned MipsAsmParser::getGPR(int RegNo) {
2946 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2950 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2952 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2955 return getReg(RegClass, RegNum);
2958 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2959 MCAsmParser &Parser = getParser();
2960 DEBUG(dbgs() << "parseOperand\n");
2962 // Check if the current operand has a custom associated parser, if so, try to
2963 // custom parse the operand, or fallback to the general approach.
2964 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2965 if (ResTy == MatchOperand_Success)
2967 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2968 // there was a match, but an error occurred, in which case, just return that
2969 // the operand parsing failed.
2970 if (ResTy == MatchOperand_ParseFail)
2973 DEBUG(dbgs() << ".. Generic Parser\n");
2975 switch (getLexer().getKind()) {
2977 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2979 case AsmToken::Dollar: {
2980 // Parse the register.
2981 SMLoc S = Parser.getTok().getLoc();
2983 // Almost all registers have been parsed by custom parsers. There is only
2984 // one exception to this. $zero (and it's alias $0) will reach this point
2985 // for div, divu, and similar instructions because it is not an operand
2986 // to the instruction definition but an explicit register. Special case
2987 // this situation for now.
2988 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2991 // Maybe it is a symbol reference.
2992 StringRef Identifier;
2993 if (Parser.parseIdentifier(Identifier))
2996 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2997 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2998 // Otherwise create a symbol reference.
3000 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3002 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3005 // Else drop to expression parsing.
3006 case AsmToken::LParen:
3007 case AsmToken::Minus:
3008 case AsmToken::Plus:
3009 case AsmToken::Integer:
3010 case AsmToken::Tilde:
3011 case AsmToken::String: {
3012 DEBUG(dbgs() << ".. generic integer\n");
3013 OperandMatchResultTy ResTy = parseImm(Operands);
3014 return ResTy != MatchOperand_Success;
3016 case AsmToken::Percent: {
3017 // It is a symbol reference or constant expression.
3018 const MCExpr *IdVal;
3019 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3020 if (parseRelocOperand(IdVal))
3023 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3025 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3027 } // case AsmToken::Percent
3028 } // switch(getLexer().getKind())
3032 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3033 StringRef RelocStr) {
3035 // Check the type of the expression.
3036 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3037 // It's a constant, evaluate reloc value.
3039 switch (getVariantKind(RelocStr)) {
3040 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3041 // Get the 1st 16-bits.
3042 Val = MCE->getValue() & 0xffff;
3044 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3045 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3046 // 16 bits being negative.
3047 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3049 case MCSymbolRefExpr::VK_Mips_HIGHER:
3050 // Get the 3rd 16-bits.
3051 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3053 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3054 // Get the 4th 16-bits.
3055 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3058 report_fatal_error("unsupported reloc value");
3060 return MCConstantExpr::create(Val, getContext());
3063 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3064 // It's a symbol, create a symbolic expression from the symbol.
3065 const MCSymbol *Symbol = &MSRE->getSymbol();
3066 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3067 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3071 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3072 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3074 // Try to create target expression.
3075 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3076 return MipsMCExpr::create(VK, Expr, getContext());
3078 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3079 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3080 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3084 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3085 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3086 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3089 // Just return the original expression.
3093 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3095 switch (Expr->getKind()) {
3096 case MCExpr::Constant:
3098 case MCExpr::SymbolRef:
3099 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3100 case MCExpr::Binary:
3101 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3102 if (!isEvaluated(BE->getLHS()))
3104 return isEvaluated(BE->getRHS());
3107 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3108 case MCExpr::Target:
3114 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3115 MCAsmParser &Parser = getParser();
3116 Parser.Lex(); // Eat the % token.
3117 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3118 if (Tok.isNot(AsmToken::Identifier))
3121 std::string Str = Tok.getIdentifier();
3123 Parser.Lex(); // Eat the identifier.
3124 // Now make an expression from the rest of the operand.
3125 const MCExpr *IdVal;
3128 if (getLexer().getKind() == AsmToken::LParen) {
3130 Parser.Lex(); // Eat the '(' token.
3131 if (getLexer().getKind() == AsmToken::Percent) {
3132 Parser.Lex(); // Eat the % token.
3133 const AsmToken &nextTok = Parser.getTok();
3134 if (nextTok.isNot(AsmToken::Identifier))
3137 Str += nextTok.getIdentifier();
3138 Parser.Lex(); // Eat the identifier.
3139 if (getLexer().getKind() != AsmToken::LParen)
3144 if (getParser().parseParenExpression(IdVal, EndLoc))
3147 while (getLexer().getKind() == AsmToken::RParen)
3148 Parser.Lex(); // Eat the ')' token.
3151 return true; // Parenthesis must follow the relocation operand.
3153 Res = evaluateRelocExpr(IdVal, Str);
3157 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3159 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3160 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3161 if (ResTy == MatchOperand_Success) {
3162 assert(Operands.size() == 1);
3163 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3164 StartLoc = Operand.getStartLoc();
3165 EndLoc = Operand.getEndLoc();
3167 // AFAIK, we only support numeric registers and named GPR's in CFI
3169 // Don't worry about eating tokens before failing. Using an unrecognised
3170 // register is a parse error.
3171 if (Operand.isGPRAsmReg()) {
3172 // Resolve to GPR32 or GPR64 appropriately.
3173 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3176 return (RegNo == (unsigned)-1);
3179 assert(Operands.size() == 0);
3180 return (RegNo == (unsigned)-1);
3183 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3184 MCAsmParser &Parser = getParser();
3187 unsigned NumOfLParen = 0;
3189 while (getLexer().getKind() == AsmToken::LParen) {
3194 switch (getLexer().getKind()) {
3197 case AsmToken::Identifier:
3198 case AsmToken::LParen:
3199 case AsmToken::Integer:
3200 case AsmToken::Minus:
3201 case AsmToken::Plus:
3203 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3205 Result = (getParser().parseExpression(Res));
3206 while (getLexer().getKind() == AsmToken::RParen)
3209 case AsmToken::Percent:
3210 Result = parseRelocOperand(Res);
3215 MipsAsmParser::OperandMatchResultTy
3216 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3217 MCAsmParser &Parser = getParser();
3218 DEBUG(dbgs() << "parseMemOperand\n");
3219 const MCExpr *IdVal = nullptr;
3221 bool isParenExpr = false;
3222 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3223 // First operand is the offset.
3224 S = Parser.getTok().getLoc();
3226 if (getLexer().getKind() == AsmToken::LParen) {
3231 if (getLexer().getKind() != AsmToken::Dollar) {
3232 if (parseMemOffset(IdVal, isParenExpr))
3233 return MatchOperand_ParseFail;
3235 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3236 if (Tok.isNot(AsmToken::LParen)) {
3237 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3238 if (Mnemonic.getToken() == "la") {
3240 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3241 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3242 return MatchOperand_Success;
3244 if (Tok.is(AsmToken::EndOfStatement)) {
3246 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3248 // Zero register assumed, add a memory operand with ZERO as its base.
3249 // "Base" will be managed by k_Memory.
3250 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3253 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3254 return MatchOperand_Success;
3256 Error(Parser.getTok().getLoc(), "'(' expected");
3257 return MatchOperand_ParseFail;
3260 Parser.Lex(); // Eat the '(' token.
3263 Res = parseAnyRegister(Operands);
3264 if (Res != MatchOperand_Success)
3267 if (Parser.getTok().isNot(AsmToken::RParen)) {
3268 Error(Parser.getTok().getLoc(), "')' expected");
3269 return MatchOperand_ParseFail;
3272 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3274 Parser.Lex(); // Eat the ')' token.
3277 IdVal = MCConstantExpr::create(0, getContext());
3279 // Replace the register operand with the memory operand.
3280 std::unique_ptr<MipsOperand> op(
3281 static_cast<MipsOperand *>(Operands.back().release()));
3282 // Remove the register from the operands.
3283 // "op" will be managed by k_Memory.
3284 Operands.pop_back();
3285 // Add the memory operand.
3286 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3288 if (IdVal->evaluateAsAbsolute(Imm))
3289 IdVal = MCConstantExpr::create(Imm, getContext());
3290 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3291 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3295 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3296 return MatchOperand_Success;
3299 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3300 MCAsmParser &Parser = getParser();
3301 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3303 SMLoc S = Parser.getTok().getLoc();
3305 if (Sym->isVariable())
3306 Expr = Sym->getVariableValue();
3309 if (Expr->getKind() == MCExpr::SymbolRef) {
3310 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3311 StringRef DefSymbol = Ref->getSymbol().getName();
3312 if (DefSymbol.startswith("$")) {
3313 OperandMatchResultTy ResTy =
3314 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3315 if (ResTy == MatchOperand_Success) {
3318 } else if (ResTy == MatchOperand_ParseFail)
3319 llvm_unreachable("Should never ParseFail");
3322 } else if (Expr->getKind() == MCExpr::Constant) {
3324 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3326 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3333 MipsAsmParser::OperandMatchResultTy
3334 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3335 StringRef Identifier,
3337 int Index = matchCPURegisterName(Identifier);
3339 Operands.push_back(MipsOperand::createGPRReg(
3340 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3341 return MatchOperand_Success;
3344 Index = matchHWRegsRegisterName(Identifier);
3346 Operands.push_back(MipsOperand::createHWRegsReg(
3347 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3348 return MatchOperand_Success;
3351 Index = matchFPURegisterName(Identifier);
3353 Operands.push_back(MipsOperand::createFGRReg(
3354 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3355 return MatchOperand_Success;
3358 Index = matchFCCRegisterName(Identifier);
3360 Operands.push_back(MipsOperand::createFCCReg(
3361 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3362 return MatchOperand_Success;
3365 Index = matchACRegisterName(Identifier);
3367 Operands.push_back(MipsOperand::createACCReg(
3368 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3369 return MatchOperand_Success;
3372 Index = matchMSA128RegisterName(Identifier);
3374 Operands.push_back(MipsOperand::createMSA128Reg(
3375 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3376 return MatchOperand_Success;
3379 Index = matchMSA128CtrlRegisterName(Identifier);
3381 Operands.push_back(MipsOperand::createMSACtrlReg(
3382 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3383 return MatchOperand_Success;
3386 return MatchOperand_NoMatch;
3389 MipsAsmParser::OperandMatchResultTy
3390 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3391 MCAsmParser &Parser = getParser();
3392 auto Token = Parser.getLexer().peekTok(false);
3394 if (Token.is(AsmToken::Identifier)) {
3395 DEBUG(dbgs() << ".. identifier\n");
3396 StringRef Identifier = Token.getIdentifier();
3397 OperandMatchResultTy ResTy =
3398 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3400 } else if (Token.is(AsmToken::Integer)) {
3401 DEBUG(dbgs() << ".. integer\n");
3402 Operands.push_back(MipsOperand::createNumericReg(
3403 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3405 return MatchOperand_Success;
3408 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3410 return MatchOperand_NoMatch;
3413 MipsAsmParser::OperandMatchResultTy
3414 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3415 MCAsmParser &Parser = getParser();
3416 DEBUG(dbgs() << "parseAnyRegister\n");
3418 auto Token = Parser.getTok();
3420 SMLoc S = Token.getLoc();
3422 if (Token.isNot(AsmToken::Dollar)) {
3423 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3424 if (Token.is(AsmToken::Identifier)) {
3425 if (searchSymbolAlias(Operands))
3426 return MatchOperand_Success;
3428 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3429 return MatchOperand_NoMatch;
3431 DEBUG(dbgs() << ".. $\n");
3433 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3434 if (ResTy == MatchOperand_Success) {
3436 Parser.Lex(); // identifier
3441 MipsAsmParser::OperandMatchResultTy
3442 MipsAsmParser::parseImm(OperandVector &Operands) {
3443 MCAsmParser &Parser = getParser();
3444 switch (getLexer().getKind()) {
3446 return MatchOperand_NoMatch;
3447 case AsmToken::LParen:
3448 case AsmToken::Minus:
3449 case AsmToken::Plus:
3450 case AsmToken::Integer:
3451 case AsmToken::Tilde:
3452 case AsmToken::String:
3456 const MCExpr *IdVal;
3457 SMLoc S = Parser.getTok().getLoc();
3458 if (getParser().parseExpression(IdVal))
3459 return MatchOperand_ParseFail;
3461 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3462 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3463 return MatchOperand_Success;
3466 MipsAsmParser::OperandMatchResultTy
3467 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3468 MCAsmParser &Parser = getParser();
3469 DEBUG(dbgs() << "parseJumpTarget\n");
3471 SMLoc S = getLexer().getLoc();
3473 // Integers and expressions are acceptable
3474 OperandMatchResultTy ResTy = parseImm(Operands);
3475 if (ResTy != MatchOperand_NoMatch)
3478 // Registers are a valid target and have priority over symbols.
3479 ResTy = parseAnyRegister(Operands);
3480 if (ResTy != MatchOperand_NoMatch)
3483 const MCExpr *Expr = nullptr;
3484 if (Parser.parseExpression(Expr)) {
3485 // We have no way of knowing if a symbol was consumed so we must ParseFail
3486 return MatchOperand_ParseFail;
3489 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3490 return MatchOperand_Success;
3493 MipsAsmParser::OperandMatchResultTy
3494 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3495 MCAsmParser &Parser = getParser();
3496 const MCExpr *IdVal;
3497 // If the first token is '$' we may have register operand.
3498 if (Parser.getTok().is(AsmToken::Dollar))
3499 return MatchOperand_NoMatch;
3500 SMLoc S = Parser.getTok().getLoc();
3501 if (getParser().parseExpression(IdVal))
3502 return MatchOperand_ParseFail;
3503 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3504 assert(MCE && "Unexpected MCExpr type.");
3505 int64_t Val = MCE->getValue();
3506 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3507 Operands.push_back(MipsOperand::CreateImm(
3508 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3509 return MatchOperand_Success;
3512 MipsAsmParser::OperandMatchResultTy
3513 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3514 MCAsmParser &Parser = getParser();
3515 switch (getLexer().getKind()) {
3517 return MatchOperand_NoMatch;
3518 case AsmToken::LParen:
3519 case AsmToken::Plus:
3520 case AsmToken::Minus:
3521 case AsmToken::Integer:
3526 SMLoc S = Parser.getTok().getLoc();
3528 if (getParser().parseExpression(Expr))
3529 return MatchOperand_ParseFail;
3532 if (!Expr->evaluateAsAbsolute(Val)) {
3533 Error(S, "expected immediate value");
3534 return MatchOperand_ParseFail;
3537 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3538 // and because the CPU always adds one to the immediate field, the allowed
3539 // range becomes 1..4. We'll only check the range here and will deal
3540 // with the addition/subtraction when actually decoding/encoding
3542 if (Val < 1 || Val > 4) {
3543 Error(S, "immediate not in range (1..4)");
3544 return MatchOperand_ParseFail;
3548 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3549 return MatchOperand_Success;
3552 MipsAsmParser::OperandMatchResultTy
3553 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3554 MCAsmParser &Parser = getParser();
3555 SmallVector<unsigned, 10> Regs;
3557 unsigned PrevReg = Mips::NoRegister;
3558 bool RegRange = false;
3559 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3561 if (Parser.getTok().isNot(AsmToken::Dollar))
3562 return MatchOperand_ParseFail;
3564 SMLoc S = Parser.getTok().getLoc();
3565 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3566 SMLoc E = getLexer().getLoc();
3567 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3568 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3570 // Remove last register operand because registers from register range
3571 // should be inserted first.
3572 if (RegNo == Mips::RA) {
3573 Regs.push_back(RegNo);
3575 unsigned TmpReg = PrevReg + 1;
3576 while (TmpReg <= RegNo) {
3577 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3578 Error(E, "invalid register operand");
3579 return MatchOperand_ParseFail;
3583 Regs.push_back(TmpReg++);
3589 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3590 (RegNo != Mips::RA)) {
3591 Error(E, "$16 or $31 expected");
3592 return MatchOperand_ParseFail;
3593 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3594 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3595 Error(E, "invalid register operand");
3596 return MatchOperand_ParseFail;
3597 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3598 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3599 Error(E, "consecutive register numbers expected");
3600 return MatchOperand_ParseFail;
3603 Regs.push_back(RegNo);
3606 if (Parser.getTok().is(AsmToken::Minus))
3609 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3610 !Parser.getTok().isNot(AsmToken::Comma)) {
3611 Error(E, "',' or '-' expected");
3612 return MatchOperand_ParseFail;
3615 Lex(); // Consume comma or minus
3616 if (Parser.getTok().isNot(AsmToken::Dollar))
3622 SMLoc E = Parser.getTok().getLoc();
3623 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3624 parseMemOperand(Operands);
3625 return MatchOperand_Success;
3628 MipsAsmParser::OperandMatchResultTy
3629 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3630 MCAsmParser &Parser = getParser();
3632 SMLoc S = Parser.getTok().getLoc();
3633 if (parseAnyRegister(Operands) != MatchOperand_Success)
3634 return MatchOperand_ParseFail;
3636 SMLoc E = Parser.getTok().getLoc();
3637 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3638 unsigned Reg = Op.getGPR32Reg();
3639 Operands.pop_back();
3640 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3641 return MatchOperand_Success;
3644 MipsAsmParser::OperandMatchResultTy
3645 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3646 MCAsmParser &Parser = getParser();
3647 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3648 SmallVector<unsigned, 10> Regs;
3650 if (Parser.getTok().isNot(AsmToken::Dollar))
3651 return MatchOperand_ParseFail;
3653 SMLoc S = Parser.getTok().getLoc();
3655 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3656 return MatchOperand_ParseFail;
3658 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3659 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3660 Regs.push_back(RegNo);
3662 SMLoc E = Parser.getTok().getLoc();
3663 if (Parser.getTok().isNot(AsmToken::Comma)) {
3664 Error(E, "',' expected");
3665 return MatchOperand_ParseFail;
3671 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3672 return MatchOperand_ParseFail;
3674 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3675 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3676 Regs.push_back(RegNo);
3678 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3680 return MatchOperand_Success;
3683 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3685 MCSymbolRefExpr::VariantKind VK =
3686 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3687 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3688 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3689 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3690 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3691 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3692 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3693 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3694 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3695 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3696 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3697 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3698 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3699 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3700 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3701 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3702 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3703 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3704 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3705 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3706 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3707 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3708 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3709 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3710 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3711 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3712 .Default(MCSymbolRefExpr::VK_None);
3714 assert(VK != MCSymbolRefExpr::VK_None);
3719 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3721 /// ::= '(', register, ')'
3722 /// handle it before we iterate so we don't get tripped up by the lack of
3724 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3725 MCAsmParser &Parser = getParser();
3726 if (getLexer().is(AsmToken::LParen)) {
3728 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3730 if (parseOperand(Operands, Name)) {
3731 SMLoc Loc = getLexer().getLoc();
3732 Parser.eatToEndOfStatement();
3733 return Error(Loc, "unexpected token in argument list");
3735 if (Parser.getTok().isNot(AsmToken::RParen)) {
3736 SMLoc Loc = getLexer().getLoc();
3737 Parser.eatToEndOfStatement();
3738 return Error(Loc, "unexpected token, expected ')'");
3741 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3747 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3748 /// either one of these.
3749 /// ::= '[', register, ']'
3750 /// ::= '[', integer, ']'
3751 /// handle it before we iterate so we don't get tripped up by the lack of
3753 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3754 OperandVector &Operands) {
3755 MCAsmParser &Parser = getParser();
3756 if (getLexer().is(AsmToken::LBrac)) {
3758 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3760 if (parseOperand(Operands, Name)) {
3761 SMLoc Loc = getLexer().getLoc();
3762 Parser.eatToEndOfStatement();
3763 return Error(Loc, "unexpected token in argument list");
3765 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3766 SMLoc Loc = getLexer().getLoc();
3767 Parser.eatToEndOfStatement();
3768 return Error(Loc, "unexpected token, expected ']'");
3771 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3777 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3778 SMLoc NameLoc, OperandVector &Operands) {
3779 MCAsmParser &Parser = getParser();
3780 DEBUG(dbgs() << "ParseInstruction\n");
3782 // We have reached first instruction, module directive are now forbidden.
3783 getTargetStreamer().forbidModuleDirective();
3785 // Check if we have valid mnemonic
3786 if (!mnemonicIsValid(Name, 0)) {
3787 Parser.eatToEndOfStatement();
3788 return Error(NameLoc, "unknown instruction");
3790 // First operand in MCInst is instruction mnemonic.
3791 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3793 // Read the remaining operands.
3794 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3795 // Read the first operand.
3796 if (parseOperand(Operands, Name)) {
3797 SMLoc Loc = getLexer().getLoc();
3798 Parser.eatToEndOfStatement();
3799 return Error(Loc, "unexpected token in argument list");
3801 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3803 // AFAIK, parenthesis suffixes are never on the first operand
3805 while (getLexer().is(AsmToken::Comma)) {
3806 Parser.Lex(); // Eat the comma.
3807 // Parse and remember the operand.
3808 if (parseOperand(Operands, Name)) {
3809 SMLoc Loc = getLexer().getLoc();
3810 Parser.eatToEndOfStatement();
3811 return Error(Loc, "unexpected token in argument list");
3813 // Parse bracket and parenthesis suffixes before we iterate
3814 if (getLexer().is(AsmToken::LBrac)) {
3815 if (parseBracketSuffix(Name, Operands))
3817 } else if (getLexer().is(AsmToken::LParen) &&
3818 parseParenSuffix(Name, Operands))
3822 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3823 SMLoc Loc = getLexer().getLoc();
3824 Parser.eatToEndOfStatement();
3825 return Error(Loc, "unexpected token in argument list");
3827 Parser.Lex(); // Consume the EndOfStatement.
3831 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3832 MCAsmParser &Parser = getParser();
3833 SMLoc Loc = getLexer().getLoc();
3834 Parser.eatToEndOfStatement();
3835 return Error(Loc, ErrorMsg);
3838 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3839 return Error(Loc, ErrorMsg);
3842 bool MipsAsmParser::parseSetNoAtDirective() {
3843 MCAsmParser &Parser = getParser();
3844 // Line should look like: ".set noat".
3846 // Set the $at register to $0.
3847 AssemblerOptions.back()->setATRegIndex(0);
3849 Parser.Lex(); // Eat "noat".
3851 // If this is not the end of the statement, report an error.
3852 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3853 reportParseError("unexpected token, expected end of statement");
3857 getTargetStreamer().emitDirectiveSetNoAt();
3858 Parser.Lex(); // Consume the EndOfStatement.
3862 bool MipsAsmParser::parseSetAtDirective() {
3863 // Line can be: ".set at", which sets $at to $1
3864 // or ".set at=$reg", which sets $at to $reg.
3865 MCAsmParser &Parser = getParser();
3866 Parser.Lex(); // Eat "at".
3868 if (getLexer().is(AsmToken::EndOfStatement)) {
3869 // No register was specified, so we set $at to $1.
3870 AssemblerOptions.back()->setATRegIndex(1);
3872 getTargetStreamer().emitDirectiveSetAt();
3873 Parser.Lex(); // Consume the EndOfStatement.
3877 if (getLexer().isNot(AsmToken::Equal)) {
3878 reportParseError("unexpected token, expected equals sign");
3881 Parser.Lex(); // Eat "=".
3883 if (getLexer().isNot(AsmToken::Dollar)) {
3884 if (getLexer().is(AsmToken::EndOfStatement)) {
3885 reportParseError("no register specified");
3888 reportParseError("unexpected token, expected dollar sign '$'");
3892 Parser.Lex(); // Eat "$".
3894 // Find out what "reg" is.
3896 const AsmToken &Reg = Parser.getTok();
3897 if (Reg.is(AsmToken::Identifier)) {
3898 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3899 } else if (Reg.is(AsmToken::Integer)) {
3900 AtRegNo = Reg.getIntVal();
3902 reportParseError("unexpected token, expected identifier or integer");
3906 // Check if $reg is a valid register. If it is, set $at to $reg.
3907 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3908 reportParseError("invalid register");
3911 Parser.Lex(); // Eat "reg".
3913 // If this is not the end of the statement, report an error.
3914 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3915 reportParseError("unexpected token, expected end of statement");
3919 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3921 Parser.Lex(); // Consume the EndOfStatement.
3925 bool MipsAsmParser::parseSetReorderDirective() {
3926 MCAsmParser &Parser = getParser();
3928 // If this is not the end of the statement, report an error.
3929 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3930 reportParseError("unexpected token, expected end of statement");
3933 AssemblerOptions.back()->setReorder();
3934 getTargetStreamer().emitDirectiveSetReorder();
3935 Parser.Lex(); // Consume the EndOfStatement.
3939 bool MipsAsmParser::parseSetNoReorderDirective() {
3940 MCAsmParser &Parser = getParser();
3942 // If this is not the end of the statement, report an error.
3943 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3944 reportParseError("unexpected token, expected end of statement");
3947 AssemblerOptions.back()->setNoReorder();
3948 getTargetStreamer().emitDirectiveSetNoReorder();
3949 Parser.Lex(); // Consume the EndOfStatement.
3953 bool MipsAsmParser::parseSetMacroDirective() {
3954 MCAsmParser &Parser = getParser();
3956 // If this is not the end of the statement, report an error.
3957 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3958 reportParseError("unexpected token, expected end of statement");
3961 AssemblerOptions.back()->setMacro();
3962 getTargetStreamer().emitDirectiveSetMacro();
3963 Parser.Lex(); // Consume the EndOfStatement.
3967 bool MipsAsmParser::parseSetNoMacroDirective() {
3968 MCAsmParser &Parser = getParser();
3970 // If this is not the end of the statement, report an error.
3971 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3972 reportParseError("unexpected token, expected end of statement");
3975 if (AssemblerOptions.back()->isReorder()) {
3976 reportParseError("`noreorder' must be set before `nomacro'");
3979 AssemblerOptions.back()->setNoMacro();
3980 getTargetStreamer().emitDirectiveSetNoMacro();
3981 Parser.Lex(); // Consume the EndOfStatement.
3985 bool MipsAsmParser::parseSetMsaDirective() {
3986 MCAsmParser &Parser = getParser();
3989 // If this is not the end of the statement, report an error.
3990 if (getLexer().isNot(AsmToken::EndOfStatement))
3991 return reportParseError("unexpected token, expected end of statement");
3993 setFeatureBits(Mips::FeatureMSA, "msa");
3994 getTargetStreamer().emitDirectiveSetMsa();
3998 bool MipsAsmParser::parseSetNoMsaDirective() {
3999 MCAsmParser &Parser = getParser();
4002 // If this is not the end of the statement, report an error.
4003 if (getLexer().isNot(AsmToken::EndOfStatement))
4004 return reportParseError("unexpected token, expected end of statement");
4006 clearFeatureBits(Mips::FeatureMSA, "msa");
4007 getTargetStreamer().emitDirectiveSetNoMsa();
4011 bool MipsAsmParser::parseSetNoDspDirective() {
4012 MCAsmParser &Parser = getParser();
4013 Parser.Lex(); // Eat "nodsp".
4015 // If this is not the end of the statement, report an error.
4016 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4017 reportParseError("unexpected token, expected end of statement");
4021 clearFeatureBits(Mips::FeatureDSP, "dsp");
4022 getTargetStreamer().emitDirectiveSetNoDsp();
4026 bool MipsAsmParser::parseSetMips16Directive() {
4027 MCAsmParser &Parser = getParser();
4028 Parser.Lex(); // Eat "mips16".
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");
4036 setFeatureBits(Mips::FeatureMips16, "mips16");
4037 getTargetStreamer().emitDirectiveSetMips16();
4038 Parser.Lex(); // Consume the EndOfStatement.
4042 bool MipsAsmParser::parseSetNoMips16Directive() {
4043 MCAsmParser &Parser = getParser();
4044 Parser.Lex(); // Eat "nomips16".
4046 // If this is not the end of the statement, report an error.
4047 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4048 reportParseError("unexpected token, expected end of statement");
4052 clearFeatureBits(Mips::FeatureMips16, "mips16");
4053 getTargetStreamer().emitDirectiveSetNoMips16();
4054 Parser.Lex(); // Consume the EndOfStatement.
4058 bool MipsAsmParser::parseSetFpDirective() {
4059 MCAsmParser &Parser = getParser();
4060 MipsABIFlagsSection::FpABIKind FpAbiVal;
4061 // Line can be: .set fp=32
4064 Parser.Lex(); // Eat fp token
4065 AsmToken Tok = Parser.getTok();
4066 if (Tok.isNot(AsmToken::Equal)) {
4067 reportParseError("unexpected token, expected equals sign '='");
4070 Parser.Lex(); // Eat '=' token.
4071 Tok = Parser.getTok();
4073 if (!parseFpABIValue(FpAbiVal, ".set"))
4076 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4077 reportParseError("unexpected token, expected end of statement");
4080 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4081 Parser.Lex(); // Consume the EndOfStatement.
4085 bool MipsAsmParser::parseSetPopDirective() {
4086 MCAsmParser &Parser = getParser();
4087 SMLoc Loc = getLexer().getLoc();
4090 if (getLexer().isNot(AsmToken::EndOfStatement))
4091 return reportParseError("unexpected token, expected end of statement");
4093 // Always keep an element on the options "stack" to prevent the user
4094 // from changing the initial options. This is how we remember them.
4095 if (AssemblerOptions.size() == 2)
4096 return reportParseError(Loc, ".set pop with no .set push");
4098 AssemblerOptions.pop_back();
4099 setAvailableFeatures(
4100 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4101 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4103 getTargetStreamer().emitDirectiveSetPop();
4107 bool MipsAsmParser::parseSetPushDirective() {
4108 MCAsmParser &Parser = getParser();
4110 if (getLexer().isNot(AsmToken::EndOfStatement))
4111 return reportParseError("unexpected token, expected end of statement");
4113 // Create a copy of the current assembler options environment and push it.
4114 AssemblerOptions.push_back(
4115 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4117 getTargetStreamer().emitDirectiveSetPush();
4121 bool MipsAsmParser::parseSetSoftFloatDirective() {
4122 MCAsmParser &Parser = getParser();
4124 if (getLexer().isNot(AsmToken::EndOfStatement))
4125 return reportParseError("unexpected token, expected end of statement");
4127 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4128 getTargetStreamer().emitDirectiveSetSoftFloat();
4132 bool MipsAsmParser::parseSetHardFloatDirective() {
4133 MCAsmParser &Parser = getParser();
4135 if (getLexer().isNot(AsmToken::EndOfStatement))
4136 return reportParseError("unexpected token, expected end of statement");
4138 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4139 getTargetStreamer().emitDirectiveSetHardFloat();
4143 bool MipsAsmParser::parseSetAssignment() {
4145 const MCExpr *Value;
4146 MCAsmParser &Parser = getParser();
4148 if (Parser.parseIdentifier(Name))
4149 reportParseError("expected identifier after .set");
4151 if (getLexer().isNot(AsmToken::Comma))
4152 return reportParseError("unexpected token, expected comma");
4155 if (Parser.parseExpression(Value))
4156 return reportParseError("expected valid expression after comma");
4158 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4159 Sym->setVariableValue(Value);
4164 bool MipsAsmParser::parseSetMips0Directive() {
4165 MCAsmParser &Parser = getParser();
4167 if (getLexer().isNot(AsmToken::EndOfStatement))
4168 return reportParseError("unexpected token, expected end of statement");
4170 // Reset assembler options to their initial values.
4171 setAvailableFeatures(
4172 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4173 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4174 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4176 getTargetStreamer().emitDirectiveSetMips0();
4180 bool MipsAsmParser::parseSetArchDirective() {
4181 MCAsmParser &Parser = getParser();
4183 if (getLexer().isNot(AsmToken::Equal))
4184 return reportParseError("unexpected token, expected equals sign");
4188 if (Parser.parseIdentifier(Arch))
4189 return reportParseError("expected arch identifier");
4191 StringRef ArchFeatureName =
4192 StringSwitch<StringRef>(Arch)
4193 .Case("mips1", "mips1")
4194 .Case("mips2", "mips2")
4195 .Case("mips3", "mips3")
4196 .Case("mips4", "mips4")
4197 .Case("mips5", "mips5")
4198 .Case("mips32", "mips32")
4199 .Case("mips32r2", "mips32r2")
4200 .Case("mips32r3", "mips32r3")
4201 .Case("mips32r5", "mips32r5")
4202 .Case("mips32r6", "mips32r6")
4203 .Case("mips64", "mips64")
4204 .Case("mips64r2", "mips64r2")
4205 .Case("mips64r3", "mips64r3")
4206 .Case("mips64r5", "mips64r5")
4207 .Case("mips64r6", "mips64r6")
4208 .Case("cnmips", "cnmips")
4209 .Case("r4000", "mips3") // This is an implementation of Mips3.
4212 if (ArchFeatureName.empty())
4213 return reportParseError("unsupported architecture");
4215 selectArch(ArchFeatureName);
4216 getTargetStreamer().emitDirectiveSetArch(Arch);
4220 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4221 MCAsmParser &Parser = getParser();
4223 if (getLexer().isNot(AsmToken::EndOfStatement))
4224 return reportParseError("unexpected token, expected end of statement");
4228 llvm_unreachable("Unimplemented feature");
4229 case Mips::FeatureDSP:
4230 setFeatureBits(Mips::FeatureDSP, "dsp");
4231 getTargetStreamer().emitDirectiveSetDsp();
4233 case Mips::FeatureMicroMips:
4234 getTargetStreamer().emitDirectiveSetMicroMips();
4236 case Mips::FeatureMips1:
4237 selectArch("mips1");
4238 getTargetStreamer().emitDirectiveSetMips1();
4240 case Mips::FeatureMips2:
4241 selectArch("mips2");
4242 getTargetStreamer().emitDirectiveSetMips2();
4244 case Mips::FeatureMips3:
4245 selectArch("mips3");
4246 getTargetStreamer().emitDirectiveSetMips3();
4248 case Mips::FeatureMips4:
4249 selectArch("mips4");
4250 getTargetStreamer().emitDirectiveSetMips4();
4252 case Mips::FeatureMips5:
4253 selectArch("mips5");
4254 getTargetStreamer().emitDirectiveSetMips5();
4256 case Mips::FeatureMips32:
4257 selectArch("mips32");
4258 getTargetStreamer().emitDirectiveSetMips32();
4260 case Mips::FeatureMips32r2:
4261 selectArch("mips32r2");
4262 getTargetStreamer().emitDirectiveSetMips32R2();
4264 case Mips::FeatureMips32r3:
4265 selectArch("mips32r3");
4266 getTargetStreamer().emitDirectiveSetMips32R3();
4268 case Mips::FeatureMips32r5:
4269 selectArch("mips32r5");
4270 getTargetStreamer().emitDirectiveSetMips32R5();
4272 case Mips::FeatureMips32r6:
4273 selectArch("mips32r6");
4274 getTargetStreamer().emitDirectiveSetMips32R6();
4276 case Mips::FeatureMips64:
4277 selectArch("mips64");
4278 getTargetStreamer().emitDirectiveSetMips64();
4280 case Mips::FeatureMips64r2:
4281 selectArch("mips64r2");
4282 getTargetStreamer().emitDirectiveSetMips64R2();
4284 case Mips::FeatureMips64r3:
4285 selectArch("mips64r3");
4286 getTargetStreamer().emitDirectiveSetMips64R3();
4288 case Mips::FeatureMips64r5:
4289 selectArch("mips64r5");
4290 getTargetStreamer().emitDirectiveSetMips64R5();
4292 case Mips::FeatureMips64r6:
4293 selectArch("mips64r6");
4294 getTargetStreamer().emitDirectiveSetMips64R6();
4300 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4301 MCAsmParser &Parser = getParser();
4302 if (getLexer().isNot(AsmToken::Comma)) {
4303 SMLoc Loc = getLexer().getLoc();
4304 Parser.eatToEndOfStatement();
4305 return Error(Loc, ErrorStr);
4308 Parser.Lex(); // Eat the comma.
4312 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4313 if (AssemblerOptions.back()->isReorder())
4314 Warning(Loc, ".cpload should be inside a noreorder section");
4316 if (inMips16Mode()) {
4317 reportParseError(".cpload is not supported in Mips16 mode");
4321 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4322 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4323 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4324 reportParseError("expected register containing function address");
4328 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4329 if (!RegOpnd.isGPRAsmReg()) {
4330 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4334 // If this is not the end of the statement, report an error.
4335 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4336 reportParseError("unexpected token, expected end of statement");
4340 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4344 bool MipsAsmParser::parseDirectiveCPSetup() {
4345 MCAsmParser &Parser = getParser();
4348 bool SaveIsReg = true;
4350 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4351 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4352 if (ResTy == MatchOperand_NoMatch) {
4353 reportParseError("expected register containing function address");
4354 Parser.eatToEndOfStatement();
4358 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4359 if (!FuncRegOpnd.isGPRAsmReg()) {
4360 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4361 Parser.eatToEndOfStatement();
4365 FuncReg = FuncRegOpnd.getGPR32Reg();
4368 if (!eatComma("unexpected token, expected comma"))
4371 ResTy = parseAnyRegister(TmpReg);
4372 if (ResTy == MatchOperand_NoMatch) {
4373 const AsmToken &Tok = Parser.getTok();
4374 if (Tok.is(AsmToken::Integer)) {
4375 Save = Tok.getIntVal();
4379 reportParseError("expected save register or stack offset");
4380 Parser.eatToEndOfStatement();
4384 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4385 if (!SaveOpnd.isGPRAsmReg()) {
4386 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4387 Parser.eatToEndOfStatement();
4390 Save = SaveOpnd.getGPR32Reg();
4393 if (!eatComma("unexpected token, expected comma"))
4397 if (Parser.parseExpression(Expr)) {
4398 reportParseError("expected expression");
4402 if (Expr->getKind() != MCExpr::SymbolRef) {
4403 reportParseError("expected symbol");
4406 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4408 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4413 bool MipsAsmParser::parseDirectiveNaN() {
4414 MCAsmParser &Parser = getParser();
4415 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4416 const AsmToken &Tok = Parser.getTok();
4418 if (Tok.getString() == "2008") {
4420 getTargetStreamer().emitDirectiveNaN2008();
4422 } else if (Tok.getString() == "legacy") {
4424 getTargetStreamer().emitDirectiveNaNLegacy();
4428 // If we don't recognize the option passed to the .nan
4429 // directive (e.g. no option or unknown option), emit an error.
4430 reportParseError("invalid option in .nan directive");
4434 bool MipsAsmParser::parseDirectiveSet() {
4435 MCAsmParser &Parser = getParser();
4436 // Get the next token.
4437 const AsmToken &Tok = Parser.getTok();
4439 if (Tok.getString() == "noat") {
4440 return parseSetNoAtDirective();
4441 } else if (Tok.getString() == "at") {
4442 return parseSetAtDirective();
4443 } else if (Tok.getString() == "arch") {
4444 return parseSetArchDirective();
4445 } else if (Tok.getString() == "fp") {
4446 return parseSetFpDirective();
4447 } else if (Tok.getString() == "pop") {
4448 return parseSetPopDirective();
4449 } else if (Tok.getString() == "push") {
4450 return parseSetPushDirective();
4451 } else if (Tok.getString() == "reorder") {
4452 return parseSetReorderDirective();
4453 } else if (Tok.getString() == "noreorder") {
4454 return parseSetNoReorderDirective();
4455 } else if (Tok.getString() == "macro") {
4456 return parseSetMacroDirective();
4457 } else if (Tok.getString() == "nomacro") {
4458 return parseSetNoMacroDirective();
4459 } else if (Tok.getString() == "mips16") {
4460 return parseSetMips16Directive();
4461 } else if (Tok.getString() == "nomips16") {
4462 return parseSetNoMips16Directive();
4463 } else if (Tok.getString() == "nomicromips") {
4464 getTargetStreamer().emitDirectiveSetNoMicroMips();
4465 Parser.eatToEndOfStatement();
4467 } else if (Tok.getString() == "micromips") {
4468 return parseSetFeature(Mips::FeatureMicroMips);
4469 } else if (Tok.getString() == "mips0") {
4470 return parseSetMips0Directive();
4471 } else if (Tok.getString() == "mips1") {
4472 return parseSetFeature(Mips::FeatureMips1);
4473 } else if (Tok.getString() == "mips2") {
4474 return parseSetFeature(Mips::FeatureMips2);
4475 } else if (Tok.getString() == "mips3") {
4476 return parseSetFeature(Mips::FeatureMips3);
4477 } else if (Tok.getString() == "mips4") {
4478 return parseSetFeature(Mips::FeatureMips4);
4479 } else if (Tok.getString() == "mips5") {
4480 return parseSetFeature(Mips::FeatureMips5);
4481 } else if (Tok.getString() == "mips32") {
4482 return parseSetFeature(Mips::FeatureMips32);
4483 } else if (Tok.getString() == "mips32r2") {
4484 return parseSetFeature(Mips::FeatureMips32r2);
4485 } else if (Tok.getString() == "mips32r3") {
4486 return parseSetFeature(Mips::FeatureMips32r3);
4487 } else if (Tok.getString() == "mips32r5") {
4488 return parseSetFeature(Mips::FeatureMips32r5);
4489 } else if (Tok.getString() == "mips32r6") {
4490 return parseSetFeature(Mips::FeatureMips32r6);
4491 } else if (Tok.getString() == "mips64") {
4492 return parseSetFeature(Mips::FeatureMips64);
4493 } else if (Tok.getString() == "mips64r2") {
4494 return parseSetFeature(Mips::FeatureMips64r2);
4495 } else if (Tok.getString() == "mips64r3") {
4496 return parseSetFeature(Mips::FeatureMips64r3);
4497 } else if (Tok.getString() == "mips64r5") {
4498 return parseSetFeature(Mips::FeatureMips64r5);
4499 } else if (Tok.getString() == "mips64r6") {
4500 return parseSetFeature(Mips::FeatureMips64r6);
4501 } else if (Tok.getString() == "dsp") {
4502 return parseSetFeature(Mips::FeatureDSP);
4503 } else if (Tok.getString() == "nodsp") {
4504 return parseSetNoDspDirective();
4505 } else if (Tok.getString() == "msa") {
4506 return parseSetMsaDirective();
4507 } else if (Tok.getString() == "nomsa") {
4508 return parseSetNoMsaDirective();
4509 } else if (Tok.getString() == "softfloat") {
4510 return parseSetSoftFloatDirective();
4511 } else if (Tok.getString() == "hardfloat") {
4512 return parseSetHardFloatDirective();
4514 // It is just an identifier, look for an assignment.
4515 parseSetAssignment();
4522 /// parseDataDirective
4523 /// ::= .word [ expression (, expression)* ]
4524 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4525 MCAsmParser &Parser = getParser();
4526 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4528 const MCExpr *Value;
4529 if (getParser().parseExpression(Value))
4532 getParser().getStreamer().EmitValue(Value, Size);
4534 if (getLexer().is(AsmToken::EndOfStatement))
4537 if (getLexer().isNot(AsmToken::Comma))
4538 return Error(L, "unexpected token, expected comma");
4547 /// parseDirectiveGpWord
4548 /// ::= .gpword local_sym
4549 bool MipsAsmParser::parseDirectiveGpWord() {
4550 MCAsmParser &Parser = getParser();
4551 const MCExpr *Value;
4552 // EmitGPRel32Value requires an expression, so we are using base class
4553 // method to evaluate the expression.
4554 if (getParser().parseExpression(Value))
4556 getParser().getStreamer().EmitGPRel32Value(Value);
4558 if (getLexer().isNot(AsmToken::EndOfStatement))
4559 return Error(getLexer().getLoc(),
4560 "unexpected token, expected end of statement");
4561 Parser.Lex(); // Eat EndOfStatement token.
4565 /// parseDirectiveGpDWord
4566 /// ::= .gpdword local_sym
4567 bool MipsAsmParser::parseDirectiveGpDWord() {
4568 MCAsmParser &Parser = getParser();
4569 const MCExpr *Value;
4570 // EmitGPRel64Value requires an expression, so we are using base class
4571 // method to evaluate the expression.
4572 if (getParser().parseExpression(Value))
4574 getParser().getStreamer().EmitGPRel64Value(Value);
4576 if (getLexer().isNot(AsmToken::EndOfStatement))
4577 return Error(getLexer().getLoc(),
4578 "unexpected token, expected end of statement");
4579 Parser.Lex(); // Eat EndOfStatement token.
4583 bool MipsAsmParser::parseDirectiveOption() {
4584 MCAsmParser &Parser = getParser();
4585 // Get the option token.
4586 AsmToken Tok = Parser.getTok();
4587 // At the moment only identifiers are supported.
4588 if (Tok.isNot(AsmToken::Identifier)) {
4589 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4590 Parser.eatToEndOfStatement();
4594 StringRef Option = Tok.getIdentifier();
4596 if (Option == "pic0") {
4597 getTargetStreamer().emitDirectiveOptionPic0();
4599 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4600 Error(Parser.getTok().getLoc(),
4601 "unexpected token, expected end of statement");
4602 Parser.eatToEndOfStatement();
4607 if (Option == "pic2") {
4608 getTargetStreamer().emitDirectiveOptionPic2();
4610 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4611 Error(Parser.getTok().getLoc(),
4612 "unexpected token, expected end of statement");
4613 Parser.eatToEndOfStatement();
4619 Warning(Parser.getTok().getLoc(),
4620 "unknown option, expected 'pic0' or 'pic2'");
4621 Parser.eatToEndOfStatement();
4625 /// parseInsnDirective
4627 bool MipsAsmParser::parseInsnDirective() {
4628 // If this is not the end of the statement, report an error.
4629 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4630 reportParseError("unexpected token, expected end of statement");
4634 // The actual label marking happens in
4635 // MipsELFStreamer::createPendingLabelRelocs().
4636 getTargetStreamer().emitDirectiveInsn();
4638 getParser().Lex(); // Eat EndOfStatement token.
4642 /// parseDirectiveModule
4643 /// ::= .module oddspreg
4644 /// ::= .module nooddspreg
4645 /// ::= .module fp=value
4646 bool MipsAsmParser::parseDirectiveModule() {
4647 MCAsmParser &Parser = getParser();
4648 MCAsmLexer &Lexer = getLexer();
4649 SMLoc L = Lexer.getLoc();
4651 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4652 // TODO : get a better message.
4653 reportParseError(".module directive must appear before any code");
4658 if (Parser.parseIdentifier(Option)) {
4659 reportParseError("expected .module option identifier");
4663 if (Option == "oddspreg") {
4664 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4666 // Synchronize the abiflags information with the FeatureBits information we
4668 getTargetStreamer().updateABIInfo(*this);
4670 // If printing assembly, use the recently updated abiflags information.
4671 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4672 // emitted at the end).
4673 getTargetStreamer().emitDirectiveModuleOddSPReg();
4675 // If this is not the end of the statement, report an error.
4676 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4677 reportParseError("unexpected token, expected end of statement");
4681 return false; // parseDirectiveModule has finished successfully.
4682 } else if (Option == "nooddspreg") {
4684 Error(L, "'.module nooddspreg' requires the O32 ABI");
4688 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4690 // Synchronize the abiflags information with the FeatureBits information we
4692 getTargetStreamer().updateABIInfo(*this);
4694 // If printing assembly, use the recently updated abiflags information.
4695 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4696 // emitted at the end).
4697 getTargetStreamer().emitDirectiveModuleOddSPReg();
4699 // If this is not the end of the statement, report an error.
4700 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4701 reportParseError("unexpected token, expected end of statement");
4705 return false; // parseDirectiveModule has finished successfully.
4706 } else if (Option == "fp") {
4707 return parseDirectiveModuleFP();
4709 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4713 /// parseDirectiveModuleFP
4717 bool MipsAsmParser::parseDirectiveModuleFP() {
4718 MCAsmParser &Parser = getParser();
4719 MCAsmLexer &Lexer = getLexer();
4721 if (Lexer.isNot(AsmToken::Equal)) {
4722 reportParseError("unexpected token, expected equals sign '='");
4725 Parser.Lex(); // Eat '=' token.
4727 MipsABIFlagsSection::FpABIKind FpABI;
4728 if (!parseFpABIValue(FpABI, ".module"))
4731 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4732 reportParseError("unexpected token, expected end of statement");
4736 // Synchronize the abiflags information with the FeatureBits information we
4738 getTargetStreamer().updateABIInfo(*this);
4740 // If printing assembly, use the recently updated abiflags information.
4741 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4742 // emitted at the end).
4743 getTargetStreamer().emitDirectiveModuleFP();
4745 Parser.Lex(); // Consume the EndOfStatement.
4749 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4750 StringRef Directive) {
4751 MCAsmParser &Parser = getParser();
4752 MCAsmLexer &Lexer = getLexer();
4754 if (Lexer.is(AsmToken::Identifier)) {
4755 StringRef Value = Parser.getTok().getString();
4758 if (Value != "xx") {
4759 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4764 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4768 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4769 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4770 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4774 if (Lexer.is(AsmToken::Integer)) {
4775 unsigned Value = Parser.getTok().getIntVal();
4778 if (Value != 32 && Value != 64) {
4779 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4785 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4789 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4790 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4791 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4793 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4794 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4795 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4804 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4805 MCAsmParser &Parser = getParser();
4806 StringRef IDVal = DirectiveID.getString();
4808 if (IDVal == ".cpload")
4809 return parseDirectiveCpLoad(DirectiveID.getLoc());
4810 if (IDVal == ".dword") {
4811 parseDataDirective(8, DirectiveID.getLoc());
4814 if (IDVal == ".ent") {
4815 StringRef SymbolName;
4817 if (Parser.parseIdentifier(SymbolName)) {
4818 reportParseError("expected identifier after .ent");
4822 // There's an undocumented extension that allows an integer to
4823 // follow the name of the procedure which AFAICS is ignored by GAS.
4824 // Example: .ent foo,2
4825 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4826 if (getLexer().isNot(AsmToken::Comma)) {
4827 // Even though we accept this undocumented extension for compatibility
4828 // reasons, the additional integer argument does not actually change
4829 // the behaviour of the '.ent' directive, so we would like to discourage
4830 // its use. We do this by not referring to the extended version in
4831 // error messages which are not directly related to its use.
4832 reportParseError("unexpected token, expected end of statement");
4835 Parser.Lex(); // Eat the comma.
4836 const MCExpr *DummyNumber;
4837 int64_t DummyNumberVal;
4838 // If the user was explicitly trying to use the extended version,
4839 // we still give helpful extension-related error messages.
4840 if (Parser.parseExpression(DummyNumber)) {
4841 reportParseError("expected number after comma");
4844 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4845 reportParseError("expected an absolute expression after comma");
4850 // If this is not the end of the statement, report an error.
4851 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4852 reportParseError("unexpected token, expected end of statement");
4856 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4858 getTargetStreamer().emitDirectiveEnt(*Sym);
4863 if (IDVal == ".end") {
4864 StringRef SymbolName;
4866 if (Parser.parseIdentifier(SymbolName)) {
4867 reportParseError("expected identifier after .end");
4871 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4872 reportParseError("unexpected token, expected end of statement");
4876 if (CurrentFn == nullptr) {
4877 reportParseError(".end used without .ent");
4881 if ((SymbolName != CurrentFn->getName())) {
4882 reportParseError(".end symbol does not match .ent symbol");
4886 getTargetStreamer().emitDirectiveEnd(SymbolName);
4887 CurrentFn = nullptr;
4891 if (IDVal == ".frame") {
4892 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4893 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4894 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4895 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4896 reportParseError("expected stack register");
4900 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4901 if (!StackRegOpnd.isGPRAsmReg()) {
4902 reportParseError(StackRegOpnd.getStartLoc(),
4903 "expected general purpose register");
4906 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4908 if (Parser.getTok().is(AsmToken::Comma))
4911 reportParseError("unexpected token, expected comma");
4915 // Parse the frame size.
4916 const MCExpr *FrameSize;
4917 int64_t FrameSizeVal;
4919 if (Parser.parseExpression(FrameSize)) {
4920 reportParseError("expected frame size value");
4924 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4925 reportParseError("frame size not an absolute expression");
4929 if (Parser.getTok().is(AsmToken::Comma))
4932 reportParseError("unexpected token, expected comma");
4936 // Parse the return register.
4938 ResTy = parseAnyRegister(TmpReg);
4939 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4940 reportParseError("expected return register");
4944 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4945 if (!ReturnRegOpnd.isGPRAsmReg()) {
4946 reportParseError(ReturnRegOpnd.getStartLoc(),
4947 "expected general purpose register");
4951 // If this is not the end of the statement, report an error.
4952 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4953 reportParseError("unexpected token, expected end of statement");
4957 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4958 ReturnRegOpnd.getGPR32Reg());
4962 if (IDVal == ".set") {
4963 return parseDirectiveSet();
4966 if (IDVal == ".mask" || IDVal == ".fmask") {
4967 // .mask bitmask, frame_offset
4968 // bitmask: One bit for each register used.
4969 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4970 // first register is expected to be saved.
4972 // .mask 0x80000000, -4
4973 // .fmask 0x80000000, -4
4976 // Parse the bitmask
4977 const MCExpr *BitMask;
4980 if (Parser.parseExpression(BitMask)) {
4981 reportParseError("expected bitmask value");
4985 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4986 reportParseError("bitmask not an absolute expression");
4990 if (Parser.getTok().is(AsmToken::Comma))
4993 reportParseError("unexpected token, expected comma");
4997 // Parse the frame_offset
4998 const MCExpr *FrameOffset;
4999 int64_t FrameOffsetVal;
5001 if (Parser.parseExpression(FrameOffset)) {
5002 reportParseError("expected frame offset value");
5006 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5007 reportParseError("frame offset not an absolute expression");
5011 // If this is not the end of the statement, report an error.
5012 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5013 reportParseError("unexpected token, expected end of statement");
5017 if (IDVal == ".mask")
5018 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5020 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5024 if (IDVal == ".nan")
5025 return parseDirectiveNaN();
5027 if (IDVal == ".gpword") {
5028 parseDirectiveGpWord();
5032 if (IDVal == ".gpdword") {
5033 parseDirectiveGpDWord();
5037 if (IDVal == ".word") {
5038 parseDataDirective(4, DirectiveID.getLoc());
5042 if (IDVal == ".option")
5043 return parseDirectiveOption();
5045 if (IDVal == ".abicalls") {
5046 getTargetStreamer().emitDirectiveAbiCalls();
5047 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5048 Error(Parser.getTok().getLoc(),
5049 "unexpected token, expected end of statement");
5051 Parser.eatToEndOfStatement();
5056 if (IDVal == ".cpsetup")
5057 return parseDirectiveCPSetup();
5059 if (IDVal == ".module")
5060 return parseDirectiveModule();
5062 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5063 return parseInternalDirectiveReallowModule();
5065 if (IDVal == ".insn")
5066 return parseInsnDirective();
5071 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5072 // If this is not the end of the statement, report an error.
5073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5074 reportParseError("unexpected token, expected end of statement");
5078 getTargetStreamer().reallowModuleDirective();
5080 getParser().Lex(); // Eat EndOfStatement token.
5084 extern "C" void LLVMInitializeMipsAsmParser() {
5085 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5086 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5087 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5088 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5091 #define GET_REGISTER_MATCHER
5092 #define GET_MATCHER_IMPLEMENTATION
5093 #include "MipsGenAsmMatcher.inc"