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 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
222 SmallVectorImpl<MCInst> &Instructions);
224 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
225 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
227 bool reportParseError(Twine ErrorMsg);
228 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
230 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
231 bool parseRelocOperand(const MCExpr *&Res);
233 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
235 bool isEvaluated(const MCExpr *Expr);
236 bool parseSetMips0Directive();
237 bool parseSetArchDirective();
238 bool parseSetFeature(uint64_t Feature);
239 bool parseDirectiveCpLoad(SMLoc Loc);
240 bool parseDirectiveCPSetup();
241 bool parseDirectiveNaN();
242 bool parseDirectiveSet();
243 bool parseDirectiveOption();
244 bool parseInsnDirective();
246 bool parseSetAtDirective();
247 bool parseSetNoAtDirective();
248 bool parseSetMacroDirective();
249 bool parseSetNoMacroDirective();
250 bool parseSetMsaDirective();
251 bool parseSetNoMsaDirective();
252 bool parseSetNoDspDirective();
253 bool parseSetReorderDirective();
254 bool parseSetNoReorderDirective();
255 bool parseSetMips16Directive();
256 bool parseSetNoMips16Directive();
257 bool parseSetFpDirective();
258 bool parseSetPopDirective();
259 bool parseSetPushDirective();
260 bool parseSetSoftFloatDirective();
261 bool parseSetHardFloatDirective();
263 bool parseSetAssignment();
265 bool parseDataDirective(unsigned Size, SMLoc L);
266 bool parseDirectiveGpWord();
267 bool parseDirectiveGpDWord();
268 bool parseDirectiveModule();
269 bool parseDirectiveModuleFP();
270 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
271 StringRef Directive);
273 bool parseInternalDirectiveReallowModule();
275 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
277 bool eatComma(StringRef ErrorStr);
279 int matchCPURegisterName(StringRef Symbol);
281 int matchHWRegsRegisterName(StringRef Symbol);
283 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
285 int matchFPURegisterName(StringRef Name);
287 int matchFCCRegisterName(StringRef Name);
289 int matchACRegisterName(StringRef Name);
291 int matchMSA128RegisterName(StringRef Name);
293 int matchMSA128CtrlRegisterName(StringRef Name);
295 unsigned getReg(int RC, int RegNo);
297 unsigned getGPR(int RegNo);
299 /// Returns the internal register number for the current AT. Also checks if
300 /// the current AT is unavailable (set to $0) and gives an error if it is.
301 /// This should be used in pseudo-instruction expansions which need AT.
302 unsigned getATReg(SMLoc Loc);
304 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
305 SmallVectorImpl<MCInst> &Instructions);
307 // Helper function that checks if the value of a vector index is within the
308 // boundaries of accepted values for each RegisterKind
309 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
310 bool validateMSAIndex(int Val, int RegKind);
312 // Selects a new architecture by updating the FeatureBits with the necessary
313 // info including implied dependencies.
314 // Internally, it clears all the feature bits related to *any* architecture
315 // and selects the new one using the ToggleFeature functionality of the
316 // MCSubtargetInfo object that handles implied dependencies. The reason we
317 // clear all the arch related bits manually is because ToggleFeature only
318 // clears the features that imply the feature being cleared and not the
319 // features implied by the feature being cleared. This is easier to see
321 // --------------------------------------------------
322 // | Feature | Implies |
323 // | -------------------------------------------------|
324 // | FeatureMips1 | None |
325 // | FeatureMips2 | FeatureMips1 |
326 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
327 // | FeatureMips4 | FeatureMips3 |
329 // --------------------------------------------------
331 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
332 // FeatureMipsGP64 | FeatureMips1)
333 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
334 void selectArch(StringRef ArchFeature) {
335 FeatureBitset FeatureBits = STI.getFeatureBits();
336 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
337 STI.setFeatureBits(FeatureBits);
338 setAvailableFeatures(
339 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
340 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
343 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
344 if (!(STI.getFeatureBits()[Feature])) {
345 setAvailableFeatures(
346 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
347 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
351 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
352 if (STI.getFeatureBits()[Feature]) {
353 setAvailableFeatures(
354 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
355 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
360 enum MipsMatchResultTy {
361 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
362 #define GET_OPERAND_DIAGNOSTIC_TYPES
363 #include "MipsGenAsmMatcher.inc"
364 #undef GET_OPERAND_DIAGNOSTIC_TYPES
368 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
369 const MCInstrInfo &MII, const MCTargetOptions &Options)
370 : MCTargetAsmParser(), STI(sti),
371 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
372 sti.getCPU(), Options)) {
373 MCAsmParserExtension::Initialize(parser);
375 parser.addAliasForDirective(".asciiz", ".asciz");
377 // Initialize the set of available features.
378 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
380 // Remember the initial assembler options. The user can not modify these.
381 AssemblerOptions.push_back(
382 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
384 // Create an assembler options environment for the user to modify.
385 AssemblerOptions.push_back(
386 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
388 getTargetStreamer().updateABIInfo(*this);
390 if (!isABI_O32() && !useOddSPReg() != 0)
391 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
395 Triple TheTriple(sti.getTargetTriple());
396 if ((TheTriple.getArch() == Triple::mips) ||
397 (TheTriple.getArch() == Triple::mips64))
398 IsLittleEndian = false;
400 IsLittleEndian = true;
403 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
404 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
406 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
407 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
408 const MipsABIInfo &getABI() const { return ABI; }
409 bool isABI_N32() const { return ABI.IsN32(); }
410 bool isABI_N64() const { return ABI.IsN64(); }
411 bool isABI_O32() const { return ABI.IsO32(); }
412 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
414 bool useOddSPReg() const {
415 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
418 bool inMicroMipsMode() const {
419 return STI.getFeatureBits()[Mips::FeatureMicroMips];
421 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
422 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
423 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
424 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
425 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
426 bool hasMips32() const {
427 return STI.getFeatureBits()[Mips::FeatureMips32];
429 bool hasMips64() const {
430 return STI.getFeatureBits()[Mips::FeatureMips64];
432 bool hasMips32r2() const {
433 return STI.getFeatureBits()[Mips::FeatureMips32r2];
435 bool hasMips64r2() const {
436 return STI.getFeatureBits()[Mips::FeatureMips64r2];
438 bool hasMips32r3() const {
439 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
441 bool hasMips64r3() const {
442 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
444 bool hasMips32r5() const {
445 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
447 bool hasMips64r5() const {
448 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
450 bool hasMips32r6() const {
451 return STI.getFeatureBits()[Mips::FeatureMips32r6];
453 bool hasMips64r6() const {
454 return STI.getFeatureBits()[Mips::FeatureMips64r6];
457 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
458 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
459 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
460 bool hasCnMips() const {
461 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
464 bool inMips16Mode() const {
465 return STI.getFeatureBits()[Mips::FeatureMips16];
468 bool useSoftFloat() const {
469 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
472 /// Warn if RegIndex is the same as the current AT.
473 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
475 void warnIfNoMacro(SMLoc Loc);
477 bool isLittle() const { return IsLittleEndian; }
483 /// MipsOperand - Instances of this class represent a parsed Mips machine
485 class MipsOperand : public MCParsedAsmOperand {
487 /// Broad categories of register classes
488 /// The exact class is finalized by the render method.
490 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
491 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
493 RegKind_FCC = 4, /// FCC
494 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
495 RegKind_MSACtrl = 16, /// MSA control registers
496 RegKind_COP2 = 32, /// COP2
497 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
499 RegKind_CCR = 128, /// CCR
500 RegKind_HWRegs = 256, /// HWRegs
501 RegKind_COP3 = 512, /// COP3
503 /// Potentially any (e.g. $1)
504 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
505 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
506 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
511 k_Immediate, /// An immediate (possibly involving symbol references)
512 k_Memory, /// Base + Offset Memory Address
513 k_PhysRegister, /// A physical register from the Mips namespace
514 k_RegisterIndex, /// A register index in one or more RegKind.
515 k_Token, /// A simple token
516 k_RegList, /// A physical register list
517 k_RegPair /// A pair of physical register
521 MipsOperand(KindTy K, MipsAsmParser &Parser)
522 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
525 /// For diagnostics, and checking the assembler temporary
526 MipsAsmParser &AsmParser;
534 unsigned Num; /// Register Number
538 unsigned Index; /// Index into the register class
539 RegKind Kind; /// Bitfield of the kinds it could possibly be
540 const MCRegisterInfo *RegInfo;
553 SmallVector<unsigned, 10> *List;
558 struct PhysRegOp PhysReg;
559 struct RegIdxOp RegIdx;
562 struct RegListOp RegList;
565 SMLoc StartLoc, EndLoc;
567 /// Internal constructor for register kinds
568 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
569 const MCRegisterInfo *RegInfo,
571 MipsAsmParser &Parser) {
572 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
573 Op->RegIdx.Index = Index;
574 Op->RegIdx.RegInfo = RegInfo;
575 Op->RegIdx.Kind = RegKind;
582 /// Coerce the register to GPR32 and return the real register for the current
584 unsigned getGPR32Reg() const {
585 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
586 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
587 unsigned ClassID = Mips::GPR32RegClassID;
588 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
591 /// Coerce the register to GPR32 and return the real register for the current
593 unsigned getGPRMM16Reg() const {
594 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
595 unsigned ClassID = Mips::GPR32RegClassID;
596 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
599 /// Coerce the register to GPR64 and return the real register for the current
601 unsigned getGPR64Reg() const {
602 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
603 unsigned ClassID = Mips::GPR64RegClassID;
604 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
608 /// Coerce the register to AFGR64 and return the real register for the current
610 unsigned getAFGR64Reg() const {
611 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
612 if (RegIdx.Index % 2 != 0)
613 AsmParser.Warning(StartLoc, "Float register should be even.");
614 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
615 .getRegister(RegIdx.Index / 2);
618 /// Coerce the register to FGR64 and return the real register for the current
620 unsigned getFGR64Reg() const {
621 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
622 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
623 .getRegister(RegIdx.Index);
626 /// Coerce the register to FGR32 and return the real register for the current
628 unsigned getFGR32Reg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
630 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
631 .getRegister(RegIdx.Index);
634 /// Coerce the register to FGRH32 and return the real register for the current
636 unsigned getFGRH32Reg() const {
637 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
638 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
639 .getRegister(RegIdx.Index);
642 /// Coerce the register to FCC and return the real register for the current
644 unsigned getFCCReg() const {
645 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
646 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
647 .getRegister(RegIdx.Index);
650 /// Coerce the register to MSA128 and return the real register for the current
652 unsigned getMSA128Reg() const {
653 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
654 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
656 unsigned ClassID = Mips::MSA128BRegClassID;
657 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
660 /// Coerce the register to MSACtrl and return the real register for the
662 unsigned getMSACtrlReg() const {
663 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
664 unsigned ClassID = Mips::MSACtrlRegClassID;
665 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
668 /// Coerce the register to COP2 and return the real register for the
670 unsigned getCOP2Reg() const {
671 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
672 unsigned ClassID = Mips::COP2RegClassID;
673 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
676 /// Coerce the register to COP3 and return the real register for the
678 unsigned getCOP3Reg() const {
679 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
680 unsigned ClassID = Mips::COP3RegClassID;
681 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
684 /// Coerce the register to ACC64DSP and return the real register for the
686 unsigned getACC64DSPReg() const {
687 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
688 unsigned ClassID = Mips::ACC64DSPRegClassID;
689 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
692 /// Coerce the register to HI32DSP and return the real register for the
694 unsigned getHI32DSPReg() const {
695 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
696 unsigned ClassID = Mips::HI32DSPRegClassID;
697 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
700 /// Coerce the register to LO32DSP and return the real register for the
702 unsigned getLO32DSPReg() const {
703 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
704 unsigned ClassID = Mips::LO32DSPRegClassID;
705 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
708 /// Coerce the register to CCR and return the real register for the
710 unsigned getCCRReg() const {
711 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
712 unsigned ClassID = Mips::CCRRegClassID;
713 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
716 /// Coerce the register to HWRegs and return the real register for the
718 unsigned getHWRegsReg() const {
719 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
720 unsigned ClassID = Mips::HWRegsRegClassID;
721 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
725 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
726 // Add as immediate when possible. Null MCExpr = 0.
728 Inst.addOperand(MCOperand::createImm(0));
729 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
730 Inst.addOperand(MCOperand::createImm(CE->getValue()));
732 Inst.addOperand(MCOperand::createExpr(Expr));
735 void addRegOperands(MCInst &Inst, unsigned N) const {
736 llvm_unreachable("Use a custom parser instead");
739 /// Render the operand to an MCInst as a GPR32
740 /// Asserts if the wrong number of operands are requested, or the operand
741 /// is not a k_RegisterIndex compatible with RegKind_GPR
742 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
743 assert(N == 1 && "Invalid number of operands!");
744 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
747 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
748 assert(N == 1 && "Invalid number of operands!");
749 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
752 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
753 assert(N == 1 && "Invalid number of operands!");
754 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
757 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
758 assert(N == 1 && "Invalid number of operands!");
759 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
762 /// Render the operand to an MCInst as a GPR64
763 /// Asserts if the wrong number of operands are requested, or the operand
764 /// is not a k_RegisterIndex compatible with RegKind_GPR
765 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 1 && "Invalid number of operands!");
767 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
770 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
771 assert(N == 1 && "Invalid number of operands!");
772 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
775 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
776 assert(N == 1 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
780 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
781 assert(N == 1 && "Invalid number of operands!");
782 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
783 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
784 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
785 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
789 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
794 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::createReg(getFCCReg()));
799 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
800 assert(N == 1 && "Invalid number of operands!");
801 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
804 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
809 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
810 assert(N == 1 && "Invalid number of operands!");
811 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
814 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
815 assert(N == 1 && "Invalid number of operands!");
816 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
819 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 1 && "Invalid number of operands!");
821 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
824 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
825 assert(N == 1 && "Invalid number of operands!");
826 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
829 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
830 assert(N == 1 && "Invalid number of operands!");
831 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
834 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
835 assert(N == 1 && "Invalid number of operands!");
836 Inst.addOperand(MCOperand::createReg(getCCRReg()));
839 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
840 assert(N == 1 && "Invalid number of operands!");
841 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
844 void addImmOperands(MCInst &Inst, unsigned N) const {
845 assert(N == 1 && "Invalid number of operands!");
846 const MCExpr *Expr = getImm();
850 void addMemOperands(MCInst &Inst, unsigned N) const {
851 assert(N == 2 && "Invalid number of operands!");
853 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPR32Reg()));
855 const MCExpr *Expr = getMemOff();
859 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
860 assert(N == 2 && "Invalid number of operands!");
862 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
864 const MCExpr *Expr = getMemOff();
868 void addRegListOperands(MCInst &Inst, unsigned N) const {
869 assert(N == 1 && "Invalid number of operands!");
871 for (auto RegNo : getRegList())
872 Inst.addOperand(MCOperand::createReg(RegNo));
875 void addRegPairOperands(MCInst &Inst, unsigned N) const {
876 assert(N == 2 && "Invalid number of operands!");
877 unsigned RegNo = getRegPair();
878 Inst.addOperand(MCOperand::createReg(RegNo++));
879 Inst.addOperand(MCOperand::createReg(RegNo));
882 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
883 assert(N == 2 && "Invalid number of operands!");
884 for (auto RegNo : getRegList())
885 Inst.addOperand(MCOperand::createReg(RegNo));
888 bool isReg() const override {
889 // As a special case until we sort out the definition of div/divu, pretend
890 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
891 if (isGPRAsmReg() && RegIdx.Index == 0)
894 return Kind == k_PhysRegister;
896 bool isRegIdx() const { return Kind == k_RegisterIndex; }
897 bool isImm() const override { return Kind == k_Immediate; }
898 bool isConstantImm() const {
899 return isImm() && dyn_cast<MCConstantExpr>(getImm());
901 template <unsigned Bits> bool isUImm() const {
902 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
904 bool isToken() const override {
905 // Note: It's not possible to pretend that other operand kinds are tokens.
906 // The matcher emitter checks tokens first.
907 return Kind == k_Token;
909 bool isMem() const override { return Kind == k_Memory; }
910 bool isConstantMemOff() const {
911 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
913 template <unsigned Bits> bool isMemWithSimmOffset() const {
914 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
916 bool isMemWithGRPMM16Base() const {
917 return isMem() && getMemBase()->isMM16AsmReg();
919 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
920 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
921 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
923 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
924 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
925 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
926 && (getMemBase()->getGPR32Reg() == Mips::SP);
928 bool isRegList16() const {
932 int Size = RegList.List->size();
933 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
934 RegList.List->back() != Mips::RA)
937 int PrevReg = *RegList.List->begin();
938 for (int i = 1; i < Size - 1; i++) {
939 int Reg = (*(RegList.List))[i];
940 if ( Reg != PrevReg + 1)
947 bool isInvNum() const { return Kind == k_Immediate; }
948 bool isLSAImm() const {
949 if (!isConstantImm())
951 int64_t Val = getConstantImm();
952 return 1 <= Val && Val <= 4;
954 bool isRegList() const { return Kind == k_RegList; }
955 bool isMovePRegPair() const {
956 if (Kind != k_RegList || RegList.List->size() != 2)
959 unsigned R0 = RegList.List->front();
960 unsigned R1 = RegList.List->back();
962 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
963 (R0 == Mips::A1 && R1 == Mips::A3) ||
964 (R0 == Mips::A2 && R1 == Mips::A3) ||
965 (R0 == Mips::A0 && R1 == Mips::S5) ||
966 (R0 == Mips::A0 && R1 == Mips::S6) ||
967 (R0 == Mips::A0 && R1 == Mips::A1) ||
968 (R0 == Mips::A0 && R1 == Mips::A2) ||
969 (R0 == Mips::A0 && R1 == Mips::A3))
975 StringRef getToken() const {
976 assert(Kind == k_Token && "Invalid access!");
977 return StringRef(Tok.Data, Tok.Length);
979 bool isRegPair() const { return Kind == k_RegPair; }
981 unsigned getReg() const override {
982 // As a special case until we sort out the definition of div/divu, pretend
983 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
984 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
985 RegIdx.Kind & RegKind_GPR)
986 return getGPR32Reg(); // FIXME: GPR64 too
988 assert(Kind == k_PhysRegister && "Invalid access!");
992 const MCExpr *getImm() const {
993 assert((Kind == k_Immediate) && "Invalid access!");
997 int64_t getConstantImm() const {
998 const MCExpr *Val = getImm();
999 return static_cast<const MCConstantExpr *>(Val)->getValue();
1002 MipsOperand *getMemBase() const {
1003 assert((Kind == k_Memory) && "Invalid access!");
1007 const MCExpr *getMemOff() const {
1008 assert((Kind == k_Memory) && "Invalid access!");
1012 int64_t getConstantMemOff() const {
1013 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1016 const SmallVectorImpl<unsigned> &getRegList() const {
1017 assert((Kind == k_RegList) && "Invalid access!");
1018 return *(RegList.List);
1021 unsigned getRegPair() const {
1022 assert((Kind == k_RegPair) && "Invalid access!");
1023 return RegIdx.Index;
1026 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1027 MipsAsmParser &Parser) {
1028 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1029 Op->Tok.Data = Str.data();
1030 Op->Tok.Length = Str.size();
1036 /// Create a numeric register (e.g. $1). The exact register remains
1037 /// unresolved until an instruction successfully matches
1038 static std::unique_ptr<MipsOperand>
1039 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1040 SMLoc E, MipsAsmParser &Parser) {
1041 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1042 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1045 /// Create a register that is definitely a GPR.
1046 /// This is typically only used for named registers such as $gp.
1047 static std::unique_ptr<MipsOperand>
1048 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1049 MipsAsmParser &Parser) {
1050 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1053 /// Create a register that is definitely a FGR.
1054 /// This is typically only used for named registers such as $f0.
1055 static std::unique_ptr<MipsOperand>
1056 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1057 MipsAsmParser &Parser) {
1058 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1061 /// Create a register that is definitely a HWReg.
1062 /// This is typically only used for named registers such as $hwr_cpunum.
1063 static std::unique_ptr<MipsOperand>
1064 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1065 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1066 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1069 /// Create a register that is definitely an FCC.
1070 /// This is typically only used for named registers such as $fcc0.
1071 static std::unique_ptr<MipsOperand>
1072 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1073 MipsAsmParser &Parser) {
1074 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1077 /// Create a register that is definitely an ACC.
1078 /// This is typically only used for named registers such as $ac0.
1079 static std::unique_ptr<MipsOperand>
1080 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1081 MipsAsmParser &Parser) {
1082 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1085 /// Create a register that is definitely an MSA128.
1086 /// This is typically only used for named registers such as $w0.
1087 static std::unique_ptr<MipsOperand>
1088 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1089 SMLoc E, MipsAsmParser &Parser) {
1090 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1093 /// Create a register that is definitely an MSACtrl.
1094 /// This is typically only used for named registers such as $msaaccess.
1095 static std::unique_ptr<MipsOperand>
1096 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1097 SMLoc E, MipsAsmParser &Parser) {
1098 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1101 static std::unique_ptr<MipsOperand>
1102 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1103 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1110 static std::unique_ptr<MipsOperand>
1111 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1112 SMLoc E, MipsAsmParser &Parser) {
1113 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1114 Op->Mem.Base = Base.release();
1121 static std::unique_ptr<MipsOperand>
1122 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1123 MipsAsmParser &Parser) {
1124 assert (Regs.size() > 0 && "Empty list not allowed");
1126 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1127 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1128 Op->StartLoc = StartLoc;
1129 Op->EndLoc = EndLoc;
1133 static std::unique_ptr<MipsOperand>
1134 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1135 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1136 Op->RegIdx.Index = RegNo;
1142 bool isGPRAsmReg() const {
1143 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1145 bool isMM16AsmReg() const {
1146 if (!(isRegIdx() && RegIdx.Kind))
1148 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1149 || RegIdx.Index == 16 || RegIdx.Index == 17);
1151 bool isMM16AsmRegZero() const {
1152 if (!(isRegIdx() && RegIdx.Kind))
1154 return (RegIdx.Index == 0 ||
1155 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1156 RegIdx.Index == 17);
1158 bool isMM16AsmRegMoveP() const {
1159 if (!(isRegIdx() && RegIdx.Kind))
1161 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1162 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1164 bool isFGRAsmReg() const {
1165 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1166 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1168 bool isHWRegsAsmReg() const {
1169 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1171 bool isCCRAsmReg() const {
1172 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1174 bool isFCCAsmReg() const {
1175 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1177 if (!AsmParser.hasEightFccRegisters())
1178 return RegIdx.Index == 0;
1179 return RegIdx.Index <= 7;
1181 bool isACCAsmReg() const {
1182 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1184 bool isCOP2AsmReg() const {
1185 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1187 bool isCOP3AsmReg() const {
1188 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1190 bool isMSA128AsmReg() const {
1191 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1193 bool isMSACtrlAsmReg() const {
1194 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1197 /// getStartLoc - Get the location of the first token of this operand.
1198 SMLoc getStartLoc() const override { return StartLoc; }
1199 /// getEndLoc - Get the location of the last token of this operand.
1200 SMLoc getEndLoc() const override { return EndLoc; }
1202 virtual ~MipsOperand() {
1210 delete RegList.List;
1211 case k_PhysRegister:
1212 case k_RegisterIndex:
1219 void print(raw_ostream &OS) const override {
1228 Mem.Base->print(OS);
1233 case k_PhysRegister:
1234 OS << "PhysReg<" << PhysReg.Num << ">";
1236 case k_RegisterIndex:
1237 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1244 for (auto Reg : (*RegList.List))
1249 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1253 }; // class MipsOperand
1257 extern const MCInstrDesc MipsInsts[];
1259 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1260 return MipsInsts[Opcode];
1263 static bool hasShortDelaySlot(unsigned Opcode) {
1266 case Mips::JALRS_MM:
1267 case Mips::JALRS16_MM:
1268 case Mips::BGEZALS_MM:
1269 case Mips::BLTZALS_MM:
1276 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1277 SmallVectorImpl<MCInst> &Instructions) {
1278 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1282 if (MCID.isBranch() || MCID.isCall()) {
1283 const unsigned Opcode = Inst.getOpcode();
1293 assert(hasCnMips() && "instruction only valid for octeon cpus");
1300 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1301 Offset = Inst.getOperand(2);
1302 if (!Offset.isImm())
1303 break; // We'll deal with this situation later on when applying fixups.
1304 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1305 return Error(IDLoc, "branch target out of range");
1306 if (OffsetToAlignment(Offset.getImm(),
1307 1LL << (inMicroMipsMode() ? 1 : 2)))
1308 return Error(IDLoc, "branch to misaligned address");
1322 case Mips::BGEZAL_MM:
1323 case Mips::BLTZAL_MM:
1326 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1327 Offset = Inst.getOperand(1);
1328 if (!Offset.isImm())
1329 break; // We'll deal with this situation later on when applying fixups.
1330 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1331 return Error(IDLoc, "branch target out of range");
1332 if (OffsetToAlignment(Offset.getImm(),
1333 1LL << (inMicroMipsMode() ? 1 : 2)))
1334 return Error(IDLoc, "branch to misaligned address");
1336 case Mips::BEQZ16_MM:
1337 case Mips::BNEZ16_MM:
1338 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1339 Offset = Inst.getOperand(1);
1340 if (!Offset.isImm())
1341 break; // We'll deal with this situation later on when applying fixups.
1342 if (!isIntN(8, Offset.getImm()))
1343 return Error(IDLoc, "branch target out of range");
1344 if (OffsetToAlignment(Offset.getImm(), 2LL))
1345 return Error(IDLoc, "branch to misaligned address");
1350 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1351 // We still accept it but it is a normal nop.
1352 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1353 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1354 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1359 const unsigned Opcode = Inst.getOpcode();
1371 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1372 // The offset is handled above
1373 Opnd = Inst.getOperand(1);
1375 return Error(IDLoc, "expected immediate operand kind");
1376 Imm = Opnd.getImm();
1377 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1378 Opcode == Mips::BBIT1 ? 63 : 31))
1379 return Error(IDLoc, "immediate operand value out of range");
1381 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1383 Inst.getOperand(1).setImm(Imm - 32);
1391 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1393 Opnd = Inst.getOperand(3);
1395 return Error(IDLoc, "expected immediate operand kind");
1396 Imm = Opnd.getImm();
1397 if (Imm < 0 || Imm > 31)
1398 return Error(IDLoc, "immediate operand value out of range");
1400 Opnd = Inst.getOperand(2);
1402 return Error(IDLoc, "expected immediate operand kind");
1403 Imm = Opnd.getImm();
1404 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1405 Opcode == Mips::EXTS ? 63 : 31))
1406 return Error(IDLoc, "immediate operand value out of range");
1408 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1409 Inst.getOperand(2).setImm(Imm - 32);
1415 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1416 Opnd = Inst.getOperand(2);
1418 return Error(IDLoc, "expected immediate operand kind");
1419 Imm = Opnd.getImm();
1420 if (!isInt<10>(Imm))
1421 return Error(IDLoc, "immediate operand value out of range");
1426 if (MCID.mayLoad() || MCID.mayStore()) {
1427 // Check the offset of memory operand, if it is a symbol
1428 // reference or immediate we may have to expand instructions.
1429 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1430 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1431 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1432 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1433 MCOperand &Op = Inst.getOperand(i);
1435 int MemOffset = Op.getImm();
1436 if (MemOffset < -32768 || MemOffset > 32767) {
1437 // Offset can't exceed 16bit value.
1438 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1441 } else if (Op.isExpr()) {
1442 const MCExpr *Expr = Op.getExpr();
1443 if (Expr->getKind() == MCExpr::SymbolRef) {
1444 const MCSymbolRefExpr *SR =
1445 static_cast<const MCSymbolRefExpr *>(Expr);
1446 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1448 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1451 } else if (!isEvaluated(Expr)) {
1452 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1460 if (inMicroMipsMode()) {
1461 if (MCID.mayLoad()) {
1462 // Try to create 16-bit GP relative load instruction.
1463 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1464 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1465 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1466 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1467 MCOperand &Op = Inst.getOperand(i);
1469 int MemOffset = Op.getImm();
1470 MCOperand &DstReg = Inst.getOperand(0);
1471 MCOperand &BaseReg = Inst.getOperand(1);
1472 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1473 getContext().getRegisterInfo()->getRegClass(
1474 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1475 BaseReg.getReg() == Mips::GP) {
1477 TmpInst.setLoc(IDLoc);
1478 TmpInst.setOpcode(Mips::LWGP_MM);
1479 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1480 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1481 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1482 Instructions.push_back(TmpInst);
1490 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1495 switch (Inst.getOpcode()) {
1498 case Mips::ADDIUS5_MM:
1499 Opnd = Inst.getOperand(2);
1501 return Error(IDLoc, "expected immediate operand kind");
1502 Imm = Opnd.getImm();
1503 if (Imm < -8 || Imm > 7)
1504 return Error(IDLoc, "immediate operand value out of range");
1506 case Mips::ADDIUSP_MM:
1507 Opnd = Inst.getOperand(0);
1509 return Error(IDLoc, "expected immediate operand kind");
1510 Imm = Opnd.getImm();
1511 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1513 return Error(IDLoc, "immediate operand value out of range");
1515 case Mips::SLL16_MM:
1516 case Mips::SRL16_MM:
1517 Opnd = Inst.getOperand(2);
1519 return Error(IDLoc, "expected immediate operand kind");
1520 Imm = Opnd.getImm();
1521 if (Imm < 1 || Imm > 8)
1522 return Error(IDLoc, "immediate operand value out of range");
1525 Opnd = Inst.getOperand(1);
1527 return Error(IDLoc, "expected immediate operand kind");
1528 Imm = Opnd.getImm();
1529 if (Imm < -1 || Imm > 126)
1530 return Error(IDLoc, "immediate operand value out of range");
1532 case Mips::ADDIUR2_MM:
1533 Opnd = Inst.getOperand(2);
1535 return Error(IDLoc, "expected immediate operand kind");
1536 Imm = Opnd.getImm();
1537 if (!(Imm == 1 || Imm == -1 ||
1538 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1539 return Error(IDLoc, "immediate operand value out of range");
1541 case Mips::ADDIUR1SP_MM:
1542 Opnd = Inst.getOperand(1);
1544 return Error(IDLoc, "expected immediate operand kind");
1545 Imm = Opnd.getImm();
1546 if (OffsetToAlignment(Imm, 4LL))
1547 return Error(IDLoc, "misaligned immediate operand value");
1548 if (Imm < 0 || Imm > 255)
1549 return Error(IDLoc, "immediate operand value out of range");
1551 case Mips::ANDI16_MM:
1552 Opnd = Inst.getOperand(2);
1554 return Error(IDLoc, "expected immediate operand kind");
1555 Imm = Opnd.getImm();
1556 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1557 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1558 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1559 return Error(IDLoc, "immediate operand value out of range");
1561 case Mips::LBU16_MM:
1562 Opnd = Inst.getOperand(2);
1564 return Error(IDLoc, "expected immediate operand kind");
1565 Imm = Opnd.getImm();
1566 if (Imm < -1 || Imm > 14)
1567 return Error(IDLoc, "immediate operand value out of range");
1570 Opnd = Inst.getOperand(2);
1572 return Error(IDLoc, "expected immediate operand kind");
1573 Imm = Opnd.getImm();
1574 if (Imm < 0 || Imm > 15)
1575 return Error(IDLoc, "immediate operand value out of range");
1577 case Mips::LHU16_MM:
1579 Opnd = Inst.getOperand(2);
1581 return Error(IDLoc, "expected immediate operand kind");
1582 Imm = Opnd.getImm();
1583 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1584 return Error(IDLoc, "immediate operand value out of range");
1588 Opnd = Inst.getOperand(2);
1590 return Error(IDLoc, "expected immediate operand kind");
1591 Imm = Opnd.getImm();
1592 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1593 return Error(IDLoc, "immediate operand value out of range");
1597 Opnd = Inst.getOperand(2);
1599 return Error(IDLoc, "expected immediate operand kind");
1600 Imm = Opnd.getImm();
1601 if (!isUInt<5>(Imm))
1602 return Error(IDLoc, "immediate operand value out of range");
1604 case Mips::ADDIUPC_MM:
1605 MCOperand Opnd = Inst.getOperand(1);
1607 return Error(IDLoc, "expected immediate operand kind");
1608 int Imm = Opnd.getImm();
1609 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1610 return Error(IDLoc, "immediate operand value out of range");
1615 if (needsExpansion(Inst)) {
1616 if (expandInstruction(Inst, IDLoc, Instructions))
1619 Instructions.push_back(Inst);
1621 // If this instruction has a delay slot and .set reorder is active,
1622 // emit a NOP after it.
1623 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1624 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1629 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1631 switch (Inst.getOpcode()) {
1632 case Mips::LoadImm32:
1633 case Mips::LoadImm64:
1634 case Mips::LoadAddrImm32:
1635 case Mips::LoadAddrReg32:
1636 case Mips::B_MM_Pseudo:
1639 case Mips::JalOneReg:
1640 case Mips::JalTwoReg:
1658 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1659 SmallVectorImpl<MCInst> &Instructions) {
1660 switch (Inst.getOpcode()) {
1661 default: llvm_unreachable("unimplemented expansion");
1662 case Mips::LoadImm32:
1663 return expandLoadImm(Inst, true, IDLoc, Instructions);
1664 case Mips::LoadImm64:
1665 return expandLoadImm(Inst, false, IDLoc, Instructions);
1666 case Mips::LoadAddrImm32:
1667 return expandLoadAddressImm(Inst, true, IDLoc, Instructions);
1668 case Mips::LoadAddrReg32:
1669 return expandLoadAddressReg(Inst, true, IDLoc, Instructions);
1670 case Mips::B_MM_Pseudo:
1671 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1674 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1675 case Mips::JalOneReg:
1676 case Mips::JalTwoReg:
1677 return expandJalWithRegs(Inst, IDLoc, Instructions);
1680 return expandBranchImm(Inst, IDLoc, Instructions);
1689 return expandCondBranches(Inst, IDLoc, Instructions);
1691 return expandUlhu(Inst, IDLoc, Instructions);
1696 template <unsigned ShiftAmount>
1697 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1698 SmallVectorImpl<MCInst> &Instructions) {
1700 if (ShiftAmount >= 32) {
1701 tmpInst.setOpcode(Mips::DSLL32);
1702 tmpInst.addOperand(MCOperand::createReg(RegNo));
1703 tmpInst.addOperand(MCOperand::createReg(RegNo));
1704 tmpInst.addOperand(MCOperand::createImm(ShiftAmount - 32));
1705 tmpInst.setLoc(IDLoc);
1706 Instructions.push_back(tmpInst);
1708 } else if (ShiftAmount > 0) {
1709 tmpInst.setOpcode(Mips::DSLL);
1710 tmpInst.addOperand(MCOperand::createReg(RegNo));
1711 tmpInst.addOperand(MCOperand::createReg(RegNo));
1712 tmpInst.addOperand(MCOperand::createImm(ShiftAmount));
1713 tmpInst.setLoc(IDLoc);
1714 Instructions.push_back(tmpInst);
1717 // There's no need for an ORi if the immediate is 0.
1718 if (Operand.isImm() && Operand.getImm() == 0)
1721 tmpInst.setOpcode(Mips::ORi);
1722 tmpInst.addOperand(MCOperand::createReg(RegNo));
1723 tmpInst.addOperand(MCOperand::createReg(RegNo));
1724 tmpInst.addOperand(Operand);
1725 tmpInst.setLoc(IDLoc);
1726 Instructions.push_back(tmpInst);
1729 template <unsigned ShiftAmount>
1730 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1731 SmallVectorImpl<MCInst> &Instructions) {
1732 createLShiftOri<ShiftAmount>(MCOperand::createImm(Value), RegNo, IDLoc,
1737 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1738 SmallVectorImpl<MCInst> &Instructions) {
1739 // Create a JALR instruction which is going to replace the pseudo-JAL.
1741 JalrInst.setLoc(IDLoc);
1742 const MCOperand FirstRegOp = Inst.getOperand(0);
1743 const unsigned Opcode = Inst.getOpcode();
1745 if (Opcode == Mips::JalOneReg) {
1746 // jal $rs => jalr $rs
1747 if (inMicroMipsMode()) {
1748 JalrInst.setOpcode(Mips::JALR16_MM);
1749 JalrInst.addOperand(FirstRegOp);
1751 JalrInst.setOpcode(Mips::JALR);
1752 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1753 JalrInst.addOperand(FirstRegOp);
1755 } else if (Opcode == Mips::JalTwoReg) {
1756 // jal $rd, $rs => jalr $rd, $rs
1757 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1758 JalrInst.addOperand(FirstRegOp);
1759 const MCOperand SecondRegOp = Inst.getOperand(1);
1760 JalrInst.addOperand(SecondRegOp);
1762 Instructions.push_back(JalrInst);
1764 // If .set reorder is active, emit a NOP after it.
1765 if (AssemblerOptions.back()->isReorder()) {
1766 // This is a 32-bit NOP because these 2 pseudo-instructions
1767 // do not have a short delay slot.
1769 NopInst.setOpcode(Mips::SLL);
1770 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1771 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
1772 NopInst.addOperand(MCOperand::createImm(0));
1773 Instructions.push_back(NopInst);
1779 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
1780 unsigned SrcReg, bool Is32BitImm, SMLoc IDLoc,
1781 SmallVectorImpl<MCInst> &Instructions) {
1782 if (!Is32BitImm && !isGP64bit()) {
1783 Error(IDLoc, "instruction requires a 64-bit architecture");
1787 bool UseSrcReg = false;
1788 if (SrcReg != Mips::NoRegister)
1793 unsigned TmpReg = DstReg;
1794 if (UseSrcReg && (DstReg == SrcReg)) {
1795 // At this point we need AT to perform the expansions and we exit if it is
1797 unsigned ATReg = getATReg(IDLoc);
1803 tmpInst.setLoc(IDLoc);
1804 // FIXME: gas has a special case for values that are 000...1111, which
1805 // becomes a li -1 and then a dsrl
1806 if (0 <= ImmValue && ImmValue <= 65535) {
1807 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1808 // li d,j => ori d,$zero,j
1810 SrcReg = isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
1811 tmpInst.setOpcode(Mips::ORi);
1812 tmpInst.addOperand(MCOperand::createReg(DstReg));
1813 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1814 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1815 Instructions.push_back(tmpInst);
1816 } else if (ImmValue < 0 && ImmValue >= -32768) {
1817 // For negative signed 16-bit values (-32768 <= j < 0):
1818 // li d,j => addiu d,$zero,j
1820 SrcReg = Mips::ZERO;
1821 tmpInst.setOpcode(Mips::ADDiu);
1822 tmpInst.addOperand(MCOperand::createReg(DstReg));
1823 tmpInst.addOperand(MCOperand::createReg(SrcReg));
1824 tmpInst.addOperand(MCOperand::createImm(ImmValue));
1825 Instructions.push_back(tmpInst);
1826 } else if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
1827 warnIfNoMacro(IDLoc);
1829 // For all other values which are representable as a 32-bit integer:
1830 // li d,j => lui d,hi16(j)
1832 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1833 uint16_t Bits15To0 = ImmValue & 0xffff;
1835 if (!Is32BitImm && !isInt<32>(ImmValue)) {
1836 // For DLI, expand to an ORi instead of a LUi to avoid sign-extending the
1838 tmpInst.setOpcode(Mips::ORi);
1839 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1840 tmpInst.addOperand(MCOperand::createReg(Mips::ZERO));
1841 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1842 tmpInst.setLoc(IDLoc);
1843 Instructions.push_back(tmpInst);
1844 // Move the value to the upper 16 bits by doing a 16-bit left shift.
1845 createLShiftOri<16>(0, TmpReg, IDLoc, Instructions);
1847 tmpInst.setOpcode(Mips::LUi);
1848 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1849 tmpInst.addOperand(MCOperand::createImm(Bits31To16));
1850 Instructions.push_back(tmpInst);
1852 createLShiftOri<0>(Bits15To0, TmpReg, IDLoc, Instructions);
1855 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1857 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1859 Error(IDLoc, "instruction requires a 32-bit immediate");
1862 warnIfNoMacro(IDLoc);
1864 // <------- lo32 ------>
1865 // <------- hi32 ------>
1866 // <- hi16 -> <- lo16 ->
1867 // _________________________________
1869 // | 16-bits | 16-bits | 16-bits |
1870 // |__________|__________|__________|
1872 // For any 64-bit value that is representable as a 48-bit integer:
1873 // li d,j => lui d,hi16(j)
1874 // ori d,d,hi16(lo32(j))
1876 // ori d,d,lo16(lo32(j))
1877 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1878 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1879 uint16_t Bits15To0 = ImmValue & 0xffff;
1881 tmpInst.setOpcode(Mips::LUi);
1882 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1883 tmpInst.addOperand(MCOperand::createImm(Bits47To32));
1884 Instructions.push_back(tmpInst);
1885 createLShiftOri<0>(Bits31To16, TmpReg, IDLoc, Instructions);
1886 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1889 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1893 Error(IDLoc, "instruction requires a 32-bit immediate");
1896 warnIfNoMacro(IDLoc);
1898 // <------- hi32 ------> <------- lo32 ------>
1899 // <- hi16 -> <- lo16 ->
1900 // ___________________________________________
1902 // | 16-bits | 16-bits | 16-bits | 16-bits |
1903 // |__________|__________|__________|__________|
1905 // For all other values which are representable as a 64-bit integer:
1906 // li d,j => lui d,hi16(j)
1907 // ori d,d,lo16(hi32(j))
1909 // ori d,d,hi16(lo32(j))
1911 // ori d,d,lo16(lo32(j))
1912 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1913 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1914 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1915 uint16_t Bits15To0 = ImmValue & 0xffff;
1917 tmpInst.setOpcode(Mips::LUi);
1918 tmpInst.addOperand(MCOperand::createReg(TmpReg));
1919 tmpInst.addOperand(MCOperand::createImm(Bits63To48));
1920 Instructions.push_back(tmpInst);
1921 createLShiftOri<0>(Bits47To32, TmpReg, IDLoc, Instructions);
1923 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1924 // two left shifts of 16 bits.
1925 if (Bits31To16 == 0) {
1926 createLShiftOri<32>(Bits15To0, TmpReg, IDLoc, Instructions);
1928 createLShiftOri<16>(Bits31To16, TmpReg, IDLoc, Instructions);
1929 createLShiftOri<16>(Bits15To0, TmpReg, IDLoc, Instructions);
1933 createAddu(DstReg, TmpReg, SrcReg, !Is32BitImm, Instructions);
1938 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1939 SmallVectorImpl<MCInst> &Instructions) {
1940 const MCOperand &ImmOp = Inst.getOperand(1);
1941 assert(ImmOp.isImm() && "expected immediate operand kind");
1942 const MCOperand &DstRegOp = Inst.getOperand(0);
1943 assert(DstRegOp.isReg() && "expected register operand kind");
1945 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1946 Is32BitImm, IDLoc, Instructions))
1953 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1954 SmallVectorImpl<MCInst> &Instructions) {
1955 const MCOperand &DstRegOp = Inst.getOperand(0);
1956 assert(DstRegOp.isReg() && "expected register operand kind");
1958 const MCOperand &SrcRegOp = Inst.getOperand(1);
1959 assert(SrcRegOp.isReg() && "expected register operand kind");
1961 const MCOperand &ImmOp = Inst.getOperand(2);
1962 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1963 "expected immediate operand kind");
1964 if (!ImmOp.isImm()) {
1965 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1966 SrcRegOp.getReg(), Is32BitImm, IDLoc,
1973 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), SrcRegOp.getReg(),
1974 Is32BitImm, IDLoc, Instructions))
1981 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1982 SmallVectorImpl<MCInst> &Instructions) {
1983 const MCOperand &DstRegOp = Inst.getOperand(0);
1984 assert(DstRegOp.isReg() && "expected register operand kind");
1986 const MCOperand &ImmOp = Inst.getOperand(1);
1987 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1988 "expected immediate operand kind");
1989 if (!ImmOp.isImm()) {
1990 if (loadAndAddSymbolAddress(ImmOp.getExpr(), DstRegOp.getReg(),
1991 Mips::NoRegister, Is32BitImm, IDLoc,
1998 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
1999 Is32BitImm, IDLoc, Instructions))
2005 bool MipsAsmParser::loadAndAddSymbolAddress(
2006 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2007 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2008 warnIfNoMacro(IDLoc);
2010 if (Is32BitSym && isABI_N64())
2011 Warning(IDLoc, "instruction loads the 32-bit address of a 64-bit symbol");
2014 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2015 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2016 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2017 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2018 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2020 bool UseSrcReg = SrcReg != Mips::NoRegister;
2022 unsigned TmpReg = DstReg;
2023 if (UseSrcReg && (DstReg == SrcReg)) {
2024 // At this point we need AT to perform the expansions and we exit if it is
2026 unsigned ATReg = getATReg(IDLoc);
2033 // If it's a 64-bit architecture, expand to:
2034 // la d,sym => lui d,highest(sym)
2035 // ori d,d,higher(sym)
2037 // ori d,d,hi16(sym)
2039 // ori d,d,lo16(sym)
2040 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2041 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2042 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2043 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2045 tmpInst.setOpcode(Mips::LUi);
2046 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2047 tmpInst.addOperand(MCOperand::createExpr(HighestExpr));
2048 Instructions.push_back(tmpInst);
2050 createLShiftOri<0>(MCOperand::createExpr(HigherExpr), TmpReg, SMLoc(),
2052 createLShiftOri<16>(MCOperand::createExpr(HiExpr), TmpReg, SMLoc(),
2054 createLShiftOri<16>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2057 // Otherwise, expand to:
2058 // la d,sym => lui d,hi16(sym)
2059 // ori d,d,lo16(sym)
2060 tmpInst.setOpcode(Mips::LUi);
2061 tmpInst.addOperand(MCOperand::createReg(TmpReg));
2062 tmpInst.addOperand(MCOperand::createExpr(HiExpr));
2063 Instructions.push_back(tmpInst);
2065 createLShiftOri<0>(MCOperand::createExpr(LoExpr), TmpReg, SMLoc(),
2070 createAddu(DstReg, TmpReg, SrcReg, !Is32BitSym, Instructions);
2075 bool MipsAsmParser::expandUncondBranchMMPseudo(
2076 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2077 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2078 "unexpected number of operands");
2080 MCOperand Offset = Inst.getOperand(0);
2081 if (Offset.isExpr()) {
2083 Inst.setOpcode(Mips::BEQ_MM);
2084 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2085 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2086 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2088 assert(Offset.isImm() && "expected immediate operand kind");
2089 if (isIntN(11, Offset.getImm())) {
2090 // If offset fits into 11 bits then this instruction becomes microMIPS
2091 // 16-bit unconditional branch instruction.
2092 Inst.setOpcode(Mips::B16_MM);
2094 if (!isIntN(17, Offset.getImm()))
2095 Error(IDLoc, "branch target out of range");
2096 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2097 Error(IDLoc, "branch to misaligned address");
2099 Inst.setOpcode(Mips::BEQ_MM);
2100 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2101 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2102 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2105 Instructions.push_back(Inst);
2107 // If .set reorder is active, emit a NOP after the branch instruction.
2108 if (AssemblerOptions.back()->isReorder())
2109 createNop(true, IDLoc, Instructions);
2114 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2115 SmallVectorImpl<MCInst> &Instructions) {
2116 const MCOperand &DstRegOp = Inst.getOperand(0);
2117 assert(DstRegOp.isReg() && "expected register operand kind");
2119 const MCOperand &ImmOp = Inst.getOperand(1);
2120 assert(ImmOp.isImm() && "expected immediate operand kind");
2122 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2123 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2125 unsigned OpCode = 0;
2126 switch(Inst.getOpcode()) {
2134 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2138 int64_t ImmValue = ImmOp.getImm();
2139 if (ImmValue == 0) {
2141 BranchInst.setOpcode(OpCode);
2142 BranchInst.addOperand(DstRegOp);
2143 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2144 BranchInst.addOperand(MemOffsetOp);
2145 Instructions.push_back(BranchInst);
2147 warnIfNoMacro(IDLoc);
2149 unsigned ATReg = getATReg(IDLoc);
2153 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), IDLoc,
2158 BranchInst.setOpcode(OpCode);
2159 BranchInst.addOperand(DstRegOp);
2160 BranchInst.addOperand(MCOperand::createReg(ATReg));
2161 BranchInst.addOperand(MemOffsetOp);
2162 Instructions.push_back(BranchInst);
2167 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2168 SmallVectorImpl<MCInst> &Instructions,
2169 bool isLoad, bool isImmOpnd) {
2171 unsigned ImmOffset, HiOffset, LoOffset;
2172 const MCExpr *ExprOffset;
2174 // 1st operand is either the source or destination register.
2175 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2176 unsigned RegOpNum = Inst.getOperand(0).getReg();
2177 // 2nd operand is the base register.
2178 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2179 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2180 // 3rd operand is either an immediate or expression.
2182 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2183 ImmOffset = Inst.getOperand(2).getImm();
2184 LoOffset = ImmOffset & 0x0000ffff;
2185 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2186 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2187 if (LoOffset & 0x8000)
2190 ExprOffset = Inst.getOperand(2).getExpr();
2191 // All instructions will have the same location.
2192 TempInst.setLoc(IDLoc);
2193 // These are some of the types of expansions we perform here:
2194 // 1) lw $8, sym => lui $8, %hi(sym)
2195 // lw $8, %lo(sym)($8)
2196 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2198 // lw $8, %lo(offset)($9)
2199 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2201 // lw $8, %lo(offset)($at)
2202 // 4) sw $8, sym => lui $at, %hi(sym)
2203 // sw $8, %lo(sym)($at)
2204 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2206 // sw $8, %lo(offset)($at)
2207 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2208 // ldc1 $f0, %lo(sym)($at)
2210 // For load instructions we can use the destination register as a temporary
2211 // if base and dst are different (examples 1 and 2) and if the base register
2212 // is general purpose otherwise we must use $at (example 6) and error if it's
2213 // not available. For stores we must use $at (examples 4 and 5) because we
2214 // must not clobber the source register setting up the offset.
2215 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2216 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2217 unsigned RegClassIDOp0 =
2218 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2219 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2220 (RegClassIDOp0 == Mips::GPR64RegClassID);
2221 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2222 TmpRegNum = RegOpNum;
2224 // At this point we need AT to perform the expansions and we exit if it is
2226 TmpRegNum = getATReg(IDLoc);
2231 TempInst.setOpcode(Mips::LUi);
2232 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2234 TempInst.addOperand(MCOperand::createImm(HiOffset));
2236 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2237 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2239 // Add the instruction to the list.
2240 Instructions.push_back(TempInst);
2241 // Prepare TempInst for next instruction.
2243 // Add temp register to base.
2244 if (BaseRegNum != Mips::ZERO) {
2245 TempInst.setOpcode(Mips::ADDu);
2246 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2247 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2248 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2249 Instructions.push_back(TempInst);
2252 // And finally, create original instruction with low part
2253 // of offset and new base.
2254 TempInst.setOpcode(Inst.getOpcode());
2255 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2256 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2258 TempInst.addOperand(MCOperand::createImm(LoOffset));
2260 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2261 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2263 Instructions.push_back(TempInst);
2268 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2269 SmallVectorImpl<MCInst> &Instructions) {
2270 unsigned OpNum = Inst.getNumOperands();
2271 unsigned Opcode = Inst.getOpcode();
2272 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2274 assert (Inst.getOperand(OpNum - 1).isImm() &&
2275 Inst.getOperand(OpNum - 2).isReg() &&
2276 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2278 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2279 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2280 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2281 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2282 // It can be implemented as SWM16 or LWM16 instruction.
2283 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2285 Inst.setOpcode(NewOpcode);
2286 Instructions.push_back(Inst);
2290 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2291 SmallVectorImpl<MCInst> &Instructions) {
2292 unsigned PseudoOpcode = Inst.getOpcode();
2293 unsigned SrcReg = Inst.getOperand(0).getReg();
2294 unsigned TrgReg = Inst.getOperand(1).getReg();
2295 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2297 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2298 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2300 switch (PseudoOpcode) {
2303 AcceptsEquality = false;
2304 ReverseOrderSLT = false;
2305 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2306 ZeroSrcOpcode = Mips::BGTZ;
2307 ZeroTrgOpcode = Mips::BLTZ;
2311 AcceptsEquality = true;
2312 ReverseOrderSLT = true;
2313 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2314 ZeroSrcOpcode = Mips::BGEZ;
2315 ZeroTrgOpcode = Mips::BLEZ;
2319 AcceptsEquality = true;
2320 ReverseOrderSLT = false;
2321 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2322 ZeroSrcOpcode = Mips::BLEZ;
2323 ZeroTrgOpcode = Mips::BGEZ;
2327 AcceptsEquality = false;
2328 ReverseOrderSLT = true;
2329 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2330 ZeroSrcOpcode = Mips::BLTZ;
2331 ZeroTrgOpcode = Mips::BGTZ;
2334 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2338 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2339 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2340 if (IsSrcRegZero && IsTrgRegZero) {
2341 // FIXME: All of these Opcode-specific if's are needed for compatibility
2342 // with GAS' behaviour. However, they may not generate the most efficient
2343 // code in some circumstances.
2344 if (PseudoOpcode == Mips::BLT) {
2345 BranchInst.setOpcode(Mips::BLTZ);
2346 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2347 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2348 Instructions.push_back(BranchInst);
2351 if (PseudoOpcode == Mips::BLE) {
2352 BranchInst.setOpcode(Mips::BLEZ);
2353 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2354 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2355 Instructions.push_back(BranchInst);
2356 Warning(IDLoc, "branch is always taken");
2359 if (PseudoOpcode == Mips::BGE) {
2360 BranchInst.setOpcode(Mips::BGEZ);
2361 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2362 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2363 Instructions.push_back(BranchInst);
2364 Warning(IDLoc, "branch is always taken");
2367 if (PseudoOpcode == Mips::BGT) {
2368 BranchInst.setOpcode(Mips::BGTZ);
2369 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2370 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2371 Instructions.push_back(BranchInst);
2374 if (PseudoOpcode == Mips::BGTU) {
2375 BranchInst.setOpcode(Mips::BNE);
2376 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2377 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2378 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2379 Instructions.push_back(BranchInst);
2382 if (AcceptsEquality) {
2383 // If both registers are $0 and the pseudo-branch accepts equality, it
2384 // will always be taken, so we emit an unconditional branch.
2385 BranchInst.setOpcode(Mips::BEQ);
2386 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2387 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2388 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2389 Instructions.push_back(BranchInst);
2390 Warning(IDLoc, "branch is always taken");
2393 // If both registers are $0 and the pseudo-branch does not accept
2394 // equality, it will never be taken, so we don't have to emit anything.
2397 if (IsSrcRegZero || IsTrgRegZero) {
2398 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2399 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2400 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2401 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2402 // the pseudo-branch will never be taken, so we don't emit anything.
2403 // This only applies to unsigned pseudo-branches.
2406 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2407 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2408 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2409 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2410 // the pseudo-branch will always be taken, so we emit an unconditional
2412 // This only applies to unsigned pseudo-branches.
2413 BranchInst.setOpcode(Mips::BEQ);
2414 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2415 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2416 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2417 Instructions.push_back(BranchInst);
2418 Warning(IDLoc, "branch is always taken");
2422 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2423 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2424 // the pseudo-branch will be taken only when the non-zero register is
2425 // different from 0, so we emit a BNEZ.
2427 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2428 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2429 // the pseudo-branch will be taken only when the non-zero register is
2430 // equal to 0, so we emit a BEQZ.
2432 // Because only BLEU and BGEU branch on equality, we can use the
2433 // AcceptsEquality variable to decide when to emit the BEQZ.
2434 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2435 BranchInst.addOperand(
2436 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2437 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2438 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2439 Instructions.push_back(BranchInst);
2442 // If we have a signed pseudo-branch and one of the registers is $0,
2443 // we can use an appropriate compare-to-zero branch. We select which one
2444 // to use in the switch statement above.
2445 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2446 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2447 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2448 Instructions.push_back(BranchInst);
2452 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2453 // expansions. If it is not available, we return.
2454 unsigned ATRegNum = getATReg(IDLoc);
2458 warnIfNoMacro(IDLoc);
2460 // SLT fits well with 2 of our 4 pseudo-branches:
2461 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2462 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2463 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2464 // This is accomplished by using a BNEZ with the result of the SLT.
2466 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2467 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2468 // Because only BGE and BLE branch on equality, we can use the
2469 // AcceptsEquality variable to decide when to emit the BEQZ.
2470 // Note that the order of the SLT arguments doesn't change between
2473 // The same applies to the unsigned variants, except that SLTu is used
2476 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2477 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2478 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2479 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2480 Instructions.push_back(SetInst);
2482 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2483 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2484 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2485 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2486 Instructions.push_back(BranchInst);
2490 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2491 SmallVectorImpl<MCInst> &Instructions) {
2492 if (hasMips32r6() || hasMips64r6()) {
2493 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2497 warnIfNoMacro(IDLoc);
2499 const MCOperand &DstRegOp = Inst.getOperand(0);
2500 assert(DstRegOp.isReg() && "expected register operand kind");
2502 const MCOperand &SrcRegOp = Inst.getOperand(1);
2503 assert(SrcRegOp.isReg() && "expected register operand kind");
2505 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2506 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2508 unsigned DstReg = DstRegOp.getReg();
2509 unsigned SrcReg = SrcRegOp.getReg();
2510 int64_t OffsetValue = OffsetImmOp.getImm();
2512 // NOTE: We always need AT for ULHU, as it is always used as the source
2513 // register for one of the LBu's.
2514 unsigned ATReg = getATReg(IDLoc);
2518 // When the value of offset+1 does not fit in 16 bits, we have to load the
2519 // offset in AT, (D)ADDu the original source register (if there was one), and
2520 // then use AT as the source register for the 2 generated LBu's.
2521 bool LoadedOffsetInAT = false;
2522 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2523 LoadedOffsetInAT = true;
2525 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2526 IDLoc, Instructions))
2529 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2530 // because it will make our output more similar to GAS'. For example,
2531 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2532 // instead of just an "ori $1, $9, 32768".
2533 // NOTE: If there is no source register specified in the ULHU, the parser
2534 // will interpret it as $0.
2535 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2536 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2539 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2540 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2541 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2543 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2545 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2546 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2548 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2549 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2552 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2555 TmpInst.setOpcode(Mips::LBu);
2556 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2557 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2558 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2559 Instructions.push_back(TmpInst);
2562 TmpInst.setOpcode(Mips::LBu);
2563 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2564 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2565 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2566 Instructions.push_back(TmpInst);
2569 TmpInst.setOpcode(Mips::SLL);
2570 TmpInst.addOperand(MCOperand::createReg(SllReg));
2571 TmpInst.addOperand(MCOperand::createReg(SllReg));
2572 TmpInst.addOperand(MCOperand::createImm(8));
2573 Instructions.push_back(TmpInst);
2576 TmpInst.setOpcode(Mips::OR);
2577 TmpInst.addOperand(MCOperand::createReg(DstReg));
2578 TmpInst.addOperand(MCOperand::createReg(DstReg));
2579 TmpInst.addOperand(MCOperand::createReg(ATReg));
2580 Instructions.push_back(TmpInst);
2585 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2586 SmallVectorImpl<MCInst> &Instructions) {
2588 if (hasShortDelaySlot) {
2589 NopInst.setOpcode(Mips::MOVE16_MM);
2590 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2591 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2593 NopInst.setOpcode(Mips::SLL);
2594 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2595 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2596 NopInst.addOperand(MCOperand::createImm(0));
2598 Instructions.push_back(NopInst);
2601 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
2602 unsigned TrgReg, bool Is64Bit,
2603 SmallVectorImpl<MCInst> &Instructions) {
2605 AdduInst.setOpcode(Is64Bit ? Mips::DADDu : Mips::ADDu);
2606 AdduInst.addOperand(MCOperand::createReg(DstReg));
2607 AdduInst.addOperand(MCOperand::createReg(SrcReg));
2608 AdduInst.addOperand(MCOperand::createReg(TrgReg));
2609 Instructions.push_back(AdduInst);
2612 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2613 // As described by the Mips32r2 spec, the registers Rd and Rs for
2614 // jalr.hb must be different.
2615 unsigned Opcode = Inst.getOpcode();
2617 if (Opcode == Mips::JALR_HB &&
2618 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2619 return Match_RequiresDifferentSrcAndDst;
2621 return Match_Success;
2624 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2625 OperandVector &Operands,
2627 uint64_t &ErrorInfo,
2628 bool MatchingInlineAsm) {
2631 SmallVector<MCInst, 8> Instructions;
2632 unsigned MatchResult =
2633 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2635 switch (MatchResult) {
2636 case Match_Success: {
2637 if (processInstruction(Inst, IDLoc, Instructions))
2639 for (unsigned i = 0; i < Instructions.size(); i++)
2640 Out.EmitInstruction(Instructions[i], STI);
2643 case Match_MissingFeature:
2644 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2646 case Match_InvalidOperand: {
2647 SMLoc ErrorLoc = IDLoc;
2648 if (ErrorInfo != ~0ULL) {
2649 if (ErrorInfo >= Operands.size())
2650 return Error(IDLoc, "too few operands for instruction");
2652 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2653 if (ErrorLoc == SMLoc())
2657 return Error(ErrorLoc, "invalid operand for instruction");
2659 case Match_MnemonicFail:
2660 return Error(IDLoc, "invalid instruction");
2661 case Match_RequiresDifferentSrcAndDst:
2662 return Error(IDLoc, "source and destination must be different");
2665 llvm_unreachable("Implement any new match types added!");
2668 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2669 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2670 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2671 ") without \".set noat\"");
2674 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
2675 if (!AssemblerOptions.back()->isMacro())
2676 Warning(Loc, "macro instruction expanded into multiple instructions");
2680 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2681 SMRange Range, bool ShowColors) {
2682 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2683 Range, SMFixIt(Range, FixMsg),
2687 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2690 CC = StringSwitch<unsigned>(Name)
2726 if (!(isABI_N32() || isABI_N64()))
2729 if (12 <= CC && CC <= 15) {
2730 // Name is one of t4-t7
2731 AsmToken RegTok = getLexer().peekTok();
2732 SMRange RegRange = RegTok.getLocRange();
2734 StringRef FixedName = StringSwitch<StringRef>(Name)
2740 assert(FixedName != "" && "Register name is not one of t4-t7.");
2742 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2743 "Did you mean $" + FixedName + "?", RegRange);
2746 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2747 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2748 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2749 if (8 <= CC && CC <= 11)
2753 CC = StringSwitch<unsigned>(Name)
2765 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2768 CC = StringSwitch<unsigned>(Name)
2769 .Case("hwr_cpunum", 0)
2770 .Case("hwr_synci_step", 1)
2772 .Case("hwr_ccres", 3)
2773 .Case("hwr_ulr", 29)
2779 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2781 if (Name[0] == 'f') {
2782 StringRef NumString = Name.substr(1);
2784 if (NumString.getAsInteger(10, IntVal))
2785 return -1; // This is not an integer.
2786 if (IntVal > 31) // Maximum index for fpu register.
2793 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2795 if (Name.startswith("fcc")) {
2796 StringRef NumString = Name.substr(3);
2798 if (NumString.getAsInteger(10, IntVal))
2799 return -1; // This is not an integer.
2800 if (IntVal > 7) // There are only 8 fcc registers.
2807 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2809 if (Name.startswith("ac")) {
2810 StringRef NumString = Name.substr(2);
2812 if (NumString.getAsInteger(10, IntVal))
2813 return -1; // This is not an integer.
2814 if (IntVal > 3) // There are only 3 acc registers.
2821 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2824 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2833 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2836 CC = StringSwitch<unsigned>(Name)
2839 .Case("msaaccess", 2)
2841 .Case("msamodify", 4)
2842 .Case("msarequest", 5)
2844 .Case("msaunmap", 7)
2850 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2851 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2853 reportParseError(Loc,
2854 "pseudo-instruction requires $at, which is not available");
2857 unsigned AT = getReg(
2858 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2862 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2863 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2866 unsigned MipsAsmParser::getGPR(int RegNo) {
2867 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2871 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2873 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2876 return getReg(RegClass, RegNum);
2879 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2880 MCAsmParser &Parser = getParser();
2881 DEBUG(dbgs() << "parseOperand\n");
2883 // Check if the current operand has a custom associated parser, if so, try to
2884 // custom parse the operand, or fallback to the general approach.
2885 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2886 if (ResTy == MatchOperand_Success)
2888 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2889 // there was a match, but an error occurred, in which case, just return that
2890 // the operand parsing failed.
2891 if (ResTy == MatchOperand_ParseFail)
2894 DEBUG(dbgs() << ".. Generic Parser\n");
2896 switch (getLexer().getKind()) {
2898 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2900 case AsmToken::Dollar: {
2901 // Parse the register.
2902 SMLoc S = Parser.getTok().getLoc();
2904 // Almost all registers have been parsed by custom parsers. There is only
2905 // one exception to this. $zero (and it's alias $0) will reach this point
2906 // for div, divu, and similar instructions because it is not an operand
2907 // to the instruction definition but an explicit register. Special case
2908 // this situation for now.
2909 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2912 // Maybe it is a symbol reference.
2913 StringRef Identifier;
2914 if (Parser.parseIdentifier(Identifier))
2917 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2918 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
2919 // Otherwise create a symbol reference.
2921 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
2923 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2926 // Else drop to expression parsing.
2927 case AsmToken::LParen:
2928 case AsmToken::Minus:
2929 case AsmToken::Plus:
2930 case AsmToken::Integer:
2931 case AsmToken::Tilde:
2932 case AsmToken::String: {
2933 DEBUG(dbgs() << ".. generic integer\n");
2934 OperandMatchResultTy ResTy = parseImm(Operands);
2935 return ResTy != MatchOperand_Success;
2937 case AsmToken::Percent: {
2938 // It is a symbol reference or constant expression.
2939 const MCExpr *IdVal;
2940 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2941 if (parseRelocOperand(IdVal))
2944 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2946 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2948 } // case AsmToken::Percent
2949 } // switch(getLexer().getKind())
2953 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2954 StringRef RelocStr) {
2956 // Check the type of the expression.
2957 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2958 // It's a constant, evaluate reloc value.
2960 switch (getVariantKind(RelocStr)) {
2961 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2962 // Get the 1st 16-bits.
2963 Val = MCE->getValue() & 0xffff;
2965 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2966 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2967 // 16 bits being negative.
2968 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2970 case MCSymbolRefExpr::VK_Mips_HIGHER:
2971 // Get the 3rd 16-bits.
2972 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2974 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2975 // Get the 4th 16-bits.
2976 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2979 report_fatal_error("unsupported reloc value");
2981 return MCConstantExpr::create(Val, getContext());
2984 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2985 // It's a symbol, create a symbolic expression from the symbol.
2986 const MCSymbol *Symbol = &MSRE->getSymbol();
2987 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2988 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
2992 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2993 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2995 // Try to create target expression.
2996 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2997 return MipsMCExpr::create(VK, Expr, getContext());
2999 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3000 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3001 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3005 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3006 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3007 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3010 // Just return the original expression.
3014 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3016 switch (Expr->getKind()) {
3017 case MCExpr::Constant:
3019 case MCExpr::SymbolRef:
3020 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3021 case MCExpr::Binary:
3022 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3023 if (!isEvaluated(BE->getLHS()))
3025 return isEvaluated(BE->getRHS());
3028 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3029 case MCExpr::Target:
3035 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3036 MCAsmParser &Parser = getParser();
3037 Parser.Lex(); // Eat the % token.
3038 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3039 if (Tok.isNot(AsmToken::Identifier))
3042 std::string Str = Tok.getIdentifier();
3044 Parser.Lex(); // Eat the identifier.
3045 // Now make an expression from the rest of the operand.
3046 const MCExpr *IdVal;
3049 if (getLexer().getKind() == AsmToken::LParen) {
3051 Parser.Lex(); // Eat the '(' token.
3052 if (getLexer().getKind() == AsmToken::Percent) {
3053 Parser.Lex(); // Eat the % token.
3054 const AsmToken &nextTok = Parser.getTok();
3055 if (nextTok.isNot(AsmToken::Identifier))
3058 Str += nextTok.getIdentifier();
3059 Parser.Lex(); // Eat the identifier.
3060 if (getLexer().getKind() != AsmToken::LParen)
3065 if (getParser().parseParenExpression(IdVal, EndLoc))
3068 while (getLexer().getKind() == AsmToken::RParen)
3069 Parser.Lex(); // Eat the ')' token.
3072 return true; // Parenthesis must follow the relocation operand.
3074 Res = evaluateRelocExpr(IdVal, Str);
3078 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3080 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3081 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3082 if (ResTy == MatchOperand_Success) {
3083 assert(Operands.size() == 1);
3084 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3085 StartLoc = Operand.getStartLoc();
3086 EndLoc = Operand.getEndLoc();
3088 // AFAIK, we only support numeric registers and named GPR's in CFI
3090 // Don't worry about eating tokens before failing. Using an unrecognised
3091 // register is a parse error.
3092 if (Operand.isGPRAsmReg()) {
3093 // Resolve to GPR32 or GPR64 appropriately.
3094 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3097 return (RegNo == (unsigned)-1);
3100 assert(Operands.size() == 0);
3101 return (RegNo == (unsigned)-1);
3104 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3105 MCAsmParser &Parser = getParser();
3108 unsigned NumOfLParen = 0;
3110 while (getLexer().getKind() == AsmToken::LParen) {
3115 switch (getLexer().getKind()) {
3118 case AsmToken::Identifier:
3119 case AsmToken::LParen:
3120 case AsmToken::Integer:
3121 case AsmToken::Minus:
3122 case AsmToken::Plus:
3124 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3126 Result = (getParser().parseExpression(Res));
3127 while (getLexer().getKind() == AsmToken::RParen)
3130 case AsmToken::Percent:
3131 Result = parseRelocOperand(Res);
3136 MipsAsmParser::OperandMatchResultTy
3137 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3138 MCAsmParser &Parser = getParser();
3139 DEBUG(dbgs() << "parseMemOperand\n");
3140 const MCExpr *IdVal = nullptr;
3142 bool isParenExpr = false;
3143 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3144 // First operand is the offset.
3145 S = Parser.getTok().getLoc();
3147 if (getLexer().getKind() == AsmToken::LParen) {
3152 if (getLexer().getKind() != AsmToken::Dollar) {
3153 if (parseMemOffset(IdVal, isParenExpr))
3154 return MatchOperand_ParseFail;
3156 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3157 if (Tok.isNot(AsmToken::LParen)) {
3158 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3159 if (Mnemonic.getToken() == "la") {
3161 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3162 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3163 return MatchOperand_Success;
3165 if (Tok.is(AsmToken::EndOfStatement)) {
3167 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3169 // Zero register assumed, add a memory operand with ZERO as its base.
3170 // "Base" will be managed by k_Memory.
3171 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3174 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3175 return MatchOperand_Success;
3177 Error(Parser.getTok().getLoc(), "'(' expected");
3178 return MatchOperand_ParseFail;
3181 Parser.Lex(); // Eat the '(' token.
3184 Res = parseAnyRegister(Operands);
3185 if (Res != MatchOperand_Success)
3188 if (Parser.getTok().isNot(AsmToken::RParen)) {
3189 Error(Parser.getTok().getLoc(), "')' expected");
3190 return MatchOperand_ParseFail;
3193 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3195 Parser.Lex(); // Eat the ')' token.
3198 IdVal = MCConstantExpr::create(0, getContext());
3200 // Replace the register operand with the memory operand.
3201 std::unique_ptr<MipsOperand> op(
3202 static_cast<MipsOperand *>(Operands.back().release()));
3203 // Remove the register from the operands.
3204 // "op" will be managed by k_Memory.
3205 Operands.pop_back();
3206 // Add the memory operand.
3207 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3209 if (IdVal->evaluateAsAbsolute(Imm))
3210 IdVal = MCConstantExpr::create(Imm, getContext());
3211 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3212 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3216 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3217 return MatchOperand_Success;
3220 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3221 MCAsmParser &Parser = getParser();
3222 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3224 SMLoc S = Parser.getTok().getLoc();
3226 if (Sym->isVariable())
3227 Expr = Sym->getVariableValue();
3230 if (Expr->getKind() == MCExpr::SymbolRef) {
3231 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3232 StringRef DefSymbol = Ref->getSymbol().getName();
3233 if (DefSymbol.startswith("$")) {
3234 OperandMatchResultTy ResTy =
3235 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3236 if (ResTy == MatchOperand_Success) {
3239 } else if (ResTy == MatchOperand_ParseFail)
3240 llvm_unreachable("Should never ParseFail");
3243 } else if (Expr->getKind() == MCExpr::Constant) {
3245 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3247 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3254 MipsAsmParser::OperandMatchResultTy
3255 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3256 StringRef Identifier,
3258 int Index = matchCPURegisterName(Identifier);
3260 Operands.push_back(MipsOperand::createGPRReg(
3261 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3262 return MatchOperand_Success;
3265 Index = matchHWRegsRegisterName(Identifier);
3267 Operands.push_back(MipsOperand::createHWRegsReg(
3268 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3269 return MatchOperand_Success;
3272 Index = matchFPURegisterName(Identifier);
3274 Operands.push_back(MipsOperand::createFGRReg(
3275 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3276 return MatchOperand_Success;
3279 Index = matchFCCRegisterName(Identifier);
3281 Operands.push_back(MipsOperand::createFCCReg(
3282 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3283 return MatchOperand_Success;
3286 Index = matchACRegisterName(Identifier);
3288 Operands.push_back(MipsOperand::createACCReg(
3289 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3290 return MatchOperand_Success;
3293 Index = matchMSA128RegisterName(Identifier);
3295 Operands.push_back(MipsOperand::createMSA128Reg(
3296 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3297 return MatchOperand_Success;
3300 Index = matchMSA128CtrlRegisterName(Identifier);
3302 Operands.push_back(MipsOperand::createMSACtrlReg(
3303 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3304 return MatchOperand_Success;
3307 return MatchOperand_NoMatch;
3310 MipsAsmParser::OperandMatchResultTy
3311 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3312 MCAsmParser &Parser = getParser();
3313 auto Token = Parser.getLexer().peekTok(false);
3315 if (Token.is(AsmToken::Identifier)) {
3316 DEBUG(dbgs() << ".. identifier\n");
3317 StringRef Identifier = Token.getIdentifier();
3318 OperandMatchResultTy ResTy =
3319 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3321 } else if (Token.is(AsmToken::Integer)) {
3322 DEBUG(dbgs() << ".. integer\n");
3323 Operands.push_back(MipsOperand::createNumericReg(
3324 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3326 return MatchOperand_Success;
3329 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3331 return MatchOperand_NoMatch;
3334 MipsAsmParser::OperandMatchResultTy
3335 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3336 MCAsmParser &Parser = getParser();
3337 DEBUG(dbgs() << "parseAnyRegister\n");
3339 auto Token = Parser.getTok();
3341 SMLoc S = Token.getLoc();
3343 if (Token.isNot(AsmToken::Dollar)) {
3344 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3345 if (Token.is(AsmToken::Identifier)) {
3346 if (searchSymbolAlias(Operands))
3347 return MatchOperand_Success;
3349 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3350 return MatchOperand_NoMatch;
3352 DEBUG(dbgs() << ".. $\n");
3354 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3355 if (ResTy == MatchOperand_Success) {
3357 Parser.Lex(); // identifier
3362 MipsAsmParser::OperandMatchResultTy
3363 MipsAsmParser::parseImm(OperandVector &Operands) {
3364 MCAsmParser &Parser = getParser();
3365 switch (getLexer().getKind()) {
3367 return MatchOperand_NoMatch;
3368 case AsmToken::LParen:
3369 case AsmToken::Minus:
3370 case AsmToken::Plus:
3371 case AsmToken::Integer:
3372 case AsmToken::Tilde:
3373 case AsmToken::String:
3377 const MCExpr *IdVal;
3378 SMLoc S = Parser.getTok().getLoc();
3379 if (getParser().parseExpression(IdVal))
3380 return MatchOperand_ParseFail;
3382 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3383 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3384 return MatchOperand_Success;
3387 MipsAsmParser::OperandMatchResultTy
3388 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3389 MCAsmParser &Parser = getParser();
3390 DEBUG(dbgs() << "parseJumpTarget\n");
3392 SMLoc S = getLexer().getLoc();
3394 // Integers and expressions are acceptable
3395 OperandMatchResultTy ResTy = parseImm(Operands);
3396 if (ResTy != MatchOperand_NoMatch)
3399 // Registers are a valid target and have priority over symbols.
3400 ResTy = parseAnyRegister(Operands);
3401 if (ResTy != MatchOperand_NoMatch)
3404 const MCExpr *Expr = nullptr;
3405 if (Parser.parseExpression(Expr)) {
3406 // We have no way of knowing if a symbol was consumed so we must ParseFail
3407 return MatchOperand_ParseFail;
3410 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3411 return MatchOperand_Success;
3414 MipsAsmParser::OperandMatchResultTy
3415 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3416 MCAsmParser &Parser = getParser();
3417 const MCExpr *IdVal;
3418 // If the first token is '$' we may have register operand.
3419 if (Parser.getTok().is(AsmToken::Dollar))
3420 return MatchOperand_NoMatch;
3421 SMLoc S = Parser.getTok().getLoc();
3422 if (getParser().parseExpression(IdVal))
3423 return MatchOperand_ParseFail;
3424 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3425 assert(MCE && "Unexpected MCExpr type.");
3426 int64_t Val = MCE->getValue();
3427 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3428 Operands.push_back(MipsOperand::CreateImm(
3429 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3430 return MatchOperand_Success;
3433 MipsAsmParser::OperandMatchResultTy
3434 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3435 MCAsmParser &Parser = getParser();
3436 switch (getLexer().getKind()) {
3438 return MatchOperand_NoMatch;
3439 case AsmToken::LParen:
3440 case AsmToken::Plus:
3441 case AsmToken::Minus:
3442 case AsmToken::Integer:
3447 SMLoc S = Parser.getTok().getLoc();
3449 if (getParser().parseExpression(Expr))
3450 return MatchOperand_ParseFail;
3453 if (!Expr->evaluateAsAbsolute(Val)) {
3454 Error(S, "expected immediate value");
3455 return MatchOperand_ParseFail;
3458 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3459 // and because the CPU always adds one to the immediate field, the allowed
3460 // range becomes 1..4. We'll only check the range here and will deal
3461 // with the addition/subtraction when actually decoding/encoding
3463 if (Val < 1 || Val > 4) {
3464 Error(S, "immediate not in range (1..4)");
3465 return MatchOperand_ParseFail;
3469 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3470 return MatchOperand_Success;
3473 MipsAsmParser::OperandMatchResultTy
3474 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3475 MCAsmParser &Parser = getParser();
3476 SmallVector<unsigned, 10> Regs;
3478 unsigned PrevReg = Mips::NoRegister;
3479 bool RegRange = false;
3480 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3482 if (Parser.getTok().isNot(AsmToken::Dollar))
3483 return MatchOperand_ParseFail;
3485 SMLoc S = Parser.getTok().getLoc();
3486 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3487 SMLoc E = getLexer().getLoc();
3488 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3489 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3491 // Remove last register operand because registers from register range
3492 // should be inserted first.
3493 if (RegNo == Mips::RA) {
3494 Regs.push_back(RegNo);
3496 unsigned TmpReg = PrevReg + 1;
3497 while (TmpReg <= RegNo) {
3498 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3499 Error(E, "invalid register operand");
3500 return MatchOperand_ParseFail;
3504 Regs.push_back(TmpReg++);
3510 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3511 (RegNo != Mips::RA)) {
3512 Error(E, "$16 or $31 expected");
3513 return MatchOperand_ParseFail;
3514 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3515 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3516 Error(E, "invalid register operand");
3517 return MatchOperand_ParseFail;
3518 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3519 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3520 Error(E, "consecutive register numbers expected");
3521 return MatchOperand_ParseFail;
3524 Regs.push_back(RegNo);
3527 if (Parser.getTok().is(AsmToken::Minus))
3530 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3531 !Parser.getTok().isNot(AsmToken::Comma)) {
3532 Error(E, "',' or '-' expected");
3533 return MatchOperand_ParseFail;
3536 Lex(); // Consume comma or minus
3537 if (Parser.getTok().isNot(AsmToken::Dollar))
3543 SMLoc E = Parser.getTok().getLoc();
3544 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3545 parseMemOperand(Operands);
3546 return MatchOperand_Success;
3549 MipsAsmParser::OperandMatchResultTy
3550 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3551 MCAsmParser &Parser = getParser();
3553 SMLoc S = Parser.getTok().getLoc();
3554 if (parseAnyRegister(Operands) != MatchOperand_Success)
3555 return MatchOperand_ParseFail;
3557 SMLoc E = Parser.getTok().getLoc();
3558 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3559 unsigned Reg = Op.getGPR32Reg();
3560 Operands.pop_back();
3561 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3562 return MatchOperand_Success;
3565 MipsAsmParser::OperandMatchResultTy
3566 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3567 MCAsmParser &Parser = getParser();
3568 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3569 SmallVector<unsigned, 10> Regs;
3571 if (Parser.getTok().isNot(AsmToken::Dollar))
3572 return MatchOperand_ParseFail;
3574 SMLoc S = Parser.getTok().getLoc();
3576 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3577 return MatchOperand_ParseFail;
3579 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3580 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3581 Regs.push_back(RegNo);
3583 SMLoc E = Parser.getTok().getLoc();
3584 if (Parser.getTok().isNot(AsmToken::Comma)) {
3585 Error(E, "',' expected");
3586 return MatchOperand_ParseFail;
3592 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3593 return MatchOperand_ParseFail;
3595 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3596 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3597 Regs.push_back(RegNo);
3599 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3601 return MatchOperand_Success;
3604 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3606 MCSymbolRefExpr::VariantKind VK =
3607 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3608 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3609 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3610 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3611 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3612 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3613 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3614 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3615 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3616 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3617 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3618 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3619 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3620 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3621 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3622 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3623 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3624 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3625 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3626 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3627 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3628 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3629 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3630 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3631 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3632 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3633 .Default(MCSymbolRefExpr::VK_None);
3635 assert(VK != MCSymbolRefExpr::VK_None);
3640 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3642 /// ::= '(', register, ')'
3643 /// handle it before we iterate so we don't get tripped up by the lack of
3645 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3646 MCAsmParser &Parser = getParser();
3647 if (getLexer().is(AsmToken::LParen)) {
3649 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3651 if (parseOperand(Operands, Name)) {
3652 SMLoc Loc = getLexer().getLoc();
3653 Parser.eatToEndOfStatement();
3654 return Error(Loc, "unexpected token in argument list");
3656 if (Parser.getTok().isNot(AsmToken::RParen)) {
3657 SMLoc Loc = getLexer().getLoc();
3658 Parser.eatToEndOfStatement();
3659 return Error(Loc, "unexpected token, expected ')'");
3662 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3668 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3669 /// either one of these.
3670 /// ::= '[', register, ']'
3671 /// ::= '[', integer, ']'
3672 /// handle it before we iterate so we don't get tripped up by the lack of
3674 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3675 OperandVector &Operands) {
3676 MCAsmParser &Parser = getParser();
3677 if (getLexer().is(AsmToken::LBrac)) {
3679 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3681 if (parseOperand(Operands, Name)) {
3682 SMLoc Loc = getLexer().getLoc();
3683 Parser.eatToEndOfStatement();
3684 return Error(Loc, "unexpected token in argument list");
3686 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3687 SMLoc Loc = getLexer().getLoc();
3688 Parser.eatToEndOfStatement();
3689 return Error(Loc, "unexpected token, expected ']'");
3692 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3698 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3699 SMLoc NameLoc, OperandVector &Operands) {
3700 MCAsmParser &Parser = getParser();
3701 DEBUG(dbgs() << "ParseInstruction\n");
3703 // We have reached first instruction, module directive are now forbidden.
3704 getTargetStreamer().forbidModuleDirective();
3706 // Check if we have valid mnemonic
3707 if (!mnemonicIsValid(Name, 0)) {
3708 Parser.eatToEndOfStatement();
3709 return Error(NameLoc, "unknown instruction");
3711 // First operand in MCInst is instruction mnemonic.
3712 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3714 // Read the remaining operands.
3715 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3716 // Read the first operand.
3717 if (parseOperand(Operands, Name)) {
3718 SMLoc Loc = getLexer().getLoc();
3719 Parser.eatToEndOfStatement();
3720 return Error(Loc, "unexpected token in argument list");
3722 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3724 // AFAIK, parenthesis suffixes are never on the first operand
3726 while (getLexer().is(AsmToken::Comma)) {
3727 Parser.Lex(); // Eat the comma.
3728 // Parse and remember the operand.
3729 if (parseOperand(Operands, Name)) {
3730 SMLoc Loc = getLexer().getLoc();
3731 Parser.eatToEndOfStatement();
3732 return Error(Loc, "unexpected token in argument list");
3734 // Parse bracket and parenthesis suffixes before we iterate
3735 if (getLexer().is(AsmToken::LBrac)) {
3736 if (parseBracketSuffix(Name, Operands))
3738 } else if (getLexer().is(AsmToken::LParen) &&
3739 parseParenSuffix(Name, Operands))
3743 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3744 SMLoc Loc = getLexer().getLoc();
3745 Parser.eatToEndOfStatement();
3746 return Error(Loc, "unexpected token in argument list");
3748 Parser.Lex(); // Consume the EndOfStatement.
3752 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3753 MCAsmParser &Parser = getParser();
3754 SMLoc Loc = getLexer().getLoc();
3755 Parser.eatToEndOfStatement();
3756 return Error(Loc, ErrorMsg);
3759 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3760 return Error(Loc, ErrorMsg);
3763 bool MipsAsmParser::parseSetNoAtDirective() {
3764 MCAsmParser &Parser = getParser();
3765 // Line should look like: ".set noat".
3767 // Set the $at register to $0.
3768 AssemblerOptions.back()->setATRegIndex(0);
3770 Parser.Lex(); // Eat "noat".
3772 // If this is not the end of the statement, report an error.
3773 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3774 reportParseError("unexpected token, expected end of statement");
3778 getTargetStreamer().emitDirectiveSetNoAt();
3779 Parser.Lex(); // Consume the EndOfStatement.
3783 bool MipsAsmParser::parseSetAtDirective() {
3784 // Line can be: ".set at", which sets $at to $1
3785 // or ".set at=$reg", which sets $at to $reg.
3786 MCAsmParser &Parser = getParser();
3787 Parser.Lex(); // Eat "at".
3789 if (getLexer().is(AsmToken::EndOfStatement)) {
3790 // No register was specified, so we set $at to $1.
3791 AssemblerOptions.back()->setATRegIndex(1);
3793 getTargetStreamer().emitDirectiveSetAt();
3794 Parser.Lex(); // Consume the EndOfStatement.
3798 if (getLexer().isNot(AsmToken::Equal)) {
3799 reportParseError("unexpected token, expected equals sign");
3802 Parser.Lex(); // Eat "=".
3804 if (getLexer().isNot(AsmToken::Dollar)) {
3805 if (getLexer().is(AsmToken::EndOfStatement)) {
3806 reportParseError("no register specified");
3809 reportParseError("unexpected token, expected dollar sign '$'");
3813 Parser.Lex(); // Eat "$".
3815 // Find out what "reg" is.
3817 const AsmToken &Reg = Parser.getTok();
3818 if (Reg.is(AsmToken::Identifier)) {
3819 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3820 } else if (Reg.is(AsmToken::Integer)) {
3821 AtRegNo = Reg.getIntVal();
3823 reportParseError("unexpected token, expected identifier or integer");
3827 // Check if $reg is a valid register. If it is, set $at to $reg.
3828 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3829 reportParseError("invalid register");
3832 Parser.Lex(); // Eat "reg".
3834 // If this is not the end of the statement, report an error.
3835 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3836 reportParseError("unexpected token, expected end of statement");
3840 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3842 Parser.Lex(); // Consume the EndOfStatement.
3846 bool MipsAsmParser::parseSetReorderDirective() {
3847 MCAsmParser &Parser = getParser();
3849 // If this is not the end of the statement, report an error.
3850 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3851 reportParseError("unexpected token, expected end of statement");
3854 AssemblerOptions.back()->setReorder();
3855 getTargetStreamer().emitDirectiveSetReorder();
3856 Parser.Lex(); // Consume the EndOfStatement.
3860 bool MipsAsmParser::parseSetNoReorderDirective() {
3861 MCAsmParser &Parser = getParser();
3863 // If this is not the end of the statement, report an error.
3864 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3865 reportParseError("unexpected token, expected end of statement");
3868 AssemblerOptions.back()->setNoReorder();
3869 getTargetStreamer().emitDirectiveSetNoReorder();
3870 Parser.Lex(); // Consume the EndOfStatement.
3874 bool MipsAsmParser::parseSetMacroDirective() {
3875 MCAsmParser &Parser = getParser();
3877 // If this is not the end of the statement, report an error.
3878 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3879 reportParseError("unexpected token, expected end of statement");
3882 AssemblerOptions.back()->setMacro();
3883 getTargetStreamer().emitDirectiveSetMacro();
3884 Parser.Lex(); // Consume the EndOfStatement.
3888 bool MipsAsmParser::parseSetNoMacroDirective() {
3889 MCAsmParser &Parser = getParser();
3891 // If this is not the end of the statement, report an error.
3892 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3893 reportParseError("unexpected token, expected end of statement");
3896 if (AssemblerOptions.back()->isReorder()) {
3897 reportParseError("`noreorder' must be set before `nomacro'");
3900 AssemblerOptions.back()->setNoMacro();
3901 getTargetStreamer().emitDirectiveSetNoMacro();
3902 Parser.Lex(); // Consume the EndOfStatement.
3906 bool MipsAsmParser::parseSetMsaDirective() {
3907 MCAsmParser &Parser = getParser();
3910 // If this is not the end of the statement, report an error.
3911 if (getLexer().isNot(AsmToken::EndOfStatement))
3912 return reportParseError("unexpected token, expected end of statement");
3914 setFeatureBits(Mips::FeatureMSA, "msa");
3915 getTargetStreamer().emitDirectiveSetMsa();
3919 bool MipsAsmParser::parseSetNoMsaDirective() {
3920 MCAsmParser &Parser = getParser();
3923 // If this is not the end of the statement, report an error.
3924 if (getLexer().isNot(AsmToken::EndOfStatement))
3925 return reportParseError("unexpected token, expected end of statement");
3927 clearFeatureBits(Mips::FeatureMSA, "msa");
3928 getTargetStreamer().emitDirectiveSetNoMsa();
3932 bool MipsAsmParser::parseSetNoDspDirective() {
3933 MCAsmParser &Parser = getParser();
3934 Parser.Lex(); // Eat "nodsp".
3936 // If this is not the end of the statement, report an error.
3937 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3938 reportParseError("unexpected token, expected end of statement");
3942 clearFeatureBits(Mips::FeatureDSP, "dsp");
3943 getTargetStreamer().emitDirectiveSetNoDsp();
3947 bool MipsAsmParser::parseSetMips16Directive() {
3948 MCAsmParser &Parser = getParser();
3949 Parser.Lex(); // Eat "mips16".
3951 // If this is not the end of the statement, report an error.
3952 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3953 reportParseError("unexpected token, expected end of statement");
3957 setFeatureBits(Mips::FeatureMips16, "mips16");
3958 getTargetStreamer().emitDirectiveSetMips16();
3959 Parser.Lex(); // Consume the EndOfStatement.
3963 bool MipsAsmParser::parseSetNoMips16Directive() {
3964 MCAsmParser &Parser = getParser();
3965 Parser.Lex(); // Eat "nomips16".
3967 // If this is not the end of the statement, report an error.
3968 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3969 reportParseError("unexpected token, expected end of statement");
3973 clearFeatureBits(Mips::FeatureMips16, "mips16");
3974 getTargetStreamer().emitDirectiveSetNoMips16();
3975 Parser.Lex(); // Consume the EndOfStatement.
3979 bool MipsAsmParser::parseSetFpDirective() {
3980 MCAsmParser &Parser = getParser();
3981 MipsABIFlagsSection::FpABIKind FpAbiVal;
3982 // Line can be: .set fp=32
3985 Parser.Lex(); // Eat fp token
3986 AsmToken Tok = Parser.getTok();
3987 if (Tok.isNot(AsmToken::Equal)) {
3988 reportParseError("unexpected token, expected equals sign '='");
3991 Parser.Lex(); // Eat '=' token.
3992 Tok = Parser.getTok();
3994 if (!parseFpABIValue(FpAbiVal, ".set"))
3997 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3998 reportParseError("unexpected token, expected end of statement");
4001 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4002 Parser.Lex(); // Consume the EndOfStatement.
4006 bool MipsAsmParser::parseSetPopDirective() {
4007 MCAsmParser &Parser = getParser();
4008 SMLoc Loc = getLexer().getLoc();
4011 if (getLexer().isNot(AsmToken::EndOfStatement))
4012 return reportParseError("unexpected token, expected end of statement");
4014 // Always keep an element on the options "stack" to prevent the user
4015 // from changing the initial options. This is how we remember them.
4016 if (AssemblerOptions.size() == 2)
4017 return reportParseError(Loc, ".set pop with no .set push");
4019 AssemblerOptions.pop_back();
4020 setAvailableFeatures(
4021 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4022 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4024 getTargetStreamer().emitDirectiveSetPop();
4028 bool MipsAsmParser::parseSetPushDirective() {
4029 MCAsmParser &Parser = getParser();
4031 if (getLexer().isNot(AsmToken::EndOfStatement))
4032 return reportParseError("unexpected token, expected end of statement");
4034 // Create a copy of the current assembler options environment and push it.
4035 AssemblerOptions.push_back(
4036 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4038 getTargetStreamer().emitDirectiveSetPush();
4042 bool MipsAsmParser::parseSetSoftFloatDirective() {
4043 MCAsmParser &Parser = getParser();
4045 if (getLexer().isNot(AsmToken::EndOfStatement))
4046 return reportParseError("unexpected token, expected end of statement");
4048 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4049 getTargetStreamer().emitDirectiveSetSoftFloat();
4053 bool MipsAsmParser::parseSetHardFloatDirective() {
4054 MCAsmParser &Parser = getParser();
4056 if (getLexer().isNot(AsmToken::EndOfStatement))
4057 return reportParseError("unexpected token, expected end of statement");
4059 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4060 getTargetStreamer().emitDirectiveSetHardFloat();
4064 bool MipsAsmParser::parseSetAssignment() {
4066 const MCExpr *Value;
4067 MCAsmParser &Parser = getParser();
4069 if (Parser.parseIdentifier(Name))
4070 reportParseError("expected identifier after .set");
4072 if (getLexer().isNot(AsmToken::Comma))
4073 return reportParseError("unexpected token, expected comma");
4076 if (Parser.parseExpression(Value))
4077 return reportParseError("expected valid expression after comma");
4079 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4080 Sym->setVariableValue(Value);
4085 bool MipsAsmParser::parseSetMips0Directive() {
4086 MCAsmParser &Parser = getParser();
4088 if (getLexer().isNot(AsmToken::EndOfStatement))
4089 return reportParseError("unexpected token, expected end of statement");
4091 // Reset assembler options to their initial values.
4092 setAvailableFeatures(
4093 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4094 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4095 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4097 getTargetStreamer().emitDirectiveSetMips0();
4101 bool MipsAsmParser::parseSetArchDirective() {
4102 MCAsmParser &Parser = getParser();
4104 if (getLexer().isNot(AsmToken::Equal))
4105 return reportParseError("unexpected token, expected equals sign");
4109 if (Parser.parseIdentifier(Arch))
4110 return reportParseError("expected arch identifier");
4112 StringRef ArchFeatureName =
4113 StringSwitch<StringRef>(Arch)
4114 .Case("mips1", "mips1")
4115 .Case("mips2", "mips2")
4116 .Case("mips3", "mips3")
4117 .Case("mips4", "mips4")
4118 .Case("mips5", "mips5")
4119 .Case("mips32", "mips32")
4120 .Case("mips32r2", "mips32r2")
4121 .Case("mips32r3", "mips32r3")
4122 .Case("mips32r5", "mips32r5")
4123 .Case("mips32r6", "mips32r6")
4124 .Case("mips64", "mips64")
4125 .Case("mips64r2", "mips64r2")
4126 .Case("mips64r3", "mips64r3")
4127 .Case("mips64r5", "mips64r5")
4128 .Case("mips64r6", "mips64r6")
4129 .Case("cnmips", "cnmips")
4130 .Case("r4000", "mips3") // This is an implementation of Mips3.
4133 if (ArchFeatureName.empty())
4134 return reportParseError("unsupported architecture");
4136 selectArch(ArchFeatureName);
4137 getTargetStreamer().emitDirectiveSetArch(Arch);
4141 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4142 MCAsmParser &Parser = getParser();
4144 if (getLexer().isNot(AsmToken::EndOfStatement))
4145 return reportParseError("unexpected token, expected end of statement");
4149 llvm_unreachable("Unimplemented feature");
4150 case Mips::FeatureDSP:
4151 setFeatureBits(Mips::FeatureDSP, "dsp");
4152 getTargetStreamer().emitDirectiveSetDsp();
4154 case Mips::FeatureMicroMips:
4155 getTargetStreamer().emitDirectiveSetMicroMips();
4157 case Mips::FeatureMips1:
4158 selectArch("mips1");
4159 getTargetStreamer().emitDirectiveSetMips1();
4161 case Mips::FeatureMips2:
4162 selectArch("mips2");
4163 getTargetStreamer().emitDirectiveSetMips2();
4165 case Mips::FeatureMips3:
4166 selectArch("mips3");
4167 getTargetStreamer().emitDirectiveSetMips3();
4169 case Mips::FeatureMips4:
4170 selectArch("mips4");
4171 getTargetStreamer().emitDirectiveSetMips4();
4173 case Mips::FeatureMips5:
4174 selectArch("mips5");
4175 getTargetStreamer().emitDirectiveSetMips5();
4177 case Mips::FeatureMips32:
4178 selectArch("mips32");
4179 getTargetStreamer().emitDirectiveSetMips32();
4181 case Mips::FeatureMips32r2:
4182 selectArch("mips32r2");
4183 getTargetStreamer().emitDirectiveSetMips32R2();
4185 case Mips::FeatureMips32r3:
4186 selectArch("mips32r3");
4187 getTargetStreamer().emitDirectiveSetMips32R3();
4189 case Mips::FeatureMips32r5:
4190 selectArch("mips32r5");
4191 getTargetStreamer().emitDirectiveSetMips32R5();
4193 case Mips::FeatureMips32r6:
4194 selectArch("mips32r6");
4195 getTargetStreamer().emitDirectiveSetMips32R6();
4197 case Mips::FeatureMips64:
4198 selectArch("mips64");
4199 getTargetStreamer().emitDirectiveSetMips64();
4201 case Mips::FeatureMips64r2:
4202 selectArch("mips64r2");
4203 getTargetStreamer().emitDirectiveSetMips64R2();
4205 case Mips::FeatureMips64r3:
4206 selectArch("mips64r3");
4207 getTargetStreamer().emitDirectiveSetMips64R3();
4209 case Mips::FeatureMips64r5:
4210 selectArch("mips64r5");
4211 getTargetStreamer().emitDirectiveSetMips64R5();
4213 case Mips::FeatureMips64r6:
4214 selectArch("mips64r6");
4215 getTargetStreamer().emitDirectiveSetMips64R6();
4221 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4222 MCAsmParser &Parser = getParser();
4223 if (getLexer().isNot(AsmToken::Comma)) {
4224 SMLoc Loc = getLexer().getLoc();
4225 Parser.eatToEndOfStatement();
4226 return Error(Loc, ErrorStr);
4229 Parser.Lex(); // Eat the comma.
4233 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4234 if (AssemblerOptions.back()->isReorder())
4235 Warning(Loc, ".cpload should be inside a noreorder section");
4237 if (inMips16Mode()) {
4238 reportParseError(".cpload is not supported in Mips16 mode");
4242 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4243 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4244 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4245 reportParseError("expected register containing function address");
4249 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4250 if (!RegOpnd.isGPRAsmReg()) {
4251 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4255 // If this is not the end of the statement, report an error.
4256 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4257 reportParseError("unexpected token, expected end of statement");
4261 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4265 bool MipsAsmParser::parseDirectiveCPSetup() {
4266 MCAsmParser &Parser = getParser();
4269 bool SaveIsReg = true;
4271 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4272 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4273 if (ResTy == MatchOperand_NoMatch) {
4274 reportParseError("expected register containing function address");
4275 Parser.eatToEndOfStatement();
4279 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4280 if (!FuncRegOpnd.isGPRAsmReg()) {
4281 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4282 Parser.eatToEndOfStatement();
4286 FuncReg = FuncRegOpnd.getGPR32Reg();
4289 if (!eatComma("unexpected token, expected comma"))
4292 ResTy = parseAnyRegister(TmpReg);
4293 if (ResTy == MatchOperand_NoMatch) {
4294 const AsmToken &Tok = Parser.getTok();
4295 if (Tok.is(AsmToken::Integer)) {
4296 Save = Tok.getIntVal();
4300 reportParseError("expected save register or stack offset");
4301 Parser.eatToEndOfStatement();
4305 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4306 if (!SaveOpnd.isGPRAsmReg()) {
4307 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4308 Parser.eatToEndOfStatement();
4311 Save = SaveOpnd.getGPR32Reg();
4314 if (!eatComma("unexpected token, expected comma"))
4318 if (Parser.parseExpression(Expr)) {
4319 reportParseError("expected expression");
4323 if (Expr->getKind() != MCExpr::SymbolRef) {
4324 reportParseError("expected symbol");
4327 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4329 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4334 bool MipsAsmParser::parseDirectiveNaN() {
4335 MCAsmParser &Parser = getParser();
4336 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4337 const AsmToken &Tok = Parser.getTok();
4339 if (Tok.getString() == "2008") {
4341 getTargetStreamer().emitDirectiveNaN2008();
4343 } else if (Tok.getString() == "legacy") {
4345 getTargetStreamer().emitDirectiveNaNLegacy();
4349 // If we don't recognize the option passed to the .nan
4350 // directive (e.g. no option or unknown option), emit an error.
4351 reportParseError("invalid option in .nan directive");
4355 bool MipsAsmParser::parseDirectiveSet() {
4356 MCAsmParser &Parser = getParser();
4357 // Get the next token.
4358 const AsmToken &Tok = Parser.getTok();
4360 if (Tok.getString() == "noat") {
4361 return parseSetNoAtDirective();
4362 } else if (Tok.getString() == "at") {
4363 return parseSetAtDirective();
4364 } else if (Tok.getString() == "arch") {
4365 return parseSetArchDirective();
4366 } else if (Tok.getString() == "fp") {
4367 return parseSetFpDirective();
4368 } else if (Tok.getString() == "pop") {
4369 return parseSetPopDirective();
4370 } else if (Tok.getString() == "push") {
4371 return parseSetPushDirective();
4372 } else if (Tok.getString() == "reorder") {
4373 return parseSetReorderDirective();
4374 } else if (Tok.getString() == "noreorder") {
4375 return parseSetNoReorderDirective();
4376 } else if (Tok.getString() == "macro") {
4377 return parseSetMacroDirective();
4378 } else if (Tok.getString() == "nomacro") {
4379 return parseSetNoMacroDirective();
4380 } else if (Tok.getString() == "mips16") {
4381 return parseSetMips16Directive();
4382 } else if (Tok.getString() == "nomips16") {
4383 return parseSetNoMips16Directive();
4384 } else if (Tok.getString() == "nomicromips") {
4385 getTargetStreamer().emitDirectiveSetNoMicroMips();
4386 Parser.eatToEndOfStatement();
4388 } else if (Tok.getString() == "micromips") {
4389 return parseSetFeature(Mips::FeatureMicroMips);
4390 } else if (Tok.getString() == "mips0") {
4391 return parseSetMips0Directive();
4392 } else if (Tok.getString() == "mips1") {
4393 return parseSetFeature(Mips::FeatureMips1);
4394 } else if (Tok.getString() == "mips2") {
4395 return parseSetFeature(Mips::FeatureMips2);
4396 } else if (Tok.getString() == "mips3") {
4397 return parseSetFeature(Mips::FeatureMips3);
4398 } else if (Tok.getString() == "mips4") {
4399 return parseSetFeature(Mips::FeatureMips4);
4400 } else if (Tok.getString() == "mips5") {
4401 return parseSetFeature(Mips::FeatureMips5);
4402 } else if (Tok.getString() == "mips32") {
4403 return parseSetFeature(Mips::FeatureMips32);
4404 } else if (Tok.getString() == "mips32r2") {
4405 return parseSetFeature(Mips::FeatureMips32r2);
4406 } else if (Tok.getString() == "mips32r3") {
4407 return parseSetFeature(Mips::FeatureMips32r3);
4408 } else if (Tok.getString() == "mips32r5") {
4409 return parseSetFeature(Mips::FeatureMips32r5);
4410 } else if (Tok.getString() == "mips32r6") {
4411 return parseSetFeature(Mips::FeatureMips32r6);
4412 } else if (Tok.getString() == "mips64") {
4413 return parseSetFeature(Mips::FeatureMips64);
4414 } else if (Tok.getString() == "mips64r2") {
4415 return parseSetFeature(Mips::FeatureMips64r2);
4416 } else if (Tok.getString() == "mips64r3") {
4417 return parseSetFeature(Mips::FeatureMips64r3);
4418 } else if (Tok.getString() == "mips64r5") {
4419 return parseSetFeature(Mips::FeatureMips64r5);
4420 } else if (Tok.getString() == "mips64r6") {
4421 return parseSetFeature(Mips::FeatureMips64r6);
4422 } else if (Tok.getString() == "dsp") {
4423 return parseSetFeature(Mips::FeatureDSP);
4424 } else if (Tok.getString() == "nodsp") {
4425 return parseSetNoDspDirective();
4426 } else if (Tok.getString() == "msa") {
4427 return parseSetMsaDirective();
4428 } else if (Tok.getString() == "nomsa") {
4429 return parseSetNoMsaDirective();
4430 } else if (Tok.getString() == "softfloat") {
4431 return parseSetSoftFloatDirective();
4432 } else if (Tok.getString() == "hardfloat") {
4433 return parseSetHardFloatDirective();
4435 // It is just an identifier, look for an assignment.
4436 parseSetAssignment();
4443 /// parseDataDirective
4444 /// ::= .word [ expression (, expression)* ]
4445 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4446 MCAsmParser &Parser = getParser();
4447 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4449 const MCExpr *Value;
4450 if (getParser().parseExpression(Value))
4453 getParser().getStreamer().EmitValue(Value, Size);
4455 if (getLexer().is(AsmToken::EndOfStatement))
4458 if (getLexer().isNot(AsmToken::Comma))
4459 return Error(L, "unexpected token, expected comma");
4468 /// parseDirectiveGpWord
4469 /// ::= .gpword local_sym
4470 bool MipsAsmParser::parseDirectiveGpWord() {
4471 MCAsmParser &Parser = getParser();
4472 const MCExpr *Value;
4473 // EmitGPRel32Value requires an expression, so we are using base class
4474 // method to evaluate the expression.
4475 if (getParser().parseExpression(Value))
4477 getParser().getStreamer().EmitGPRel32Value(Value);
4479 if (getLexer().isNot(AsmToken::EndOfStatement))
4480 return Error(getLexer().getLoc(),
4481 "unexpected token, expected end of statement");
4482 Parser.Lex(); // Eat EndOfStatement token.
4486 /// parseDirectiveGpDWord
4487 /// ::= .gpdword local_sym
4488 bool MipsAsmParser::parseDirectiveGpDWord() {
4489 MCAsmParser &Parser = getParser();
4490 const MCExpr *Value;
4491 // EmitGPRel64Value requires an expression, so we are using base class
4492 // method to evaluate the expression.
4493 if (getParser().parseExpression(Value))
4495 getParser().getStreamer().EmitGPRel64Value(Value);
4497 if (getLexer().isNot(AsmToken::EndOfStatement))
4498 return Error(getLexer().getLoc(),
4499 "unexpected token, expected end of statement");
4500 Parser.Lex(); // Eat EndOfStatement token.
4504 bool MipsAsmParser::parseDirectiveOption() {
4505 MCAsmParser &Parser = getParser();
4506 // Get the option token.
4507 AsmToken Tok = Parser.getTok();
4508 // At the moment only identifiers are supported.
4509 if (Tok.isNot(AsmToken::Identifier)) {
4510 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4511 Parser.eatToEndOfStatement();
4515 StringRef Option = Tok.getIdentifier();
4517 if (Option == "pic0") {
4518 getTargetStreamer().emitDirectiveOptionPic0();
4520 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4521 Error(Parser.getTok().getLoc(),
4522 "unexpected token, expected end of statement");
4523 Parser.eatToEndOfStatement();
4528 if (Option == "pic2") {
4529 getTargetStreamer().emitDirectiveOptionPic2();
4531 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4532 Error(Parser.getTok().getLoc(),
4533 "unexpected token, expected end of statement");
4534 Parser.eatToEndOfStatement();
4540 Warning(Parser.getTok().getLoc(),
4541 "unknown option, expected 'pic0' or 'pic2'");
4542 Parser.eatToEndOfStatement();
4546 /// parseInsnDirective
4548 bool MipsAsmParser::parseInsnDirective() {
4549 // If this is not the end of the statement, report an error.
4550 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4551 reportParseError("unexpected token, expected end of statement");
4555 // The actual label marking happens in
4556 // MipsELFStreamer::createPendingLabelRelocs().
4557 getTargetStreamer().emitDirectiveInsn();
4559 getParser().Lex(); // Eat EndOfStatement token.
4563 /// parseDirectiveModule
4564 /// ::= .module oddspreg
4565 /// ::= .module nooddspreg
4566 /// ::= .module fp=value
4567 bool MipsAsmParser::parseDirectiveModule() {
4568 MCAsmParser &Parser = getParser();
4569 MCAsmLexer &Lexer = getLexer();
4570 SMLoc L = Lexer.getLoc();
4572 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4573 // TODO : get a better message.
4574 reportParseError(".module directive must appear before any code");
4579 if (Parser.parseIdentifier(Option)) {
4580 reportParseError("expected .module option identifier");
4584 if (Option == "oddspreg") {
4585 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4587 // Synchronize the abiflags information with the FeatureBits information we
4589 getTargetStreamer().updateABIInfo(*this);
4591 // If printing assembly, use the recently updated abiflags information.
4592 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4593 // emitted at the end).
4594 getTargetStreamer().emitDirectiveModuleOddSPReg();
4596 // If this is not the end of the statement, report an error.
4597 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4598 reportParseError("unexpected token, expected end of statement");
4602 return false; // parseDirectiveModule has finished successfully.
4603 } else if (Option == "nooddspreg") {
4605 Error(L, "'.module nooddspreg' requires the O32 ABI");
4609 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4611 // Synchronize the abiflags information with the FeatureBits information we
4613 getTargetStreamer().updateABIInfo(*this);
4615 // If printing assembly, use the recently updated abiflags information.
4616 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4617 // emitted at the end).
4618 getTargetStreamer().emitDirectiveModuleOddSPReg();
4620 // If this is not the end of the statement, report an error.
4621 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4622 reportParseError("unexpected token, expected end of statement");
4626 return false; // parseDirectiveModule has finished successfully.
4627 } else if (Option == "fp") {
4628 return parseDirectiveModuleFP();
4630 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4634 /// parseDirectiveModuleFP
4638 bool MipsAsmParser::parseDirectiveModuleFP() {
4639 MCAsmParser &Parser = getParser();
4640 MCAsmLexer &Lexer = getLexer();
4642 if (Lexer.isNot(AsmToken::Equal)) {
4643 reportParseError("unexpected token, expected equals sign '='");
4646 Parser.Lex(); // Eat '=' token.
4648 MipsABIFlagsSection::FpABIKind FpABI;
4649 if (!parseFpABIValue(FpABI, ".module"))
4652 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4653 reportParseError("unexpected token, expected end of statement");
4657 // Synchronize the abiflags information with the FeatureBits information we
4659 getTargetStreamer().updateABIInfo(*this);
4661 // If printing assembly, use the recently updated abiflags information.
4662 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
4663 // emitted at the end).
4664 getTargetStreamer().emitDirectiveModuleFP();
4666 Parser.Lex(); // Consume the EndOfStatement.
4670 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4671 StringRef Directive) {
4672 MCAsmParser &Parser = getParser();
4673 MCAsmLexer &Lexer = getLexer();
4675 if (Lexer.is(AsmToken::Identifier)) {
4676 StringRef Value = Parser.getTok().getString();
4679 if (Value != "xx") {
4680 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4685 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4689 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4690 setFeatureBits(Mips::FeatureFPXX, "fpxx");
4691 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4695 if (Lexer.is(AsmToken::Integer)) {
4696 unsigned Value = Parser.getTok().getIntVal();
4699 if (Value != 32 && Value != 64) {
4700 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4706 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4710 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4711 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4712 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
4714 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4715 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
4716 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
4725 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4726 MCAsmParser &Parser = getParser();
4727 StringRef IDVal = DirectiveID.getString();
4729 if (IDVal == ".cpload")
4730 return parseDirectiveCpLoad(DirectiveID.getLoc());
4731 if (IDVal == ".dword") {
4732 parseDataDirective(8, DirectiveID.getLoc());
4735 if (IDVal == ".ent") {
4736 StringRef SymbolName;
4738 if (Parser.parseIdentifier(SymbolName)) {
4739 reportParseError("expected identifier after .ent");
4743 // There's an undocumented extension that allows an integer to
4744 // follow the name of the procedure which AFAICS is ignored by GAS.
4745 // Example: .ent foo,2
4746 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4747 if (getLexer().isNot(AsmToken::Comma)) {
4748 // Even though we accept this undocumented extension for compatibility
4749 // reasons, the additional integer argument does not actually change
4750 // the behaviour of the '.ent' directive, so we would like to discourage
4751 // its use. We do this by not referring to the extended version in
4752 // error messages which are not directly related to its use.
4753 reportParseError("unexpected token, expected end of statement");
4756 Parser.Lex(); // Eat the comma.
4757 const MCExpr *DummyNumber;
4758 int64_t DummyNumberVal;
4759 // If the user was explicitly trying to use the extended version,
4760 // we still give helpful extension-related error messages.
4761 if (Parser.parseExpression(DummyNumber)) {
4762 reportParseError("expected number after comma");
4765 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4766 reportParseError("expected an absolute expression after comma");
4771 // If this is not the end of the statement, report an error.
4772 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4773 reportParseError("unexpected token, expected end of statement");
4777 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4779 getTargetStreamer().emitDirectiveEnt(*Sym);
4784 if (IDVal == ".end") {
4785 StringRef SymbolName;
4787 if (Parser.parseIdentifier(SymbolName)) {
4788 reportParseError("expected identifier after .end");
4792 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4793 reportParseError("unexpected token, expected end of statement");
4797 if (CurrentFn == nullptr) {
4798 reportParseError(".end used without .ent");
4802 if ((SymbolName != CurrentFn->getName())) {
4803 reportParseError(".end symbol does not match .ent symbol");
4807 getTargetStreamer().emitDirectiveEnd(SymbolName);
4808 CurrentFn = nullptr;
4812 if (IDVal == ".frame") {
4813 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4814 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4815 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4816 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4817 reportParseError("expected stack register");
4821 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4822 if (!StackRegOpnd.isGPRAsmReg()) {
4823 reportParseError(StackRegOpnd.getStartLoc(),
4824 "expected general purpose register");
4827 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4829 if (Parser.getTok().is(AsmToken::Comma))
4832 reportParseError("unexpected token, expected comma");
4836 // Parse the frame size.
4837 const MCExpr *FrameSize;
4838 int64_t FrameSizeVal;
4840 if (Parser.parseExpression(FrameSize)) {
4841 reportParseError("expected frame size value");
4845 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4846 reportParseError("frame size not an absolute expression");
4850 if (Parser.getTok().is(AsmToken::Comma))
4853 reportParseError("unexpected token, expected comma");
4857 // Parse the return register.
4859 ResTy = parseAnyRegister(TmpReg);
4860 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4861 reportParseError("expected return register");
4865 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4866 if (!ReturnRegOpnd.isGPRAsmReg()) {
4867 reportParseError(ReturnRegOpnd.getStartLoc(),
4868 "expected general purpose register");
4872 // If this is not the end of the statement, report an error.
4873 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4874 reportParseError("unexpected token, expected end of statement");
4878 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4879 ReturnRegOpnd.getGPR32Reg());
4883 if (IDVal == ".set") {
4884 return parseDirectiveSet();
4887 if (IDVal == ".mask" || IDVal == ".fmask") {
4888 // .mask bitmask, frame_offset
4889 // bitmask: One bit for each register used.
4890 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4891 // first register is expected to be saved.
4893 // .mask 0x80000000, -4
4894 // .fmask 0x80000000, -4
4897 // Parse the bitmask
4898 const MCExpr *BitMask;
4901 if (Parser.parseExpression(BitMask)) {
4902 reportParseError("expected bitmask value");
4906 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4907 reportParseError("bitmask not an absolute expression");
4911 if (Parser.getTok().is(AsmToken::Comma))
4914 reportParseError("unexpected token, expected comma");
4918 // Parse the frame_offset
4919 const MCExpr *FrameOffset;
4920 int64_t FrameOffsetVal;
4922 if (Parser.parseExpression(FrameOffset)) {
4923 reportParseError("expected frame offset value");
4927 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4928 reportParseError("frame offset not an absolute expression");
4932 // If this is not the end of the statement, report an error.
4933 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4934 reportParseError("unexpected token, expected end of statement");
4938 if (IDVal == ".mask")
4939 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4941 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4945 if (IDVal == ".nan")
4946 return parseDirectiveNaN();
4948 if (IDVal == ".gpword") {
4949 parseDirectiveGpWord();
4953 if (IDVal == ".gpdword") {
4954 parseDirectiveGpDWord();
4958 if (IDVal == ".word") {
4959 parseDataDirective(4, DirectiveID.getLoc());
4963 if (IDVal == ".option")
4964 return parseDirectiveOption();
4966 if (IDVal == ".abicalls") {
4967 getTargetStreamer().emitDirectiveAbiCalls();
4968 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4969 Error(Parser.getTok().getLoc(),
4970 "unexpected token, expected end of statement");
4972 Parser.eatToEndOfStatement();
4977 if (IDVal == ".cpsetup")
4978 return parseDirectiveCPSetup();
4980 if (IDVal == ".module")
4981 return parseDirectiveModule();
4983 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4984 return parseInternalDirectiveReallowModule();
4986 if (IDVal == ".insn")
4987 return parseInsnDirective();
4992 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4993 // If this is not the end of the statement, report an error.
4994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4995 reportParseError("unexpected token, expected end of statement");
4999 getTargetStreamer().reallowModuleDirective();
5001 getParser().Lex(); // Eat EndOfStatement token.
5005 extern "C" void LLVMInitializeMipsAsmParser() {
5006 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5007 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5008 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5009 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5012 #define GET_REGISTER_MATCHER
5013 #define GET_MATCHER_IMPLEMENTATION
5014 #include "MipsGenAsmMatcher.inc"