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();
3109 while (getLexer().getKind() == AsmToken::LParen)
3112 switch (getLexer().getKind()) {
3115 case AsmToken::Identifier:
3116 case AsmToken::LParen:
3117 case AsmToken::Integer:
3118 case AsmToken::Minus:
3119 case AsmToken::Plus:
3121 Result = getParser().parseParenExpression(Res, S);
3123 Result = (getParser().parseExpression(Res));
3124 while (getLexer().getKind() == AsmToken::RParen)
3127 case AsmToken::Percent:
3128 Result = parseRelocOperand(Res);
3133 MipsAsmParser::OperandMatchResultTy
3134 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3135 MCAsmParser &Parser = getParser();
3136 DEBUG(dbgs() << "parseMemOperand\n");
3137 const MCExpr *IdVal = nullptr;
3139 bool isParenExpr = false;
3140 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3141 // First operand is the offset.
3142 S = Parser.getTok().getLoc();
3144 if (getLexer().getKind() == AsmToken::LParen) {
3149 if (getLexer().getKind() != AsmToken::Dollar) {
3150 if (parseMemOffset(IdVal, isParenExpr))
3151 return MatchOperand_ParseFail;
3153 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3154 if (Tok.isNot(AsmToken::LParen)) {
3155 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3156 if (Mnemonic.getToken() == "la") {
3158 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3159 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3160 return MatchOperand_Success;
3162 if (Tok.is(AsmToken::EndOfStatement)) {
3164 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3166 // Zero register assumed, add a memory operand with ZERO as its base.
3167 // "Base" will be managed by k_Memory.
3168 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3171 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3172 return MatchOperand_Success;
3174 Error(Parser.getTok().getLoc(), "'(' expected");
3175 return MatchOperand_ParseFail;
3178 Parser.Lex(); // Eat the '(' token.
3181 Res = parseAnyRegister(Operands);
3182 if (Res != MatchOperand_Success)
3185 if (Parser.getTok().isNot(AsmToken::RParen)) {
3186 Error(Parser.getTok().getLoc(), "')' expected");
3187 return MatchOperand_ParseFail;
3190 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3192 Parser.Lex(); // Eat the ')' token.
3195 IdVal = MCConstantExpr::create(0, getContext());
3197 // Replace the register operand with the memory operand.
3198 std::unique_ptr<MipsOperand> op(
3199 static_cast<MipsOperand *>(Operands.back().release()));
3200 // Remove the register from the operands.
3201 // "op" will be managed by k_Memory.
3202 Operands.pop_back();
3203 // Add the memory operand.
3204 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3206 if (IdVal->evaluateAsAbsolute(Imm))
3207 IdVal = MCConstantExpr::create(Imm, getContext());
3208 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3209 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3213 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3214 return MatchOperand_Success;
3217 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3218 MCAsmParser &Parser = getParser();
3219 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3221 SMLoc S = Parser.getTok().getLoc();
3223 if (Sym->isVariable())
3224 Expr = Sym->getVariableValue();
3227 if (Expr->getKind() == MCExpr::SymbolRef) {
3228 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3229 StringRef DefSymbol = Ref->getSymbol().getName();
3230 if (DefSymbol.startswith("$")) {
3231 OperandMatchResultTy ResTy =
3232 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3233 if (ResTy == MatchOperand_Success) {
3236 } else if (ResTy == MatchOperand_ParseFail)
3237 llvm_unreachable("Should never ParseFail");
3240 } else if (Expr->getKind() == MCExpr::Constant) {
3242 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3244 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3251 MipsAsmParser::OperandMatchResultTy
3252 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3253 StringRef Identifier,
3255 int Index = matchCPURegisterName(Identifier);
3257 Operands.push_back(MipsOperand::createGPRReg(
3258 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3259 return MatchOperand_Success;
3262 Index = matchHWRegsRegisterName(Identifier);
3264 Operands.push_back(MipsOperand::createHWRegsReg(
3265 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3266 return MatchOperand_Success;
3269 Index = matchFPURegisterName(Identifier);
3271 Operands.push_back(MipsOperand::createFGRReg(
3272 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3273 return MatchOperand_Success;
3276 Index = matchFCCRegisterName(Identifier);
3278 Operands.push_back(MipsOperand::createFCCReg(
3279 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3280 return MatchOperand_Success;
3283 Index = matchACRegisterName(Identifier);
3285 Operands.push_back(MipsOperand::createACCReg(
3286 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3287 return MatchOperand_Success;
3290 Index = matchMSA128RegisterName(Identifier);
3292 Operands.push_back(MipsOperand::createMSA128Reg(
3293 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3294 return MatchOperand_Success;
3297 Index = matchMSA128CtrlRegisterName(Identifier);
3299 Operands.push_back(MipsOperand::createMSACtrlReg(
3300 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3301 return MatchOperand_Success;
3304 return MatchOperand_NoMatch;
3307 MipsAsmParser::OperandMatchResultTy
3308 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3309 MCAsmParser &Parser = getParser();
3310 auto Token = Parser.getLexer().peekTok(false);
3312 if (Token.is(AsmToken::Identifier)) {
3313 DEBUG(dbgs() << ".. identifier\n");
3314 StringRef Identifier = Token.getIdentifier();
3315 OperandMatchResultTy ResTy =
3316 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3318 } else if (Token.is(AsmToken::Integer)) {
3319 DEBUG(dbgs() << ".. integer\n");
3320 Operands.push_back(MipsOperand::createNumericReg(
3321 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3323 return MatchOperand_Success;
3326 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3328 return MatchOperand_NoMatch;
3331 MipsAsmParser::OperandMatchResultTy
3332 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3333 MCAsmParser &Parser = getParser();
3334 DEBUG(dbgs() << "parseAnyRegister\n");
3336 auto Token = Parser.getTok();
3338 SMLoc S = Token.getLoc();
3340 if (Token.isNot(AsmToken::Dollar)) {
3341 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3342 if (Token.is(AsmToken::Identifier)) {
3343 if (searchSymbolAlias(Operands))
3344 return MatchOperand_Success;
3346 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3347 return MatchOperand_NoMatch;
3349 DEBUG(dbgs() << ".. $\n");
3351 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3352 if (ResTy == MatchOperand_Success) {
3354 Parser.Lex(); // identifier
3359 MipsAsmParser::OperandMatchResultTy
3360 MipsAsmParser::parseImm(OperandVector &Operands) {
3361 MCAsmParser &Parser = getParser();
3362 switch (getLexer().getKind()) {
3364 return MatchOperand_NoMatch;
3365 case AsmToken::LParen:
3366 case AsmToken::Minus:
3367 case AsmToken::Plus:
3368 case AsmToken::Integer:
3369 case AsmToken::Tilde:
3370 case AsmToken::String:
3374 const MCExpr *IdVal;
3375 SMLoc S = Parser.getTok().getLoc();
3376 if (getParser().parseExpression(IdVal))
3377 return MatchOperand_ParseFail;
3379 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3380 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3381 return MatchOperand_Success;
3384 MipsAsmParser::OperandMatchResultTy
3385 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3386 MCAsmParser &Parser = getParser();
3387 DEBUG(dbgs() << "parseJumpTarget\n");
3389 SMLoc S = getLexer().getLoc();
3391 // Integers and expressions are acceptable
3392 OperandMatchResultTy ResTy = parseImm(Operands);
3393 if (ResTy != MatchOperand_NoMatch)
3396 // Registers are a valid target and have priority over symbols.
3397 ResTy = parseAnyRegister(Operands);
3398 if (ResTy != MatchOperand_NoMatch)
3401 const MCExpr *Expr = nullptr;
3402 if (Parser.parseExpression(Expr)) {
3403 // We have no way of knowing if a symbol was consumed so we must ParseFail
3404 return MatchOperand_ParseFail;
3407 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3408 return MatchOperand_Success;
3411 MipsAsmParser::OperandMatchResultTy
3412 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3413 MCAsmParser &Parser = getParser();
3414 const MCExpr *IdVal;
3415 // If the first token is '$' we may have register operand.
3416 if (Parser.getTok().is(AsmToken::Dollar))
3417 return MatchOperand_NoMatch;
3418 SMLoc S = Parser.getTok().getLoc();
3419 if (getParser().parseExpression(IdVal))
3420 return MatchOperand_ParseFail;
3421 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3422 assert(MCE && "Unexpected MCExpr type.");
3423 int64_t Val = MCE->getValue();
3424 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3425 Operands.push_back(MipsOperand::CreateImm(
3426 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3427 return MatchOperand_Success;
3430 MipsAsmParser::OperandMatchResultTy
3431 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3432 MCAsmParser &Parser = getParser();
3433 switch (getLexer().getKind()) {
3435 return MatchOperand_NoMatch;
3436 case AsmToken::LParen:
3437 case AsmToken::Plus:
3438 case AsmToken::Minus:
3439 case AsmToken::Integer:
3444 SMLoc S = Parser.getTok().getLoc();
3446 if (getParser().parseExpression(Expr))
3447 return MatchOperand_ParseFail;
3450 if (!Expr->evaluateAsAbsolute(Val)) {
3451 Error(S, "expected immediate value");
3452 return MatchOperand_ParseFail;
3455 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3456 // and because the CPU always adds one to the immediate field, the allowed
3457 // range becomes 1..4. We'll only check the range here and will deal
3458 // with the addition/subtraction when actually decoding/encoding
3460 if (Val < 1 || Val > 4) {
3461 Error(S, "immediate not in range (1..4)");
3462 return MatchOperand_ParseFail;
3466 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3467 return MatchOperand_Success;
3470 MipsAsmParser::OperandMatchResultTy
3471 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3472 MCAsmParser &Parser = getParser();
3473 SmallVector<unsigned, 10> Regs;
3475 unsigned PrevReg = Mips::NoRegister;
3476 bool RegRange = false;
3477 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3479 if (Parser.getTok().isNot(AsmToken::Dollar))
3480 return MatchOperand_ParseFail;
3482 SMLoc S = Parser.getTok().getLoc();
3483 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3484 SMLoc E = getLexer().getLoc();
3485 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3486 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3488 // Remove last register operand because registers from register range
3489 // should be inserted first.
3490 if (RegNo == Mips::RA) {
3491 Regs.push_back(RegNo);
3493 unsigned TmpReg = PrevReg + 1;
3494 while (TmpReg <= RegNo) {
3495 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3496 Error(E, "invalid register operand");
3497 return MatchOperand_ParseFail;
3501 Regs.push_back(TmpReg++);
3507 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3508 (RegNo != Mips::RA)) {
3509 Error(E, "$16 or $31 expected");
3510 return MatchOperand_ParseFail;
3511 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3512 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3513 Error(E, "invalid register operand");
3514 return MatchOperand_ParseFail;
3515 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3516 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3517 Error(E, "consecutive register numbers expected");
3518 return MatchOperand_ParseFail;
3521 Regs.push_back(RegNo);
3524 if (Parser.getTok().is(AsmToken::Minus))
3527 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3528 !Parser.getTok().isNot(AsmToken::Comma)) {
3529 Error(E, "',' or '-' expected");
3530 return MatchOperand_ParseFail;
3533 Lex(); // Consume comma or minus
3534 if (Parser.getTok().isNot(AsmToken::Dollar))
3540 SMLoc E = Parser.getTok().getLoc();
3541 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3542 parseMemOperand(Operands);
3543 return MatchOperand_Success;
3546 MipsAsmParser::OperandMatchResultTy
3547 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3548 MCAsmParser &Parser = getParser();
3550 SMLoc S = Parser.getTok().getLoc();
3551 if (parseAnyRegister(Operands) != MatchOperand_Success)
3552 return MatchOperand_ParseFail;
3554 SMLoc E = Parser.getTok().getLoc();
3555 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3556 unsigned Reg = Op.getGPR32Reg();
3557 Operands.pop_back();
3558 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3559 return MatchOperand_Success;
3562 MipsAsmParser::OperandMatchResultTy
3563 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3564 MCAsmParser &Parser = getParser();
3565 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3566 SmallVector<unsigned, 10> Regs;
3568 if (Parser.getTok().isNot(AsmToken::Dollar))
3569 return MatchOperand_ParseFail;
3571 SMLoc S = Parser.getTok().getLoc();
3573 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3574 return MatchOperand_ParseFail;
3576 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3577 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3578 Regs.push_back(RegNo);
3580 SMLoc E = Parser.getTok().getLoc();
3581 if (Parser.getTok().isNot(AsmToken::Comma)) {
3582 Error(E, "',' expected");
3583 return MatchOperand_ParseFail;
3589 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3590 return MatchOperand_ParseFail;
3592 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3593 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3594 Regs.push_back(RegNo);
3596 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3598 return MatchOperand_Success;
3601 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3603 MCSymbolRefExpr::VariantKind VK =
3604 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3605 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3606 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3607 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3608 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3609 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3610 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3611 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3612 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3613 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3614 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3615 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3616 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3617 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3618 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3619 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3620 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3621 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3622 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3623 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3624 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3625 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3626 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3627 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3628 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3629 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3630 .Default(MCSymbolRefExpr::VK_None);
3632 assert(VK != MCSymbolRefExpr::VK_None);
3637 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3639 /// ::= '(', register, ')'
3640 /// handle it before we iterate so we don't get tripped up by the lack of
3642 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3643 MCAsmParser &Parser = getParser();
3644 if (getLexer().is(AsmToken::LParen)) {
3646 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3648 if (parseOperand(Operands, Name)) {
3649 SMLoc Loc = getLexer().getLoc();
3650 Parser.eatToEndOfStatement();
3651 return Error(Loc, "unexpected token in argument list");
3653 if (Parser.getTok().isNot(AsmToken::RParen)) {
3654 SMLoc Loc = getLexer().getLoc();
3655 Parser.eatToEndOfStatement();
3656 return Error(Loc, "unexpected token, expected ')'");
3659 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3665 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3666 /// either one of these.
3667 /// ::= '[', register, ']'
3668 /// ::= '[', integer, ']'
3669 /// handle it before we iterate so we don't get tripped up by the lack of
3671 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3672 OperandVector &Operands) {
3673 MCAsmParser &Parser = getParser();
3674 if (getLexer().is(AsmToken::LBrac)) {
3676 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3678 if (parseOperand(Operands, Name)) {
3679 SMLoc Loc = getLexer().getLoc();
3680 Parser.eatToEndOfStatement();
3681 return Error(Loc, "unexpected token in argument list");
3683 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3684 SMLoc Loc = getLexer().getLoc();
3685 Parser.eatToEndOfStatement();
3686 return Error(Loc, "unexpected token, expected ']'");
3689 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3695 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3696 SMLoc NameLoc, OperandVector &Operands) {
3697 MCAsmParser &Parser = getParser();
3698 DEBUG(dbgs() << "ParseInstruction\n");
3700 // We have reached first instruction, module directive are now forbidden.
3701 getTargetStreamer().forbidModuleDirective();
3703 // Check if we have valid mnemonic
3704 if (!mnemonicIsValid(Name, 0)) {
3705 Parser.eatToEndOfStatement();
3706 return Error(NameLoc, "unknown instruction");
3708 // First operand in MCInst is instruction mnemonic.
3709 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3711 // Read the remaining operands.
3712 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3713 // Read the first operand.
3714 if (parseOperand(Operands, Name)) {
3715 SMLoc Loc = getLexer().getLoc();
3716 Parser.eatToEndOfStatement();
3717 return Error(Loc, "unexpected token in argument list");
3719 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3721 // AFAIK, parenthesis suffixes are never on the first operand
3723 while (getLexer().is(AsmToken::Comma)) {
3724 Parser.Lex(); // Eat the comma.
3725 // Parse and remember the operand.
3726 if (parseOperand(Operands, Name)) {
3727 SMLoc Loc = getLexer().getLoc();
3728 Parser.eatToEndOfStatement();
3729 return Error(Loc, "unexpected token in argument list");
3731 // Parse bracket and parenthesis suffixes before we iterate
3732 if (getLexer().is(AsmToken::LBrac)) {
3733 if (parseBracketSuffix(Name, Operands))
3735 } else if (getLexer().is(AsmToken::LParen) &&
3736 parseParenSuffix(Name, Operands))
3740 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3741 SMLoc Loc = getLexer().getLoc();
3742 Parser.eatToEndOfStatement();
3743 return Error(Loc, "unexpected token in argument list");
3745 Parser.Lex(); // Consume the EndOfStatement.
3749 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3750 MCAsmParser &Parser = getParser();
3751 SMLoc Loc = getLexer().getLoc();
3752 Parser.eatToEndOfStatement();
3753 return Error(Loc, ErrorMsg);
3756 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3757 return Error(Loc, ErrorMsg);
3760 bool MipsAsmParser::parseSetNoAtDirective() {
3761 MCAsmParser &Parser = getParser();
3762 // Line should look like: ".set noat".
3764 // Set the $at register to $0.
3765 AssemblerOptions.back()->setATRegIndex(0);
3767 Parser.Lex(); // Eat "noat".
3769 // If this is not the end of the statement, report an error.
3770 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3771 reportParseError("unexpected token, expected end of statement");
3775 getTargetStreamer().emitDirectiveSetNoAt();
3776 Parser.Lex(); // Consume the EndOfStatement.
3780 bool MipsAsmParser::parseSetAtDirective() {
3781 // Line can be: ".set at", which sets $at to $1
3782 // or ".set at=$reg", which sets $at to $reg.
3783 MCAsmParser &Parser = getParser();
3784 Parser.Lex(); // Eat "at".
3786 if (getLexer().is(AsmToken::EndOfStatement)) {
3787 // No register was specified, so we set $at to $1.
3788 AssemblerOptions.back()->setATRegIndex(1);
3790 getTargetStreamer().emitDirectiveSetAt();
3791 Parser.Lex(); // Consume the EndOfStatement.
3795 if (getLexer().isNot(AsmToken::Equal)) {
3796 reportParseError("unexpected token, expected equals sign");
3799 Parser.Lex(); // Eat "=".
3801 if (getLexer().isNot(AsmToken::Dollar)) {
3802 if (getLexer().is(AsmToken::EndOfStatement)) {
3803 reportParseError("no register specified");
3806 reportParseError("unexpected token, expected dollar sign '$'");
3810 Parser.Lex(); // Eat "$".
3812 // Find out what "reg" is.
3814 const AsmToken &Reg = Parser.getTok();
3815 if (Reg.is(AsmToken::Identifier)) {
3816 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3817 } else if (Reg.is(AsmToken::Integer)) {
3818 AtRegNo = Reg.getIntVal();
3820 reportParseError("unexpected token, expected identifier or integer");
3824 // Check if $reg is a valid register. If it is, set $at to $reg.
3825 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3826 reportParseError("invalid register");
3829 Parser.Lex(); // Eat "reg".
3831 // If this is not the end of the statement, report an error.
3832 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3833 reportParseError("unexpected token, expected end of statement");
3837 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3839 Parser.Lex(); // Consume the EndOfStatement.
3843 bool MipsAsmParser::parseSetReorderDirective() {
3844 MCAsmParser &Parser = getParser();
3846 // If this is not the end of the statement, report an error.
3847 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3848 reportParseError("unexpected token, expected end of statement");
3851 AssemblerOptions.back()->setReorder();
3852 getTargetStreamer().emitDirectiveSetReorder();
3853 Parser.Lex(); // Consume the EndOfStatement.
3857 bool MipsAsmParser::parseSetNoReorderDirective() {
3858 MCAsmParser &Parser = getParser();
3860 // If this is not the end of the statement, report an error.
3861 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3862 reportParseError("unexpected token, expected end of statement");
3865 AssemblerOptions.back()->setNoReorder();
3866 getTargetStreamer().emitDirectiveSetNoReorder();
3867 Parser.Lex(); // Consume the EndOfStatement.
3871 bool MipsAsmParser::parseSetMacroDirective() {
3872 MCAsmParser &Parser = getParser();
3874 // If this is not the end of the statement, report an error.
3875 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3876 reportParseError("unexpected token, expected end of statement");
3879 AssemblerOptions.back()->setMacro();
3880 getTargetStreamer().emitDirectiveSetMacro();
3881 Parser.Lex(); // Consume the EndOfStatement.
3885 bool MipsAsmParser::parseSetNoMacroDirective() {
3886 MCAsmParser &Parser = getParser();
3888 // If this is not the end of the statement, report an error.
3889 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3890 reportParseError("unexpected token, expected end of statement");
3893 if (AssemblerOptions.back()->isReorder()) {
3894 reportParseError("`noreorder' must be set before `nomacro'");
3897 AssemblerOptions.back()->setNoMacro();
3898 getTargetStreamer().emitDirectiveSetNoMacro();
3899 Parser.Lex(); // Consume the EndOfStatement.
3903 bool MipsAsmParser::parseSetMsaDirective() {
3904 MCAsmParser &Parser = getParser();
3907 // If this is not the end of the statement, report an error.
3908 if (getLexer().isNot(AsmToken::EndOfStatement))
3909 return reportParseError("unexpected token, expected end of statement");
3911 setFeatureBits(Mips::FeatureMSA, "msa");
3912 getTargetStreamer().emitDirectiveSetMsa();
3916 bool MipsAsmParser::parseSetNoMsaDirective() {
3917 MCAsmParser &Parser = getParser();
3920 // If this is not the end of the statement, report an error.
3921 if (getLexer().isNot(AsmToken::EndOfStatement))
3922 return reportParseError("unexpected token, expected end of statement");
3924 clearFeatureBits(Mips::FeatureMSA, "msa");
3925 getTargetStreamer().emitDirectiveSetNoMsa();
3929 bool MipsAsmParser::parseSetNoDspDirective() {
3930 MCAsmParser &Parser = getParser();
3931 Parser.Lex(); // Eat "nodsp".
3933 // If this is not the end of the statement, report an error.
3934 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3935 reportParseError("unexpected token, expected end of statement");
3939 clearFeatureBits(Mips::FeatureDSP, "dsp");
3940 getTargetStreamer().emitDirectiveSetNoDsp();
3944 bool MipsAsmParser::parseSetMips16Directive() {
3945 MCAsmParser &Parser = getParser();
3946 Parser.Lex(); // Eat "mips16".
3948 // If this is not the end of the statement, report an error.
3949 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3950 reportParseError("unexpected token, expected end of statement");
3954 setFeatureBits(Mips::FeatureMips16, "mips16");
3955 getTargetStreamer().emitDirectiveSetMips16();
3956 Parser.Lex(); // Consume the EndOfStatement.
3960 bool MipsAsmParser::parseSetNoMips16Directive() {
3961 MCAsmParser &Parser = getParser();
3962 Parser.Lex(); // Eat "nomips16".
3964 // If this is not the end of the statement, report an error.
3965 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3966 reportParseError("unexpected token, expected end of statement");
3970 clearFeatureBits(Mips::FeatureMips16, "mips16");
3971 getTargetStreamer().emitDirectiveSetNoMips16();
3972 Parser.Lex(); // Consume the EndOfStatement.
3976 bool MipsAsmParser::parseSetFpDirective() {
3977 MCAsmParser &Parser = getParser();
3978 MipsABIFlagsSection::FpABIKind FpAbiVal;
3979 // Line can be: .set fp=32
3982 Parser.Lex(); // Eat fp token
3983 AsmToken Tok = Parser.getTok();
3984 if (Tok.isNot(AsmToken::Equal)) {
3985 reportParseError("unexpected token, expected equals sign '='");
3988 Parser.Lex(); // Eat '=' token.
3989 Tok = Parser.getTok();
3991 if (!parseFpABIValue(FpAbiVal, ".set"))
3994 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3995 reportParseError("unexpected token, expected end of statement");
3998 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3999 Parser.Lex(); // Consume the EndOfStatement.
4003 bool MipsAsmParser::parseSetPopDirective() {
4004 MCAsmParser &Parser = getParser();
4005 SMLoc Loc = getLexer().getLoc();
4008 if (getLexer().isNot(AsmToken::EndOfStatement))
4009 return reportParseError("unexpected token, expected end of statement");
4011 // Always keep an element on the options "stack" to prevent the user
4012 // from changing the initial options. This is how we remember them.
4013 if (AssemblerOptions.size() == 2)
4014 return reportParseError(Loc, ".set pop with no .set push");
4016 AssemblerOptions.pop_back();
4017 setAvailableFeatures(
4018 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4019 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4021 getTargetStreamer().emitDirectiveSetPop();
4025 bool MipsAsmParser::parseSetPushDirective() {
4026 MCAsmParser &Parser = getParser();
4028 if (getLexer().isNot(AsmToken::EndOfStatement))
4029 return reportParseError("unexpected token, expected end of statement");
4031 // Create a copy of the current assembler options environment and push it.
4032 AssemblerOptions.push_back(
4033 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4035 getTargetStreamer().emitDirectiveSetPush();
4039 bool MipsAsmParser::parseSetSoftFloatDirective() {
4040 MCAsmParser &Parser = getParser();
4042 if (getLexer().isNot(AsmToken::EndOfStatement))
4043 return reportParseError("unexpected token, expected end of statement");
4045 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4046 getTargetStreamer().emitDirectiveSetSoftFloat();
4050 bool MipsAsmParser::parseSetHardFloatDirective() {
4051 MCAsmParser &Parser = getParser();
4053 if (getLexer().isNot(AsmToken::EndOfStatement))
4054 return reportParseError("unexpected token, expected end of statement");
4056 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4057 getTargetStreamer().emitDirectiveSetHardFloat();
4061 bool MipsAsmParser::parseSetAssignment() {
4063 const MCExpr *Value;
4064 MCAsmParser &Parser = getParser();
4066 if (Parser.parseIdentifier(Name))
4067 reportParseError("expected identifier after .set");
4069 if (getLexer().isNot(AsmToken::Comma))
4070 return reportParseError("unexpected token, expected comma");
4073 if (Parser.parseExpression(Value))
4074 return reportParseError("expected valid expression after comma");
4076 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4077 Sym->setVariableValue(Value);
4082 bool MipsAsmParser::parseSetMips0Directive() {
4083 MCAsmParser &Parser = getParser();
4085 if (getLexer().isNot(AsmToken::EndOfStatement))
4086 return reportParseError("unexpected token, expected end of statement");
4088 // Reset assembler options to their initial values.
4089 setAvailableFeatures(
4090 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4091 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4092 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4094 getTargetStreamer().emitDirectiveSetMips0();
4098 bool MipsAsmParser::parseSetArchDirective() {
4099 MCAsmParser &Parser = getParser();
4101 if (getLexer().isNot(AsmToken::Equal))
4102 return reportParseError("unexpected token, expected equals sign");
4106 if (Parser.parseIdentifier(Arch))
4107 return reportParseError("expected arch identifier");
4109 StringRef ArchFeatureName =
4110 StringSwitch<StringRef>(Arch)
4111 .Case("mips1", "mips1")
4112 .Case("mips2", "mips2")
4113 .Case("mips3", "mips3")
4114 .Case("mips4", "mips4")
4115 .Case("mips5", "mips5")
4116 .Case("mips32", "mips32")
4117 .Case("mips32r2", "mips32r2")
4118 .Case("mips32r3", "mips32r3")
4119 .Case("mips32r5", "mips32r5")
4120 .Case("mips32r6", "mips32r6")
4121 .Case("mips64", "mips64")
4122 .Case("mips64r2", "mips64r2")
4123 .Case("mips64r3", "mips64r3")
4124 .Case("mips64r5", "mips64r5")
4125 .Case("mips64r6", "mips64r6")
4126 .Case("cnmips", "cnmips")
4127 .Case("r4000", "mips3") // This is an implementation of Mips3.
4130 if (ArchFeatureName.empty())
4131 return reportParseError("unsupported architecture");
4133 selectArch(ArchFeatureName);
4134 getTargetStreamer().emitDirectiveSetArch(Arch);
4138 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4139 MCAsmParser &Parser = getParser();
4141 if (getLexer().isNot(AsmToken::EndOfStatement))
4142 return reportParseError("unexpected token, expected end of statement");
4146 llvm_unreachable("Unimplemented feature");
4147 case Mips::FeatureDSP:
4148 setFeatureBits(Mips::FeatureDSP, "dsp");
4149 getTargetStreamer().emitDirectiveSetDsp();
4151 case Mips::FeatureMicroMips:
4152 getTargetStreamer().emitDirectiveSetMicroMips();
4154 case Mips::FeatureMips1:
4155 selectArch("mips1");
4156 getTargetStreamer().emitDirectiveSetMips1();
4158 case Mips::FeatureMips2:
4159 selectArch("mips2");
4160 getTargetStreamer().emitDirectiveSetMips2();
4162 case Mips::FeatureMips3:
4163 selectArch("mips3");
4164 getTargetStreamer().emitDirectiveSetMips3();
4166 case Mips::FeatureMips4:
4167 selectArch("mips4");
4168 getTargetStreamer().emitDirectiveSetMips4();
4170 case Mips::FeatureMips5:
4171 selectArch("mips5");
4172 getTargetStreamer().emitDirectiveSetMips5();
4174 case Mips::FeatureMips32:
4175 selectArch("mips32");
4176 getTargetStreamer().emitDirectiveSetMips32();
4178 case Mips::FeatureMips32r2:
4179 selectArch("mips32r2");
4180 getTargetStreamer().emitDirectiveSetMips32R2();
4182 case Mips::FeatureMips32r3:
4183 selectArch("mips32r3");
4184 getTargetStreamer().emitDirectiveSetMips32R3();
4186 case Mips::FeatureMips32r5:
4187 selectArch("mips32r5");
4188 getTargetStreamer().emitDirectiveSetMips32R5();
4190 case Mips::FeatureMips32r6:
4191 selectArch("mips32r6");
4192 getTargetStreamer().emitDirectiveSetMips32R6();
4194 case Mips::FeatureMips64:
4195 selectArch("mips64");
4196 getTargetStreamer().emitDirectiveSetMips64();
4198 case Mips::FeatureMips64r2:
4199 selectArch("mips64r2");
4200 getTargetStreamer().emitDirectiveSetMips64R2();
4202 case Mips::FeatureMips64r3:
4203 selectArch("mips64r3");
4204 getTargetStreamer().emitDirectiveSetMips64R3();
4206 case Mips::FeatureMips64r5:
4207 selectArch("mips64r5");
4208 getTargetStreamer().emitDirectiveSetMips64R5();
4210 case Mips::FeatureMips64r6:
4211 selectArch("mips64r6");
4212 getTargetStreamer().emitDirectiveSetMips64R6();
4218 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4219 MCAsmParser &Parser = getParser();
4220 if (getLexer().isNot(AsmToken::Comma)) {
4221 SMLoc Loc = getLexer().getLoc();
4222 Parser.eatToEndOfStatement();
4223 return Error(Loc, ErrorStr);
4226 Parser.Lex(); // Eat the comma.
4230 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4231 if (AssemblerOptions.back()->isReorder())
4232 Warning(Loc, ".cpload should be inside a noreorder section");
4234 if (inMips16Mode()) {
4235 reportParseError(".cpload is not supported in Mips16 mode");
4239 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4240 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4241 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4242 reportParseError("expected register containing function address");
4246 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4247 if (!RegOpnd.isGPRAsmReg()) {
4248 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4252 // If this is not the end of the statement, report an error.
4253 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4254 reportParseError("unexpected token, expected end of statement");
4258 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4262 bool MipsAsmParser::parseDirectiveCPSetup() {
4263 MCAsmParser &Parser = getParser();
4266 bool SaveIsReg = true;
4268 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4269 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4270 if (ResTy == MatchOperand_NoMatch) {
4271 reportParseError("expected register containing function address");
4272 Parser.eatToEndOfStatement();
4276 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4277 if (!FuncRegOpnd.isGPRAsmReg()) {
4278 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4279 Parser.eatToEndOfStatement();
4283 FuncReg = FuncRegOpnd.getGPR32Reg();
4286 if (!eatComma("unexpected token, expected comma"))
4289 ResTy = parseAnyRegister(TmpReg);
4290 if (ResTy == MatchOperand_NoMatch) {
4291 const AsmToken &Tok = Parser.getTok();
4292 if (Tok.is(AsmToken::Integer)) {
4293 Save = Tok.getIntVal();
4297 reportParseError("expected save register or stack offset");
4298 Parser.eatToEndOfStatement();
4302 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4303 if (!SaveOpnd.isGPRAsmReg()) {
4304 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4305 Parser.eatToEndOfStatement();
4308 Save = SaveOpnd.getGPR32Reg();
4311 if (!eatComma("unexpected token, expected comma"))
4315 if (Parser.parseExpression(Expr)) {
4316 reportParseError("expected expression");
4320 if (Expr->getKind() != MCExpr::SymbolRef) {
4321 reportParseError("expected symbol");
4324 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4326 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4331 bool MipsAsmParser::parseDirectiveNaN() {
4332 MCAsmParser &Parser = getParser();
4333 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4334 const AsmToken &Tok = Parser.getTok();
4336 if (Tok.getString() == "2008") {
4338 getTargetStreamer().emitDirectiveNaN2008();
4340 } else if (Tok.getString() == "legacy") {
4342 getTargetStreamer().emitDirectiveNaNLegacy();
4346 // If we don't recognize the option passed to the .nan
4347 // directive (e.g. no option or unknown option), emit an error.
4348 reportParseError("invalid option in .nan directive");
4352 bool MipsAsmParser::parseDirectiveSet() {
4353 MCAsmParser &Parser = getParser();
4354 // Get the next token.
4355 const AsmToken &Tok = Parser.getTok();
4357 if (Tok.getString() == "noat") {
4358 return parseSetNoAtDirective();
4359 } else if (Tok.getString() == "at") {
4360 return parseSetAtDirective();
4361 } else if (Tok.getString() == "arch") {
4362 return parseSetArchDirective();
4363 } else if (Tok.getString() == "fp") {
4364 return parseSetFpDirective();
4365 } else if (Tok.getString() == "pop") {
4366 return parseSetPopDirective();
4367 } else if (Tok.getString() == "push") {
4368 return parseSetPushDirective();
4369 } else if (Tok.getString() == "reorder") {
4370 return parseSetReorderDirective();
4371 } else if (Tok.getString() == "noreorder") {
4372 return parseSetNoReorderDirective();
4373 } else if (Tok.getString() == "macro") {
4374 return parseSetMacroDirective();
4375 } else if (Tok.getString() == "nomacro") {
4376 return parseSetNoMacroDirective();
4377 } else if (Tok.getString() == "mips16") {
4378 return parseSetMips16Directive();
4379 } else if (Tok.getString() == "nomips16") {
4380 return parseSetNoMips16Directive();
4381 } else if (Tok.getString() == "nomicromips") {
4382 getTargetStreamer().emitDirectiveSetNoMicroMips();
4383 Parser.eatToEndOfStatement();
4385 } else if (Tok.getString() == "micromips") {
4386 return parseSetFeature(Mips::FeatureMicroMips);
4387 } else if (Tok.getString() == "mips0") {
4388 return parseSetMips0Directive();
4389 } else if (Tok.getString() == "mips1") {
4390 return parseSetFeature(Mips::FeatureMips1);
4391 } else if (Tok.getString() == "mips2") {
4392 return parseSetFeature(Mips::FeatureMips2);
4393 } else if (Tok.getString() == "mips3") {
4394 return parseSetFeature(Mips::FeatureMips3);
4395 } else if (Tok.getString() == "mips4") {
4396 return parseSetFeature(Mips::FeatureMips4);
4397 } else if (Tok.getString() == "mips5") {
4398 return parseSetFeature(Mips::FeatureMips5);
4399 } else if (Tok.getString() == "mips32") {
4400 return parseSetFeature(Mips::FeatureMips32);
4401 } else if (Tok.getString() == "mips32r2") {
4402 return parseSetFeature(Mips::FeatureMips32r2);
4403 } else if (Tok.getString() == "mips32r3") {
4404 return parseSetFeature(Mips::FeatureMips32r3);
4405 } else if (Tok.getString() == "mips32r5") {
4406 return parseSetFeature(Mips::FeatureMips32r5);
4407 } else if (Tok.getString() == "mips32r6") {
4408 return parseSetFeature(Mips::FeatureMips32r6);
4409 } else if (Tok.getString() == "mips64") {
4410 return parseSetFeature(Mips::FeatureMips64);
4411 } else if (Tok.getString() == "mips64r2") {
4412 return parseSetFeature(Mips::FeatureMips64r2);
4413 } else if (Tok.getString() == "mips64r3") {
4414 return parseSetFeature(Mips::FeatureMips64r3);
4415 } else if (Tok.getString() == "mips64r5") {
4416 return parseSetFeature(Mips::FeatureMips64r5);
4417 } else if (Tok.getString() == "mips64r6") {
4418 return parseSetFeature(Mips::FeatureMips64r6);
4419 } else if (Tok.getString() == "dsp") {
4420 return parseSetFeature(Mips::FeatureDSP);
4421 } else if (Tok.getString() == "nodsp") {
4422 return parseSetNoDspDirective();
4423 } else if (Tok.getString() == "msa") {
4424 return parseSetMsaDirective();
4425 } else if (Tok.getString() == "nomsa") {
4426 return parseSetNoMsaDirective();
4427 } else if (Tok.getString() == "softfloat") {
4428 return parseSetSoftFloatDirective();
4429 } else if (Tok.getString() == "hardfloat") {
4430 return parseSetHardFloatDirective();
4432 // It is just an identifier, look for an assignment.
4433 parseSetAssignment();
4440 /// parseDataDirective
4441 /// ::= .word [ expression (, expression)* ]
4442 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4443 MCAsmParser &Parser = getParser();
4444 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4446 const MCExpr *Value;
4447 if (getParser().parseExpression(Value))
4450 getParser().getStreamer().EmitValue(Value, Size);
4452 if (getLexer().is(AsmToken::EndOfStatement))
4455 if (getLexer().isNot(AsmToken::Comma))
4456 return Error(L, "unexpected token, expected comma");
4465 /// parseDirectiveGpWord
4466 /// ::= .gpword local_sym
4467 bool MipsAsmParser::parseDirectiveGpWord() {
4468 MCAsmParser &Parser = getParser();
4469 const MCExpr *Value;
4470 // EmitGPRel32Value requires an expression, so we are using base class
4471 // method to evaluate the expression.
4472 if (getParser().parseExpression(Value))
4474 getParser().getStreamer().EmitGPRel32Value(Value);
4476 if (getLexer().isNot(AsmToken::EndOfStatement))
4477 return Error(getLexer().getLoc(),
4478 "unexpected token, expected end of statement");
4479 Parser.Lex(); // Eat EndOfStatement token.
4483 /// parseDirectiveGpDWord
4484 /// ::= .gpdword local_sym
4485 bool MipsAsmParser::parseDirectiveGpDWord() {
4486 MCAsmParser &Parser = getParser();
4487 const MCExpr *Value;
4488 // EmitGPRel64Value requires an expression, so we are using base class
4489 // method to evaluate the expression.
4490 if (getParser().parseExpression(Value))
4492 getParser().getStreamer().EmitGPRel64Value(Value);
4494 if (getLexer().isNot(AsmToken::EndOfStatement))
4495 return Error(getLexer().getLoc(),
4496 "unexpected token, expected end of statement");
4497 Parser.Lex(); // Eat EndOfStatement token.
4501 bool MipsAsmParser::parseDirectiveOption() {
4502 MCAsmParser &Parser = getParser();
4503 // Get the option token.
4504 AsmToken Tok = Parser.getTok();
4505 // At the moment only identifiers are supported.
4506 if (Tok.isNot(AsmToken::Identifier)) {
4507 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4508 Parser.eatToEndOfStatement();
4512 StringRef Option = Tok.getIdentifier();
4514 if (Option == "pic0") {
4515 getTargetStreamer().emitDirectiveOptionPic0();
4517 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4518 Error(Parser.getTok().getLoc(),
4519 "unexpected token, expected end of statement");
4520 Parser.eatToEndOfStatement();
4525 if (Option == "pic2") {
4526 getTargetStreamer().emitDirectiveOptionPic2();
4528 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4529 Error(Parser.getTok().getLoc(),
4530 "unexpected token, expected end of statement");
4531 Parser.eatToEndOfStatement();
4537 Warning(Parser.getTok().getLoc(),
4538 "unknown option, expected 'pic0' or 'pic2'");
4539 Parser.eatToEndOfStatement();
4543 /// parseInsnDirective
4545 bool MipsAsmParser::parseInsnDirective() {
4546 // If this is not the end of the statement, report an error.
4547 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4548 reportParseError("unexpected token, expected end of statement");
4552 // The actual label marking happens in
4553 // MipsELFStreamer::createPendingLabelRelocs().
4554 getTargetStreamer().emitDirectiveInsn();
4556 getParser().Lex(); // Eat EndOfStatement token.
4560 /// parseDirectiveModule
4561 /// ::= .module oddspreg
4562 /// ::= .module nooddspreg
4563 /// ::= .module fp=value
4564 bool MipsAsmParser::parseDirectiveModule() {
4565 MCAsmParser &Parser = getParser();
4566 MCAsmLexer &Lexer = getLexer();
4567 SMLoc L = Lexer.getLoc();
4569 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4570 // TODO : get a better message.
4571 reportParseError(".module directive must appear before any code");
4576 if (Parser.parseIdentifier(Option)) {
4577 reportParseError("expected .module option identifier");
4581 if (Option == "oddspreg") {
4582 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4583 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4585 // If this is not the end of the statement, report an error.
4586 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4587 reportParseError("unexpected token, expected end of statement");
4591 return false; // parseDirectiveModule has finished successfully.
4592 } else if (Option == "nooddspreg") {
4594 Error(L, "'.module nooddspreg' requires the O32 ABI");
4598 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4599 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4601 // If this is not the end of the statement, report an error.
4602 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4603 reportParseError("unexpected token, expected end of statement");
4607 return false; // parseDirectiveModule has finished successfully.
4608 } else if (Option == "fp") {
4609 return parseDirectiveModuleFP();
4611 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4615 /// parseDirectiveModuleFP
4619 bool MipsAsmParser::parseDirectiveModuleFP() {
4620 MCAsmParser &Parser = getParser();
4621 MCAsmLexer &Lexer = getLexer();
4623 if (Lexer.isNot(AsmToken::Equal)) {
4624 reportParseError("unexpected token, expected equals sign '='");
4627 Parser.Lex(); // Eat '=' token.
4629 MipsABIFlagsSection::FpABIKind FpABI;
4630 if (!parseFpABIValue(FpABI, ".module"))
4633 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4634 reportParseError("unexpected token, expected end of statement");
4638 // Emit appropriate flags.
4639 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4640 Parser.Lex(); // Consume the EndOfStatement.
4644 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4645 StringRef Directive) {
4646 MCAsmParser &Parser = getParser();
4647 MCAsmLexer &Lexer = getLexer();
4649 if (Lexer.is(AsmToken::Identifier)) {
4650 StringRef Value = Parser.getTok().getString();
4653 if (Value != "xx") {
4654 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4659 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4663 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4667 if (Lexer.is(AsmToken::Integer)) {
4668 unsigned Value = Parser.getTok().getIntVal();
4671 if (Value != 32 && Value != 64) {
4672 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4678 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4682 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4684 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4692 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4693 MCAsmParser &Parser = getParser();
4694 StringRef IDVal = DirectiveID.getString();
4696 if (IDVal == ".cpload")
4697 return parseDirectiveCpLoad(DirectiveID.getLoc());
4698 if (IDVal == ".dword") {
4699 parseDataDirective(8, DirectiveID.getLoc());
4702 if (IDVal == ".ent") {
4703 StringRef SymbolName;
4705 if (Parser.parseIdentifier(SymbolName)) {
4706 reportParseError("expected identifier after .ent");
4710 // There's an undocumented extension that allows an integer to
4711 // follow the name of the procedure which AFAICS is ignored by GAS.
4712 // Example: .ent foo,2
4713 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4714 if (getLexer().isNot(AsmToken::Comma)) {
4715 // Even though we accept this undocumented extension for compatibility
4716 // reasons, the additional integer argument does not actually change
4717 // the behaviour of the '.ent' directive, so we would like to discourage
4718 // its use. We do this by not referring to the extended version in
4719 // error messages which are not directly related to its use.
4720 reportParseError("unexpected token, expected end of statement");
4723 Parser.Lex(); // Eat the comma.
4724 const MCExpr *DummyNumber;
4725 int64_t DummyNumberVal;
4726 // If the user was explicitly trying to use the extended version,
4727 // we still give helpful extension-related error messages.
4728 if (Parser.parseExpression(DummyNumber)) {
4729 reportParseError("expected number after comma");
4732 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
4733 reportParseError("expected an absolute expression after comma");
4738 // If this is not the end of the statement, report an error.
4739 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4740 reportParseError("unexpected token, expected end of statement");
4744 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
4746 getTargetStreamer().emitDirectiveEnt(*Sym);
4751 if (IDVal == ".end") {
4752 StringRef SymbolName;
4754 if (Parser.parseIdentifier(SymbolName)) {
4755 reportParseError("expected identifier after .end");
4759 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4760 reportParseError("unexpected token, expected end of statement");
4764 if (CurrentFn == nullptr) {
4765 reportParseError(".end used without .ent");
4769 if ((SymbolName != CurrentFn->getName())) {
4770 reportParseError(".end symbol does not match .ent symbol");
4774 getTargetStreamer().emitDirectiveEnd(SymbolName);
4775 CurrentFn = nullptr;
4779 if (IDVal == ".frame") {
4780 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4781 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4782 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4783 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4784 reportParseError("expected stack register");
4788 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4789 if (!StackRegOpnd.isGPRAsmReg()) {
4790 reportParseError(StackRegOpnd.getStartLoc(),
4791 "expected general purpose register");
4794 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4796 if (Parser.getTok().is(AsmToken::Comma))
4799 reportParseError("unexpected token, expected comma");
4803 // Parse the frame size.
4804 const MCExpr *FrameSize;
4805 int64_t FrameSizeVal;
4807 if (Parser.parseExpression(FrameSize)) {
4808 reportParseError("expected frame size value");
4812 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
4813 reportParseError("frame size not an absolute expression");
4817 if (Parser.getTok().is(AsmToken::Comma))
4820 reportParseError("unexpected token, expected comma");
4824 // Parse the return register.
4826 ResTy = parseAnyRegister(TmpReg);
4827 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4828 reportParseError("expected return register");
4832 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4833 if (!ReturnRegOpnd.isGPRAsmReg()) {
4834 reportParseError(ReturnRegOpnd.getStartLoc(),
4835 "expected general purpose register");
4839 // If this is not the end of the statement, report an error.
4840 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4841 reportParseError("unexpected token, expected end of statement");
4845 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4846 ReturnRegOpnd.getGPR32Reg());
4850 if (IDVal == ".set") {
4851 return parseDirectiveSet();
4854 if (IDVal == ".mask" || IDVal == ".fmask") {
4855 // .mask bitmask, frame_offset
4856 // bitmask: One bit for each register used.
4857 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4858 // first register is expected to be saved.
4860 // .mask 0x80000000, -4
4861 // .fmask 0x80000000, -4
4864 // Parse the bitmask
4865 const MCExpr *BitMask;
4868 if (Parser.parseExpression(BitMask)) {
4869 reportParseError("expected bitmask value");
4873 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
4874 reportParseError("bitmask not an absolute expression");
4878 if (Parser.getTok().is(AsmToken::Comma))
4881 reportParseError("unexpected token, expected comma");
4885 // Parse the frame_offset
4886 const MCExpr *FrameOffset;
4887 int64_t FrameOffsetVal;
4889 if (Parser.parseExpression(FrameOffset)) {
4890 reportParseError("expected frame offset value");
4894 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
4895 reportParseError("frame offset not an absolute expression");
4899 // If this is not the end of the statement, report an error.
4900 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4901 reportParseError("unexpected token, expected end of statement");
4905 if (IDVal == ".mask")
4906 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4908 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4912 if (IDVal == ".nan")
4913 return parseDirectiveNaN();
4915 if (IDVal == ".gpword") {
4916 parseDirectiveGpWord();
4920 if (IDVal == ".gpdword") {
4921 parseDirectiveGpDWord();
4925 if (IDVal == ".word") {
4926 parseDataDirective(4, DirectiveID.getLoc());
4930 if (IDVal == ".option")
4931 return parseDirectiveOption();
4933 if (IDVal == ".abicalls") {
4934 getTargetStreamer().emitDirectiveAbiCalls();
4935 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4936 Error(Parser.getTok().getLoc(),
4937 "unexpected token, expected end of statement");
4939 Parser.eatToEndOfStatement();
4944 if (IDVal == ".cpsetup")
4945 return parseDirectiveCPSetup();
4947 if (IDVal == ".module")
4948 return parseDirectiveModule();
4950 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4951 return parseInternalDirectiveReallowModule();
4953 if (IDVal == ".insn")
4954 return parseInsnDirective();
4959 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4960 // If this is not the end of the statement, report an error.
4961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4962 reportParseError("unexpected token, expected end of statement");
4966 getTargetStreamer().reallowModuleDirective();
4968 getParser().Lex(); // Eat EndOfStatement token.
4972 extern "C" void LLVMInitializeMipsAsmParser() {
4973 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4974 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4975 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4976 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4979 #define GET_REGISTER_MATCHER
4980 #define GET_MATCHER_IMPLEMENTATION
4981 #include "MipsGenAsmMatcher.inc"