1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetObjectFile.h"
15 #include "MipsTargetStreamer.h"
16 #include "llvm/ADT/APInt.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstBuilder.h"
23 #include "llvm/MC/MCParser/MCAsmLexer.h"
24 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
25 #include "llvm/MC/MCStreamer.h"
26 #include "llvm/MC/MCSubtargetInfo.h"
27 #include "llvm/MC/MCSymbol.h"
28 #include "llvm/MC/MCTargetAsmParser.h"
29 #include "llvm/Support/Debug.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/SourceMgr.h"
32 #include "llvm/Support/TargetRegistry.h"
33 #include "llvm/Support/raw_ostream.h"
38 #define DEBUG_TYPE "mips-asm-parser"
45 class MipsAssemblerOptions {
47 MipsAssemblerOptions(const FeatureBitset &Features_) :
48 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
50 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
51 ATReg = Opts->getATRegIndex();
52 Reorder = Opts->isReorder();
53 Macro = Opts->isMacro();
54 Features = Opts->getFeatures();
57 unsigned getATRegIndex() const { return ATReg; }
58 bool setATRegIndex(unsigned Reg) {
66 bool isReorder() const { return Reorder; }
67 void setReorder() { Reorder = true; }
68 void setNoReorder() { Reorder = false; }
70 bool isMacro() const { return Macro; }
71 void setMacro() { Macro = true; }
72 void setNoMacro() { Macro = false; }
74 const FeatureBitset &getFeatures() const { return Features; }
75 void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
77 // Set of features that are either architecture features or referenced
78 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
79 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
80 // The reason we need this mask is explained in the selectArch function.
81 // FIXME: Ideally we would like TableGen to generate this information.
82 static const FeatureBitset AllArchRelatedMask;
88 FeatureBitset Features;
92 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
93 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
94 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
95 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
96 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
97 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
98 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
99 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
100 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
104 class MipsAsmParser : public MCTargetAsmParser {
105 MipsTargetStreamer &getTargetStreamer() {
106 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
107 return static_cast<MipsTargetStreamer &>(TS);
110 MCSubtargetInfo &STI;
112 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
113 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
114 // nullptr, which indicates that no function is currently
115 // selected. This usually happens after an '.end func'
120 // Print a warning along with its fix-it message at the given range.
121 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
122 SMRange Range, bool ShowColors = true);
124 #define GET_ASSEMBLER_HEADER
125 #include "MipsGenAsmMatcher.inc"
127 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
129 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
130 OperandVector &Operands, MCStreamer &Out,
132 bool MatchingInlineAsm) override;
134 /// Parse a register as used in CFI directives
135 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
137 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
139 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
141 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
142 SMLoc NameLoc, OperandVector &Operands) override;
144 bool ParseDirective(AsmToken DirectiveID) override;
146 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
148 MipsAsmParser::OperandMatchResultTy
149 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
150 StringRef Identifier, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy
153 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
155 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
161 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
163 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterPair (OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseMovePRegPair(OperandVector &Operands);
171 MipsAsmParser::OperandMatchResultTy
172 parseRegisterList (OperandVector &Operands);
174 bool searchSymbolAlias(OperandVector &Operands);
176 bool parseOperand(OperandVector &, StringRef Mnemonic);
178 bool needsExpansion(MCInst &Inst);
180 // Expands assembly pseudo instructions.
181 // Returns false on success, true otherwise.
182 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
189 bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
190 SmallVectorImpl<MCInst> &Instructions);
192 bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
193 unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions);
199 bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
200 const MCOperand &Offset, bool Is32BitAddress,
201 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions);
203 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
210 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
211 SmallVectorImpl<MCInst> &Instructions);
213 bool expandBranchImm(MCInst &Inst, SMLoc IDLoc,
214 SmallVectorImpl<MCInst> &Instructions);
216 bool expandCondBranches(MCInst &Inst, SMLoc IDLoc,
217 SmallVectorImpl<MCInst> &Instructions);
219 bool expandDiv(MCInst &Inst, SMLoc IDLoc,
220 SmallVectorImpl<MCInst> &Instructions, const bool IsMips64,
223 bool expandUlhu(MCInst &Inst, SMLoc IDLoc,
224 SmallVectorImpl<MCInst> &Instructions);
226 bool expandUlw(MCInst &Inst, SMLoc IDLoc,
227 SmallVectorImpl<MCInst> &Instructions);
229 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
230 SmallVectorImpl<MCInst> &Instructions);
232 void createAddu(unsigned DstReg, unsigned SrcReg, unsigned TrgReg,
233 bool Is64Bit, SmallVectorImpl<MCInst> &Instructions);
235 bool reportParseError(Twine ErrorMsg);
236 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
238 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
239 bool parseRelocOperand(const MCExpr *&Res);
241 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
243 bool isEvaluated(const MCExpr *Expr);
244 bool parseSetMips0Directive();
245 bool parseSetArchDirective();
246 bool parseSetFeature(uint64_t Feature);
247 bool parseDirectiveCpLoad(SMLoc Loc);
248 bool parseDirectiveCPSetup();
249 bool parseDirectiveNaN();
250 bool parseDirectiveSet();
251 bool parseDirectiveOption();
252 bool parseInsnDirective();
254 bool parseSetAtDirective();
255 bool parseSetNoAtDirective();
256 bool parseSetMacroDirective();
257 bool parseSetNoMacroDirective();
258 bool parseSetMsaDirective();
259 bool parseSetNoMsaDirective();
260 bool parseSetNoDspDirective();
261 bool parseSetReorderDirective();
262 bool parseSetNoReorderDirective();
263 bool parseSetMips16Directive();
264 bool parseSetNoMips16Directive();
265 bool parseSetFpDirective();
266 bool parseSetOddSPRegDirective();
267 bool parseSetNoOddSPRegDirective();
268 bool parseSetPopDirective();
269 bool parseSetPushDirective();
270 bool parseSetSoftFloatDirective();
271 bool parseSetHardFloatDirective();
273 bool parseSetAssignment();
275 bool parseDataDirective(unsigned Size, SMLoc L);
276 bool parseDirectiveGpWord();
277 bool parseDirectiveGpDWord();
278 bool parseDirectiveModule();
279 bool parseDirectiveModuleFP();
280 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
281 StringRef Directive);
283 bool parseInternalDirectiveReallowModule();
285 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
287 bool eatComma(StringRef ErrorStr);
289 int matchCPURegisterName(StringRef Symbol);
291 int matchHWRegsRegisterName(StringRef Symbol);
293 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
295 int matchFPURegisterName(StringRef Name);
297 int matchFCCRegisterName(StringRef Name);
299 int matchACRegisterName(StringRef Name);
301 int matchMSA128RegisterName(StringRef Name);
303 int matchMSA128CtrlRegisterName(StringRef Name);
305 unsigned getReg(int RC, int RegNo);
307 unsigned getGPR(int RegNo);
309 /// Returns the internal register number for the current AT. Also checks if
310 /// the current AT is unavailable (set to $0) and gives an error if it is.
311 /// This should be used in pseudo-instruction expansions which need AT.
312 unsigned getATReg(SMLoc Loc);
314 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
315 SmallVectorImpl<MCInst> &Instructions);
317 // Helper function that checks if the value of a vector index is within the
318 // boundaries of accepted values for each RegisterKind
319 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
320 bool validateMSAIndex(int Val, int RegKind);
322 // Selects a new architecture by updating the FeatureBits with the necessary
323 // info including implied dependencies.
324 // Internally, it clears all the feature bits related to *any* architecture
325 // and selects the new one using the ToggleFeature functionality of the
326 // MCSubtargetInfo object that handles implied dependencies. The reason we
327 // clear all the arch related bits manually is because ToggleFeature only
328 // clears the features that imply the feature being cleared and not the
329 // features implied by the feature being cleared. This is easier to see
331 // --------------------------------------------------
332 // | Feature | Implies |
333 // | -------------------------------------------------|
334 // | FeatureMips1 | None |
335 // | FeatureMips2 | FeatureMips1 |
336 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
337 // | FeatureMips4 | FeatureMips3 |
339 // --------------------------------------------------
341 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
342 // FeatureMipsGP64 | FeatureMips1)
343 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
344 void selectArch(StringRef ArchFeature) {
345 FeatureBitset FeatureBits = STI.getFeatureBits();
346 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
347 STI.setFeatureBits(FeatureBits);
348 setAvailableFeatures(
349 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
350 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
353 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
354 if (!(STI.getFeatureBits()[Feature])) {
355 setAvailableFeatures(
356 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
357 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
361 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
362 if (STI.getFeatureBits()[Feature]) {
363 setAvailableFeatures(
364 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
365 AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
369 void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
370 setFeatureBits(Feature, FeatureString);
371 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
374 void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
375 clearFeatureBits(Feature, FeatureString);
376 AssemblerOptions.front()->setFeatures(STI.getFeatureBits());
380 enum MipsMatchResultTy {
381 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
382 #define GET_OPERAND_DIAGNOSTIC_TYPES
383 #include "MipsGenAsmMatcher.inc"
384 #undef GET_OPERAND_DIAGNOSTIC_TYPES
388 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
389 const MCInstrInfo &MII, const MCTargetOptions &Options)
390 : MCTargetAsmParser(Options), STI(sti),
391 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
392 sti.getCPU(), Options)) {
393 MCAsmParserExtension::Initialize(parser);
395 parser.addAliasForDirective(".asciiz", ".asciz");
397 // Initialize the set of available features.
398 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
400 // Remember the initial assembler options. The user can not modify these.
401 AssemblerOptions.push_back(
402 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
404 // Create an assembler options environment for the user to modify.
405 AssemblerOptions.push_back(
406 llvm::make_unique<MipsAssemblerOptions>(STI.getFeatureBits()));
408 getTargetStreamer().updateABIInfo(*this);
410 if (!isABI_O32() && !useOddSPReg() != 0)
411 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
416 (getContext().getObjectFileInfo()->getRelocM() == Reloc::PIC_);
418 Triple TheTriple(sti.getTargetTriple());
419 if ((TheTriple.getArch() == Triple::mips) ||
420 (TheTriple.getArch() == Triple::mips64))
421 IsLittleEndian = false;
423 IsLittleEndian = true;
426 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
427 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
429 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
430 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
431 const MipsABIInfo &getABI() const { return ABI; }
432 bool isABI_N32() const { return ABI.IsN32(); }
433 bool isABI_N64() const { return ABI.IsN64(); }
434 bool isABI_O32() const { return ABI.IsO32(); }
435 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
437 bool useOddSPReg() const {
438 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
441 bool inMicroMipsMode() const {
442 return STI.getFeatureBits()[Mips::FeatureMicroMips];
444 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
445 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
446 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
447 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
448 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
449 bool hasMips32() const {
450 return STI.getFeatureBits()[Mips::FeatureMips32];
452 bool hasMips64() const {
453 return STI.getFeatureBits()[Mips::FeatureMips64];
455 bool hasMips32r2() const {
456 return STI.getFeatureBits()[Mips::FeatureMips32r2];
458 bool hasMips64r2() const {
459 return STI.getFeatureBits()[Mips::FeatureMips64r2];
461 bool hasMips32r3() const {
462 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
464 bool hasMips64r3() const {
465 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
467 bool hasMips32r5() const {
468 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
470 bool hasMips64r5() const {
471 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
473 bool hasMips32r6() const {
474 return STI.getFeatureBits()[Mips::FeatureMips32r6];
476 bool hasMips64r6() const {
477 return STI.getFeatureBits()[Mips::FeatureMips64r6];
480 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
481 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
482 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
483 bool hasCnMips() const {
484 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
491 bool inMips16Mode() const {
492 return STI.getFeatureBits()[Mips::FeatureMips16];
495 bool useTraps() const {
496 return STI.getFeatureBits()[Mips::FeatureUseTCCInDIV];
499 bool useSoftFloat() const {
500 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
503 /// Warn if RegIndex is the same as the current AT.
504 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
506 void warnIfNoMacro(SMLoc Loc);
508 bool isLittle() const { return IsLittleEndian; }
514 /// MipsOperand - Instances of this class represent a parsed Mips machine
516 class MipsOperand : public MCParsedAsmOperand {
518 /// Broad categories of register classes
519 /// The exact class is finalized by the render method.
521 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
522 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
524 RegKind_FCC = 4, /// FCC
525 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
526 RegKind_MSACtrl = 16, /// MSA control registers
527 RegKind_COP2 = 32, /// COP2
528 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
530 RegKind_CCR = 128, /// CCR
531 RegKind_HWRegs = 256, /// HWRegs
532 RegKind_COP3 = 512, /// COP3
533 RegKind_COP0 = 1024, /// COP0
534 /// Potentially any (e.g. $1)
535 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
536 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
537 RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
542 k_Immediate, /// An immediate (possibly involving symbol references)
543 k_Memory, /// Base + Offset Memory Address
544 k_PhysRegister, /// A physical register from the Mips namespace
545 k_RegisterIndex, /// A register index in one or more RegKind.
546 k_Token, /// A simple token
547 k_RegList, /// A physical register list
548 k_RegPair /// A pair of physical register
552 MipsOperand(KindTy K, MipsAsmParser &Parser)
553 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
556 /// For diagnostics, and checking the assembler temporary
557 MipsAsmParser &AsmParser;
565 unsigned Num; /// Register Number
569 unsigned Index; /// Index into the register class
570 RegKind Kind; /// Bitfield of the kinds it could possibly be
571 const MCRegisterInfo *RegInfo;
584 SmallVector<unsigned, 10> *List;
589 struct PhysRegOp PhysReg;
590 struct RegIdxOp RegIdx;
593 struct RegListOp RegList;
596 SMLoc StartLoc, EndLoc;
598 /// Internal constructor for register kinds
599 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
600 const MCRegisterInfo *RegInfo,
602 MipsAsmParser &Parser) {
603 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
604 Op->RegIdx.Index = Index;
605 Op->RegIdx.RegInfo = RegInfo;
606 Op->RegIdx.Kind = RegKind;
613 /// Coerce the register to GPR32 and return the real register for the current
615 unsigned getGPR32Reg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
617 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
618 unsigned ClassID = Mips::GPR32RegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
622 /// Coerce the register to GPR32 and return the real register for the current
624 unsigned getGPRMM16Reg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
626 unsigned ClassID = Mips::GPR32RegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 /// Coerce the register to GPR64 and return the real register for the current
632 unsigned getGPR64Reg() const {
633 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
634 unsigned ClassID = Mips::GPR64RegClassID;
635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 /// Coerce the register to AFGR64 and return the real register for the current
641 unsigned getAFGR64Reg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
643 if (RegIdx.Index % 2 != 0)
644 AsmParser.Warning(StartLoc, "Float register should be even.");
645 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
646 .getRegister(RegIdx.Index / 2);
649 /// Coerce the register to FGR64 and return the real register for the current
651 unsigned getFGR64Reg() const {
652 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
653 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
654 .getRegister(RegIdx.Index);
657 /// Coerce the register to FGR32 and return the real register for the current
659 unsigned getFGR32Reg() const {
660 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
661 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
662 .getRegister(RegIdx.Index);
665 /// Coerce the register to FGRH32 and return the real register for the current
667 unsigned getFGRH32Reg() const {
668 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
669 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
670 .getRegister(RegIdx.Index);
673 /// Coerce the register to FCC and return the real register for the current
675 unsigned getFCCReg() const {
676 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
677 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
678 .getRegister(RegIdx.Index);
681 /// Coerce the register to MSA128 and return the real register for the current
683 unsigned getMSA128Reg() const {
684 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
685 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
687 unsigned ClassID = Mips::MSA128BRegClassID;
688 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
691 /// Coerce the register to MSACtrl and return the real register for the
693 unsigned getMSACtrlReg() const {
694 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
695 unsigned ClassID = Mips::MSACtrlRegClassID;
696 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
699 /// Coerce the register to COP0 and return the real register for the
701 unsigned getCOP0Reg() const {
702 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
703 unsigned ClassID = Mips::COP0RegClassID;
704 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
707 /// Coerce the register to COP2 and return the real register for the
709 unsigned getCOP2Reg() const {
710 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
711 unsigned ClassID = Mips::COP2RegClassID;
712 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
715 /// Coerce the register to COP3 and return the real register for the
717 unsigned getCOP3Reg() const {
718 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
719 unsigned ClassID = Mips::COP3RegClassID;
720 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
723 /// Coerce the register to ACC64DSP and return the real register for the
725 unsigned getACC64DSPReg() const {
726 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
727 unsigned ClassID = Mips::ACC64DSPRegClassID;
728 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
731 /// Coerce the register to HI32DSP and return the real register for the
733 unsigned getHI32DSPReg() const {
734 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
735 unsigned ClassID = Mips::HI32DSPRegClassID;
736 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
739 /// Coerce the register to LO32DSP and return the real register for the
741 unsigned getLO32DSPReg() const {
742 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
743 unsigned ClassID = Mips::LO32DSPRegClassID;
744 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
747 /// Coerce the register to CCR and return the real register for the
749 unsigned getCCRReg() const {
750 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
751 unsigned ClassID = Mips::CCRRegClassID;
752 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
755 /// Coerce the register to HWRegs and return the real register for the
757 unsigned getHWRegsReg() const {
758 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
759 unsigned ClassID = Mips::HWRegsRegClassID;
760 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
764 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
765 // Add as immediate when possible. Null MCExpr = 0.
767 Inst.addOperand(MCOperand::createImm(0));
768 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
769 Inst.addOperand(MCOperand::createImm(CE->getValue()));
771 Inst.addOperand(MCOperand::createExpr(Expr));
774 void addRegOperands(MCInst &Inst, unsigned N) const {
775 llvm_unreachable("Use a custom parser instead");
778 /// Render the operand to an MCInst as a GPR32
779 /// Asserts if the wrong number of operands are requested, or the operand
780 /// is not a k_RegisterIndex compatible with RegKind_GPR
781 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
782 assert(N == 1 && "Invalid number of operands!");
783 Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
786 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
787 assert(N == 1 && "Invalid number of operands!");
788 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
791 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
792 assert(N == 1 && "Invalid number of operands!");
793 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
796 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
797 assert(N == 1 && "Invalid number of operands!");
798 Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
801 /// Render the operand to an MCInst as a GPR64
802 /// Asserts if the wrong number of operands are requested, or the operand
803 /// is not a k_RegisterIndex compatible with RegKind_GPR
804 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
809 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
810 assert(N == 1 && "Invalid number of operands!");
811 Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
814 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
815 assert(N == 1 && "Invalid number of operands!");
816 Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
819 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 1 && "Invalid number of operands!");
821 Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
822 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
823 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
824 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
828 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
830 Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
833 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
834 assert(N == 1 && "Invalid number of operands!");
835 Inst.addOperand(MCOperand::createReg(getFCCReg()));
838 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
839 assert(N == 1 && "Invalid number of operands!");
840 Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
843 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 1 && "Invalid number of operands!");
845 Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
848 void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
849 assert(N == 1 && "Invalid number of operands!");
850 Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
853 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
854 assert(N == 1 && "Invalid number of operands!");
855 Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
858 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
859 assert(N == 1 && "Invalid number of operands!");
860 Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
863 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
864 assert(N == 1 && "Invalid number of operands!");
865 Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
868 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
869 assert(N == 1 && "Invalid number of operands!");
870 Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
873 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
874 assert(N == 1 && "Invalid number of operands!");
875 Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
878 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
879 assert(N == 1 && "Invalid number of operands!");
880 Inst.addOperand(MCOperand::createReg(getCCRReg()));
883 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
884 assert(N == 1 && "Invalid number of operands!");
885 Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
888 void addImmOperands(MCInst &Inst, unsigned N) const {
889 assert(N == 1 && "Invalid number of operands!");
890 const MCExpr *Expr = getImm();
894 void addMemOperands(MCInst &Inst, unsigned N) const {
895 assert(N == 2 && "Invalid number of operands!");
897 Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
898 ? getMemBase()->getGPR64Reg()
899 : getMemBase()->getGPR32Reg()));
901 const MCExpr *Expr = getMemOff();
905 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
906 assert(N == 2 && "Invalid number of operands!");
908 Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
910 const MCExpr *Expr = getMemOff();
914 void addRegListOperands(MCInst &Inst, unsigned N) const {
915 assert(N == 1 && "Invalid number of operands!");
917 for (auto RegNo : getRegList())
918 Inst.addOperand(MCOperand::createReg(RegNo));
921 void addRegPairOperands(MCInst &Inst, unsigned N) const {
922 assert(N == 2 && "Invalid number of operands!");
923 unsigned RegNo = getRegPair();
924 Inst.addOperand(MCOperand::createReg(RegNo++));
925 Inst.addOperand(MCOperand::createReg(RegNo));
928 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
929 assert(N == 2 && "Invalid number of operands!");
930 for (auto RegNo : getRegList())
931 Inst.addOperand(MCOperand::createReg(RegNo));
934 bool isReg() const override {
935 // As a special case until we sort out the definition of div/divu, pretend
936 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
937 if (isGPRAsmReg() && RegIdx.Index == 0)
940 return Kind == k_PhysRegister;
942 bool isRegIdx() const { return Kind == k_RegisterIndex; }
943 bool isImm() const override { return Kind == k_Immediate; }
944 bool isConstantImm() const {
945 return isImm() && dyn_cast<MCConstantExpr>(getImm());
947 template <unsigned Bits> bool isUImm() const {
948 return isImm() && isConstantImm() && isUInt<Bits>(getConstantImm());
950 bool isToken() const override {
951 // Note: It's not possible to pretend that other operand kinds are tokens.
952 // The matcher emitter checks tokens first.
953 return Kind == k_Token;
955 bool isMem() const override { return Kind == k_Memory; }
956 bool isConstantMemOff() const {
957 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
959 template <unsigned Bits> bool isMemWithSimmOffset() const {
960 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
962 template <unsigned Bits> bool isMemWithSimmOffsetGPR() const {
963 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
964 && getMemBase()->isGPRAsmReg();
966 bool isMemWithGRPMM16Base() const {
967 return isMem() && getMemBase()->isMM16AsmReg();
969 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
970 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
971 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
973 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
974 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
975 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
976 && (getMemBase()->getGPR32Reg() == Mips::SP);
978 bool isRegList16() const {
982 int Size = RegList.List->size();
983 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
984 RegList.List->back() != Mips::RA)
987 int PrevReg = *RegList.List->begin();
988 for (int i = 1; i < Size - 1; i++) {
989 int Reg = (*(RegList.List))[i];
990 if ( Reg != PrevReg + 1)
997 bool isInvNum() const { return Kind == k_Immediate; }
998 bool isLSAImm() const {
999 if (!isConstantImm())
1001 int64_t Val = getConstantImm();
1002 return 1 <= Val && Val <= 4;
1004 bool isRegList() const { return Kind == k_RegList; }
1005 bool isMovePRegPair() const {
1006 if (Kind != k_RegList || RegList.List->size() != 2)
1009 unsigned R0 = RegList.List->front();
1010 unsigned R1 = RegList.List->back();
1012 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1013 (R0 == Mips::A1 && R1 == Mips::A3) ||
1014 (R0 == Mips::A2 && R1 == Mips::A3) ||
1015 (R0 == Mips::A0 && R1 == Mips::S5) ||
1016 (R0 == Mips::A0 && R1 == Mips::S6) ||
1017 (R0 == Mips::A0 && R1 == Mips::A1) ||
1018 (R0 == Mips::A0 && R1 == Mips::A2) ||
1019 (R0 == Mips::A0 && R1 == Mips::A3))
1025 StringRef getToken() const {
1026 assert(Kind == k_Token && "Invalid access!");
1027 return StringRef(Tok.Data, Tok.Length);
1029 bool isRegPair() const { return Kind == k_RegPair; }
1031 unsigned getReg() const override {
1032 // As a special case until we sort out the definition of div/divu, pretend
1033 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
1034 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
1035 RegIdx.Kind & RegKind_GPR)
1036 return getGPR32Reg(); // FIXME: GPR64 too
1038 assert(Kind == k_PhysRegister && "Invalid access!");
1042 const MCExpr *getImm() const {
1043 assert((Kind == k_Immediate) && "Invalid access!");
1047 int64_t getConstantImm() const {
1048 const MCExpr *Val = getImm();
1049 return static_cast<const MCConstantExpr *>(Val)->getValue();
1052 MipsOperand *getMemBase() const {
1053 assert((Kind == k_Memory) && "Invalid access!");
1057 const MCExpr *getMemOff() const {
1058 assert((Kind == k_Memory) && "Invalid access!");
1062 int64_t getConstantMemOff() const {
1063 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1066 const SmallVectorImpl<unsigned> &getRegList() const {
1067 assert((Kind == k_RegList) && "Invalid access!");
1068 return *(RegList.List);
1071 unsigned getRegPair() const {
1072 assert((Kind == k_RegPair) && "Invalid access!");
1073 return RegIdx.Index;
1076 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1077 MipsAsmParser &Parser) {
1078 auto Op = make_unique<MipsOperand>(k_Token, Parser);
1079 Op->Tok.Data = Str.data();
1080 Op->Tok.Length = Str.size();
1086 /// Create a numeric register (e.g. $1). The exact register remains
1087 /// unresolved until an instruction successfully matches
1088 static std::unique_ptr<MipsOperand>
1089 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1090 SMLoc E, MipsAsmParser &Parser) {
1091 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1092 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1095 /// Create a register that is definitely a GPR.
1096 /// This is typically only used for named registers such as $gp.
1097 static std::unique_ptr<MipsOperand>
1098 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1099 MipsAsmParser &Parser) {
1100 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1103 /// Create a register that is definitely a FGR.
1104 /// This is typically only used for named registers such as $f0.
1105 static std::unique_ptr<MipsOperand>
1106 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1107 MipsAsmParser &Parser) {
1108 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1111 /// Create a register that is definitely a HWReg.
1112 /// This is typically only used for named registers such as $hwr_cpunum.
1113 static std::unique_ptr<MipsOperand>
1114 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1115 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1116 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1119 /// Create a register that is definitely an FCC.
1120 /// This is typically only used for named registers such as $fcc0.
1121 static std::unique_ptr<MipsOperand>
1122 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1123 MipsAsmParser &Parser) {
1124 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1127 /// Create a register that is definitely an ACC.
1128 /// This is typically only used for named registers such as $ac0.
1129 static std::unique_ptr<MipsOperand>
1130 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1131 MipsAsmParser &Parser) {
1132 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1135 /// Create a register that is definitely an MSA128.
1136 /// This is typically only used for named registers such as $w0.
1137 static std::unique_ptr<MipsOperand>
1138 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1139 SMLoc E, MipsAsmParser &Parser) {
1140 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1143 /// Create a register that is definitely an MSACtrl.
1144 /// This is typically only used for named registers such as $msaaccess.
1145 static std::unique_ptr<MipsOperand>
1146 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1147 SMLoc E, MipsAsmParser &Parser) {
1148 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1151 static std::unique_ptr<MipsOperand>
1152 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1153 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1160 static std::unique_ptr<MipsOperand>
1161 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1162 SMLoc E, MipsAsmParser &Parser) {
1163 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1164 Op->Mem.Base = Base.release();
1171 static std::unique_ptr<MipsOperand>
1172 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1173 MipsAsmParser &Parser) {
1174 assert (Regs.size() > 0 && "Empty list not allowed");
1176 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1177 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1178 Op->StartLoc = StartLoc;
1179 Op->EndLoc = EndLoc;
1183 static std::unique_ptr<MipsOperand>
1184 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1185 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1186 Op->RegIdx.Index = RegNo;
1192 bool isGPRAsmReg() const {
1193 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1195 bool isMM16AsmReg() const {
1196 if (!(isRegIdx() && RegIdx.Kind))
1198 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1199 || RegIdx.Index == 16 || RegIdx.Index == 17);
1201 bool isMM16AsmRegZero() const {
1202 if (!(isRegIdx() && RegIdx.Kind))
1204 return (RegIdx.Index == 0 ||
1205 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1206 RegIdx.Index == 17);
1208 bool isMM16AsmRegMoveP() const {
1209 if (!(isRegIdx() && RegIdx.Kind))
1211 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1212 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1214 bool isFGRAsmReg() const {
1215 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1216 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1218 bool isHWRegsAsmReg() const {
1219 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1221 bool isCCRAsmReg() const {
1222 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1224 bool isFCCAsmReg() const {
1225 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1227 if (!AsmParser.hasEightFccRegisters())
1228 return RegIdx.Index == 0;
1229 return RegIdx.Index <= 7;
1231 bool isACCAsmReg() const {
1232 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1234 bool isCOP0AsmReg() const {
1235 return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1237 bool isCOP2AsmReg() const {
1238 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1240 bool isCOP3AsmReg() const {
1241 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1243 bool isMSA128AsmReg() const {
1244 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1246 bool isMSACtrlAsmReg() const {
1247 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1250 /// getStartLoc - Get the location of the first token of this operand.
1251 SMLoc getStartLoc() const override { return StartLoc; }
1252 /// getEndLoc - Get the location of the last token of this operand.
1253 SMLoc getEndLoc() const override { return EndLoc; }
1255 virtual ~MipsOperand() {
1263 delete RegList.List;
1264 case k_PhysRegister:
1265 case k_RegisterIndex:
1272 void print(raw_ostream &OS) const override {
1281 Mem.Base->print(OS);
1286 case k_PhysRegister:
1287 OS << "PhysReg<" << PhysReg.Num << ">";
1289 case k_RegisterIndex:
1290 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1297 for (auto Reg : (*RegList.List))
1302 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1306 }; // class MipsOperand
1310 extern const MCInstrDesc MipsInsts[];
1312 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1313 return MipsInsts[Opcode];
1316 static bool hasShortDelaySlot(unsigned Opcode) {
1319 case Mips::JALRS_MM:
1320 case Mips::JALRS16_MM:
1321 case Mips::BGEZALS_MM:
1322 case Mips::BLTZALS_MM:
1329 static const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1330 if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1331 return &SRExpr->getSymbol();
1334 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1335 const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1336 const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1347 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1348 return getSingleMCSymbol(UExpr->getSubExpr());
1353 static unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1354 if (isa<MCSymbolRefExpr>(Expr))
1357 if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1358 return countMCSymbolRefExpr(BExpr->getLHS()) +
1359 countMCSymbolRefExpr(BExpr->getRHS());
1361 if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1362 return countMCSymbolRefExpr(UExpr->getSubExpr());
1367 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1368 SmallVectorImpl<MCInst> &Instructions) {
1369 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1373 if (MCID.isBranch() || MCID.isCall()) {
1374 const unsigned Opcode = Inst.getOpcode();
1384 assert(hasCnMips() && "instruction only valid for octeon cpus");
1391 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1392 Offset = Inst.getOperand(2);
1393 if (!Offset.isImm())
1394 break; // We'll deal with this situation later on when applying fixups.
1395 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1396 return Error(IDLoc, "branch target out of range");
1397 if (OffsetToAlignment(Offset.getImm(),
1398 1LL << (inMicroMipsMode() ? 1 : 2)))
1399 return Error(IDLoc, "branch to misaligned address");
1413 case Mips::BGEZAL_MM:
1414 case Mips::BLTZAL_MM:
1417 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1418 Offset = Inst.getOperand(1);
1419 if (!Offset.isImm())
1420 break; // We'll deal with this situation later on when applying fixups.
1421 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1422 return Error(IDLoc, "branch target out of range");
1423 if (OffsetToAlignment(Offset.getImm(),
1424 1LL << (inMicroMipsMode() ? 1 : 2)))
1425 return Error(IDLoc, "branch to misaligned address");
1427 case Mips::BEQZ16_MM:
1428 case Mips::BNEZ16_MM:
1429 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1430 Offset = Inst.getOperand(1);
1431 if (!Offset.isImm())
1432 break; // We'll deal with this situation later on when applying fixups.
1433 if (!isIntN(8, Offset.getImm()))
1434 return Error(IDLoc, "branch target out of range");
1435 if (OffsetToAlignment(Offset.getImm(), 2LL))
1436 return Error(IDLoc, "branch to misaligned address");
1441 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1442 // We still accept it but it is a normal nop.
1443 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1444 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1445 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1450 const unsigned Opcode = Inst.getOpcode();
1462 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1463 // The offset is handled above
1464 Opnd = Inst.getOperand(1);
1466 return Error(IDLoc, "expected immediate operand kind");
1467 Imm = Opnd.getImm();
1468 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1469 Opcode == Mips::BBIT1 ? 63 : 31))
1470 return Error(IDLoc, "immediate operand value out of range");
1472 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1474 Inst.getOperand(1).setImm(Imm - 32);
1482 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1484 Opnd = Inst.getOperand(3);
1486 return Error(IDLoc, "expected immediate operand kind");
1487 Imm = Opnd.getImm();
1488 if (Imm < 0 || Imm > 31)
1489 return Error(IDLoc, "immediate operand value out of range");
1491 Opnd = Inst.getOperand(2);
1493 return Error(IDLoc, "expected immediate operand kind");
1494 Imm = Opnd.getImm();
1495 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1496 Opcode == Mips::EXTS ? 63 : 31))
1497 return Error(IDLoc, "immediate operand value out of range");
1499 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1500 Inst.getOperand(2).setImm(Imm - 32);
1506 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1507 Opnd = Inst.getOperand(2);
1509 return Error(IDLoc, "expected immediate operand kind");
1510 Imm = Opnd.getImm();
1511 if (!isInt<10>(Imm))
1512 return Error(IDLoc, "immediate operand value out of range");
1517 // This expansion is not in a function called by expandInstruction() because
1518 // the pseudo-instruction doesn't have a distinct opcode.
1519 if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1521 warnIfNoMacro(IDLoc);
1523 const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1525 // We can do this expansion if there's only 1 symbol in the argument
1527 if (countMCSymbolRefExpr(JalExpr) > 1)
1528 return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1530 // FIXME: This is checking the expression can be handled by the later stages
1531 // of the assembler. We ought to leave it to those later stages but
1532 // we can't do that until we stop evaluateRelocExpr() rewriting the
1533 // expressions into non-equivalent forms.
1534 const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1536 // FIXME: Add support for label+offset operands (currently causes an error).
1537 // FIXME: Add support for forward-declared local symbols.
1538 // FIXME: Add expansion for when the LargeGOT option is enabled.
1539 if (JalSym->isInSection() || JalSym->isTemporary()) {
1541 // If it's a local symbol and the O32 ABI is being used, we expand to:
1543 // R_(MICRO)MIPS_GOT16 label
1544 // addiu $25, $25, 0
1545 // R_(MICRO)MIPS_LO16 label
1547 const MCExpr *Got16RelocExpr = evaluateRelocExpr(JalExpr, "got");
1548 const MCExpr *Lo16RelocExpr = evaluateRelocExpr(JalExpr, "lo");
1551 LwInst.setOpcode(Mips::LW);
1552 LwInst.addOperand(MCOperand::createReg(Mips::T9));
1553 LwInst.addOperand(MCOperand::createReg(Mips::GP));
1554 LwInst.addOperand(MCOperand::createExpr(Got16RelocExpr));
1555 Instructions.push_back(LwInst);
1558 AddiuInst.setOpcode(Mips::ADDiu);
1559 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1560 AddiuInst.addOperand(MCOperand::createReg(Mips::T9));
1561 AddiuInst.addOperand(MCOperand::createExpr(Lo16RelocExpr));
1562 Instructions.push_back(AddiuInst);
1563 } else if (isABI_N32() || isABI_N64()) {
1564 // If it's a local symbol and the N32/N64 ABIs are being used,
1566 // lw/ld $25, 0($gp)
1567 // R_(MICRO)MIPS_GOT_DISP label
1569 const MCExpr *GotDispRelocExpr = evaluateRelocExpr(JalExpr, "got_disp");
1572 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1573 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1574 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1575 LoadInst.addOperand(MCOperand::createExpr(GotDispRelocExpr));
1576 Instructions.push_back(LoadInst);
1579 // If it's an external/weak symbol, we expand to:
1580 // lw/ld $25, 0($gp)
1581 // R_(MICRO)MIPS_CALL16 label
1583 const MCExpr *Call16RelocExpr = evaluateRelocExpr(JalExpr, "call16");
1586 LoadInst.setOpcode(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW);
1587 LoadInst.addOperand(MCOperand::createReg(Mips::T9));
1588 LoadInst.addOperand(MCOperand::createReg(Mips::GP));
1589 LoadInst.addOperand(MCOperand::createExpr(Call16RelocExpr));
1590 Instructions.push_back(LoadInst);
1594 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1595 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1596 JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1598 // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1599 // This relocation is supposed to be an optimization hint for the linker
1600 // and is not necessary for correctness.
1605 if (MCID.mayLoad() || MCID.mayStore()) {
1606 // Check the offset of memory operand, if it is a symbol
1607 // reference or immediate we may have to expand instructions.
1608 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1609 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1610 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1611 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1612 MCOperand &Op = Inst.getOperand(i);
1614 int MemOffset = Op.getImm();
1615 if (MemOffset < -32768 || MemOffset > 32767) {
1616 // Offset can't exceed 16bit value.
1617 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1620 } else if (Op.isExpr()) {
1621 const MCExpr *Expr = Op.getExpr();
1622 if (Expr->getKind() == MCExpr::SymbolRef) {
1623 const MCSymbolRefExpr *SR =
1624 static_cast<const MCSymbolRefExpr *>(Expr);
1625 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1627 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1630 } else if (!isEvaluated(Expr)) {
1631 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1639 if (inMicroMipsMode()) {
1640 if (MCID.mayLoad()) {
1641 // Try to create 16-bit GP relative load instruction.
1642 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1643 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1644 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1645 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1646 MCOperand &Op = Inst.getOperand(i);
1648 int MemOffset = Op.getImm();
1649 MCOperand &DstReg = Inst.getOperand(0);
1650 MCOperand &BaseReg = Inst.getOperand(1);
1651 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1652 getContext().getRegisterInfo()->getRegClass(
1653 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1654 BaseReg.getReg() == Mips::GP) {
1656 TmpInst.setLoc(IDLoc);
1657 TmpInst.setOpcode(Mips::LWGP_MM);
1658 TmpInst.addOperand(MCOperand::createReg(DstReg.getReg()));
1659 TmpInst.addOperand(MCOperand::createReg(Mips::GP));
1660 TmpInst.addOperand(MCOperand::createImm(MemOffset));
1661 Instructions.push_back(TmpInst);
1669 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1674 switch (Inst.getOpcode()) {
1677 case Mips::ADDIUS5_MM:
1678 Opnd = Inst.getOperand(2);
1680 return Error(IDLoc, "expected immediate operand kind");
1681 Imm = Opnd.getImm();
1682 if (Imm < -8 || Imm > 7)
1683 return Error(IDLoc, "immediate operand value out of range");
1685 case Mips::ADDIUSP_MM:
1686 Opnd = Inst.getOperand(0);
1688 return Error(IDLoc, "expected immediate operand kind");
1689 Imm = Opnd.getImm();
1690 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1692 return Error(IDLoc, "immediate operand value out of range");
1694 case Mips::SLL16_MM:
1695 case Mips::SRL16_MM:
1696 Opnd = Inst.getOperand(2);
1698 return Error(IDLoc, "expected immediate operand kind");
1699 Imm = Opnd.getImm();
1700 if (Imm < 1 || Imm > 8)
1701 return Error(IDLoc, "immediate operand value out of range");
1704 Opnd = Inst.getOperand(1);
1706 return Error(IDLoc, "expected immediate operand kind");
1707 Imm = Opnd.getImm();
1708 if (Imm < -1 || Imm > 126)
1709 return Error(IDLoc, "immediate operand value out of range");
1711 case Mips::ADDIUR2_MM:
1712 Opnd = Inst.getOperand(2);
1714 return Error(IDLoc, "expected immediate operand kind");
1715 Imm = Opnd.getImm();
1716 if (!(Imm == 1 || Imm == -1 ||
1717 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1718 return Error(IDLoc, "immediate operand value out of range");
1720 case Mips::ADDIUR1SP_MM:
1721 Opnd = Inst.getOperand(1);
1723 return Error(IDLoc, "expected immediate operand kind");
1724 Imm = Opnd.getImm();
1725 if (OffsetToAlignment(Imm, 4LL))
1726 return Error(IDLoc, "misaligned immediate operand value");
1727 if (Imm < 0 || Imm > 255)
1728 return Error(IDLoc, "immediate operand value out of range");
1730 case Mips::ANDI16_MM:
1731 Opnd = Inst.getOperand(2);
1733 return Error(IDLoc, "expected immediate operand kind");
1734 Imm = Opnd.getImm();
1735 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1736 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1737 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1738 return Error(IDLoc, "immediate operand value out of range");
1740 case Mips::LBU16_MM:
1741 Opnd = Inst.getOperand(2);
1743 return Error(IDLoc, "expected immediate operand kind");
1744 Imm = Opnd.getImm();
1745 if (Imm < -1 || Imm > 14)
1746 return Error(IDLoc, "immediate operand value out of range");
1749 Opnd = Inst.getOperand(2);
1751 return Error(IDLoc, "expected immediate operand kind");
1752 Imm = Opnd.getImm();
1753 if (Imm < 0 || Imm > 15)
1754 return Error(IDLoc, "immediate operand value out of range");
1756 case Mips::LHU16_MM:
1758 Opnd = Inst.getOperand(2);
1760 return Error(IDLoc, "expected immediate operand kind");
1761 Imm = Opnd.getImm();
1762 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1763 return Error(IDLoc, "immediate operand value out of range");
1767 Opnd = Inst.getOperand(2);
1769 return Error(IDLoc, "expected immediate operand kind");
1770 Imm = Opnd.getImm();
1771 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1772 return Error(IDLoc, "immediate operand value out of range");
1776 Opnd = Inst.getOperand(2);
1778 return Error(IDLoc, "expected immediate operand kind");
1779 Imm = Opnd.getImm();
1780 if (!isUInt<5>(Imm))
1781 return Error(IDLoc, "immediate operand value out of range");
1783 case Mips::ADDIUPC_MM:
1784 MCOperand Opnd = Inst.getOperand(1);
1786 return Error(IDLoc, "expected immediate operand kind");
1787 int Imm = Opnd.getImm();
1788 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1789 return Error(IDLoc, "immediate operand value out of range");
1794 if (needsExpansion(Inst)) {
1795 if (expandInstruction(Inst, IDLoc, Instructions))
1798 Instructions.push_back(Inst);
1800 // If this instruction has a delay slot and .set reorder is active,
1801 // emit a NOP after it.
1802 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1803 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1808 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1810 switch (Inst.getOpcode()) {
1811 case Mips::LoadImm32:
1812 case Mips::LoadImm64:
1813 case Mips::LoadAddrImm32:
1814 case Mips::LoadAddrImm64:
1815 case Mips::LoadAddrReg32:
1816 case Mips::LoadAddrReg64:
1817 case Mips::B_MM_Pseudo:
1820 case Mips::JalOneReg:
1821 case Mips::JalTwoReg:
1832 case Mips::SDivMacro:
1833 case Mips::UDivMacro:
1834 case Mips::DSDivMacro:
1835 case Mips::DUDivMacro:
1844 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1845 SmallVectorImpl<MCInst> &Instructions) {
1846 switch (Inst.getOpcode()) {
1847 default: llvm_unreachable("unimplemented expansion");
1848 case Mips::LoadImm32:
1849 return expandLoadImm(Inst, true, IDLoc, Instructions);
1850 case Mips::LoadImm64:
1851 return expandLoadImm(Inst, false, IDLoc, Instructions);
1852 case Mips::LoadAddrImm32:
1853 case Mips::LoadAddrImm64:
1854 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1855 assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1856 "expected immediate operand kind");
1858 return expandLoadAddress(
1859 Inst.getOperand(0).getReg(), Mips::NoRegister, Inst.getOperand(1),
1860 Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc, Instructions);
1861 case Mips::LoadAddrReg32:
1862 case Mips::LoadAddrReg64:
1863 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1864 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1865 assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1866 "expected immediate operand kind");
1868 return expandLoadAddress(
1869 Inst.getOperand(0).getReg(), Inst.getOperand(1).getReg(), Inst.getOperand(2),
1870 Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc, Instructions);
1871 case Mips::B_MM_Pseudo:
1872 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1875 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1876 case Mips::JalOneReg:
1877 case Mips::JalTwoReg:
1878 return expandJalWithRegs(Inst, IDLoc, Instructions);
1881 return expandBranchImm(Inst, IDLoc, Instructions);
1890 return expandCondBranches(Inst, IDLoc, Instructions);
1891 case Mips::SDivMacro:
1892 return expandDiv(Inst, IDLoc, Instructions, false, true);
1893 case Mips::DSDivMacro:
1894 return expandDiv(Inst, IDLoc, Instructions, true, true);
1895 case Mips::UDivMacro:
1896 return expandDiv(Inst, IDLoc, Instructions, false, false);
1897 case Mips::DUDivMacro:
1898 return expandDiv(Inst, IDLoc, Instructions, true, false);
1900 return expandUlhu(Inst, IDLoc, Instructions);
1902 return expandUlw(Inst, IDLoc, Instructions);
1907 void emitRX(unsigned Opcode, unsigned Reg0, MCOperand Op1, SMLoc IDLoc,
1908 SmallVectorImpl<MCInst> &Instructions) {
1910 tmpInst.setOpcode(Opcode);
1911 tmpInst.addOperand(MCOperand::createReg(Reg0));
1912 tmpInst.addOperand(Op1);
1913 tmpInst.setLoc(IDLoc);
1914 Instructions.push_back(tmpInst);
1917 void emitRI(unsigned Opcode, unsigned Reg0, int32_t Imm, SMLoc IDLoc,
1918 SmallVectorImpl<MCInst> &Instructions) {
1919 emitRX(Opcode, Reg0, MCOperand::createImm(Imm), IDLoc, Instructions);
1922 void emitRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, SMLoc IDLoc,
1923 SmallVectorImpl<MCInst> &Instructions) {
1924 emitRX(Opcode, Reg0, MCOperand::createReg(Reg1), IDLoc, Instructions);
1927 void emitII(unsigned Opcode, int16_t Imm1, int16_t Imm2, SMLoc IDLoc,
1928 SmallVectorImpl<MCInst> &Instructions) {
1930 tmpInst.setOpcode(Opcode);
1931 tmpInst.addOperand(MCOperand::createImm(Imm1));
1932 tmpInst.addOperand(MCOperand::createImm(Imm2));
1933 tmpInst.setLoc(IDLoc);
1934 Instructions.push_back(tmpInst);
1937 void emitR(unsigned Opcode, unsigned Reg0, SMLoc IDLoc,
1938 SmallVectorImpl<MCInst> &Instructions) {
1940 tmpInst.setOpcode(Opcode);
1941 tmpInst.addOperand(MCOperand::createReg(Reg0));
1942 tmpInst.setLoc(IDLoc);
1943 Instructions.push_back(tmpInst);
1946 void emitRRX(unsigned Opcode, unsigned Reg0, unsigned Reg1, MCOperand Op2,
1947 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1949 tmpInst.setOpcode(Opcode);
1950 tmpInst.addOperand(MCOperand::createReg(Reg0));
1951 tmpInst.addOperand(MCOperand::createReg(Reg1));
1952 tmpInst.addOperand(Op2);
1953 tmpInst.setLoc(IDLoc);
1954 Instructions.push_back(tmpInst);
1957 void emitRRR(unsigned Opcode, unsigned Reg0, unsigned Reg1, unsigned Reg2,
1958 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1959 emitRRX(Opcode, Reg0, Reg1, MCOperand::createReg(Reg2), IDLoc,
1963 void emitRRI(unsigned Opcode, unsigned Reg0, unsigned Reg1, int16_t Imm,
1964 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1965 emitRRX(Opcode, Reg0, Reg1, MCOperand::createImm(Imm), IDLoc,
1969 void emitAppropriateDSLL(unsigned DstReg, unsigned SrcReg, int16_t ShiftAmount,
1970 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1971 if (ShiftAmount >= 32) {
1972 emitRRI(Mips::DSLL32, DstReg, SrcReg, ShiftAmount - 32, IDLoc,
1977 emitRRI(Mips::DSLL, DstReg, SrcReg, ShiftAmount, IDLoc, Instructions);
1979 } // end anonymous namespace.
1981 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1982 SmallVectorImpl<MCInst> &Instructions) {
1983 // Create a JALR instruction which is going to replace the pseudo-JAL.
1985 JalrInst.setLoc(IDLoc);
1986 const MCOperand FirstRegOp = Inst.getOperand(0);
1987 const unsigned Opcode = Inst.getOpcode();
1989 if (Opcode == Mips::JalOneReg) {
1990 // jal $rs => jalr $rs
1991 if (inMicroMipsMode()) {
1992 JalrInst.setOpcode(Mips::JALR16_MM);
1993 JalrInst.addOperand(FirstRegOp);
1995 JalrInst.setOpcode(Mips::JALR);
1996 JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1997 JalrInst.addOperand(FirstRegOp);
1999 } else if (Opcode == Mips::JalTwoReg) {
2000 // jal $rd, $rs => jalr $rd, $rs
2001 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2002 JalrInst.addOperand(FirstRegOp);
2003 const MCOperand SecondRegOp = Inst.getOperand(1);
2004 JalrInst.addOperand(SecondRegOp);
2006 Instructions.push_back(JalrInst);
2008 // If .set reorder is active, emit a NOP after it.
2009 if (AssemblerOptions.back()->isReorder()) {
2010 // This is a 32-bit NOP because these 2 pseudo-instructions
2011 // do not have a short delay slot.
2013 NopInst.setOpcode(Mips::SLL);
2014 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2015 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
2016 NopInst.addOperand(MCOperand::createImm(0));
2017 Instructions.push_back(NopInst);
2023 /// Can the value be represented by a unsigned N-bit value and a shift left?
2024 template<unsigned N>
2025 bool isShiftedUIntAtAnyPosition(uint64_t x) {
2026 unsigned BitNum = findFirstSet(x);
2028 return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2031 /// Load (or add) an immediate into a register.
2033 /// @param ImmValue The immediate to load.
2034 /// @param DstReg The register that will hold the immediate.
2035 /// @param SrcReg A register to add to the immediate or Mips::NoRegister
2036 /// for a simple initialization.
2037 /// @param Is32BitImm Is ImmValue 32-bit or 64-bit?
2038 /// @param IsAddress True if the immediate represents an address. False if it
2040 /// @param IDLoc Location of the immediate in the source file.
2041 /// @param Instructions The instructions emitted by this expansion.
2042 bool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2043 unsigned SrcReg, bool Is32BitImm,
2044 bool IsAddress, SMLoc IDLoc,
2045 SmallVectorImpl<MCInst> &Instructions) {
2046 if (!Is32BitImm && !isGP64bit()) {
2047 Error(IDLoc, "instruction requires a 64-bit architecture");
2052 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2053 // Sign extend up to 64-bit so that the predicates match the hardware
2054 // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2056 ImmValue = SignExtend64<32>(ImmValue);
2058 Error(IDLoc, "instruction requires a 32-bit immediate");
2063 unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2064 unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2066 bool UseSrcReg = false;
2067 if (SrcReg != Mips::NoRegister)
2070 unsigned TmpReg = DstReg;
2071 if (UseSrcReg && (DstReg == SrcReg)) {
2072 // At this point we need AT to perform the expansions and we exit if it is
2074 unsigned ATReg = getATReg(IDLoc);
2080 if (isInt<16>(ImmValue)) {
2084 // This doesn't quite follow the usual ABI expectations for N32 but matches
2085 // traditional assembler behaviour. N32 would normally use addiu for both
2086 // integers and addresses.
2087 if (IsAddress && !Is32BitImm) {
2088 emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2092 emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, Instructions);
2096 if (isUInt<16>(ImmValue)) {
2097 unsigned TmpReg = DstReg;
2098 if (SrcReg == DstReg) {
2099 TmpReg = getATReg(IDLoc);
2104 emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, Instructions);
2106 emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2110 if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2111 warnIfNoMacro(IDLoc);
2113 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
2114 uint16_t Bits15To0 = ImmValue & 0xffff;
2116 if (!Is32BitImm && !isInt<32>(ImmValue)) {
2117 // Traditional behaviour seems to special case this particular value. It's
2118 // not clear why other masks are handled differently.
2119 if (ImmValue == 0xffffffff) {
2120 emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, Instructions);
2121 emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, Instructions);
2123 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2127 // Expand to an ORi instead of a LUi to avoid sign-extending into the
2129 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, Instructions);
2130 emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, Instructions);
2132 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2134 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2138 emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, Instructions);
2140 emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, Instructions);
2142 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2146 if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
2148 Error(IDLoc, "instruction requires a 32-bit immediate");
2152 // Traditionally, these immediates are shifted as little as possible and as
2153 // such we align the most significant bit to bit 15 of our temporary.
2154 unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2155 unsigned LastSet = findLastSet((uint64_t)ImmValue);
2156 unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2157 uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2158 emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, Instructions);
2159 emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, Instructions);
2162 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2167 warnIfNoMacro(IDLoc);
2169 // The remaining case is packed with a sequence of dsll and ori with zeros
2170 // being omitted and any neighbouring dsll's being coalesced.
2171 // The highest 32-bit's are equivalent to a 32-bit immediate load.
2173 // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2174 if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2175 IDLoc, Instructions))
2178 // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2179 // skip it and defer the shift to the next chunk.
2180 unsigned ShiftCarriedForwards = 16;
2181 for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2182 uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2184 if (ImmChunk != 0) {
2185 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2187 emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, Instructions);
2188 ShiftCarriedForwards = 0;
2191 ShiftCarriedForwards += 16;
2193 ShiftCarriedForwards -= 16;
2195 // Finish any remaining shifts left by trailing zeros.
2196 if (ShiftCarriedForwards)
2197 emitAppropriateDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc,
2201 emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2206 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2207 SmallVectorImpl<MCInst> &Instructions) {
2208 const MCOperand &ImmOp = Inst.getOperand(1);
2209 assert(ImmOp.isImm() && "expected immediate operand kind");
2210 const MCOperand &DstRegOp = Inst.getOperand(0);
2211 assert(DstRegOp.isReg() && "expected register operand kind");
2213 if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2214 Is32BitImm, false, IDLoc, Instructions))
2220 bool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2221 const MCOperand &Offset,
2222 bool Is32BitAddress, SMLoc IDLoc,
2223 SmallVectorImpl<MCInst> &Instructions) {
2224 // la can't produce a usable address when addresses are 64-bit.
2225 if (Is32BitAddress && ABI.ArePtrs64bit()) {
2226 // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2227 // We currently can't do this because we depend on the equality
2228 // operator and N64 can end up with a GPR32/GPR64 mismatch.
2229 Error(IDLoc, "la used to load 64-bit address");
2230 // Continue as if we had 'dla' instead.
2231 Is32BitAddress = false;
2234 // dla requires 64-bit addresses.
2235 if (!Is32BitAddress && !ABI.ArePtrs64bit()) {
2236 Error(IDLoc, "instruction requires a 64-bit architecture");
2240 if (!Offset.isImm())
2241 return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2242 Is32BitAddress, IDLoc, Instructions);
2244 return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2245 IDLoc, Instructions);
2248 bool MipsAsmParser::loadAndAddSymbolAddress(
2249 const MCExpr *SymExpr, unsigned DstReg, unsigned SrcReg, bool Is32BitSym,
2250 SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2251 warnIfNoMacro(IDLoc);
2253 // FIXME: The way we're handling symbols right now prevents simple expressions
2254 // like foo+8. We'll be able to fix this once our unary operators (%hi
2255 // and similar) are treated as operators rather than as fixup types.
2256 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymExpr);
2257 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::create(
2258 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
2259 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::create(
2260 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
2262 bool UseSrcReg = SrcReg != Mips::NoRegister;
2264 // This is the 64-bit symbol address expansion.
2265 if (ABI.ArePtrs64bit() && isGP64bit()) {
2266 // We always need AT for the 64-bit expansion.
2267 // If it is not available we exit.
2268 unsigned ATReg = getATReg(IDLoc);
2272 const MCSymbolRefExpr *HighestExpr = MCSymbolRefExpr::create(
2273 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
2274 const MCSymbolRefExpr *HigherExpr = MCSymbolRefExpr::create(
2275 &Symbol->getSymbol(), MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
2277 if (UseSrcReg && (DstReg == SrcReg)) {
2278 // If $rs is the same as $rd:
2279 // (d)la $rd, sym($rd) => lui $at, %highest(sym)
2280 // daddiu $at, $at, %higher(sym)
2281 // dsll $at, $at, 16
2282 // daddiu $at, $at, %hi(sym)
2283 // dsll $at, $at, 16
2284 // daddiu $at, $at, %lo(sym)
2285 // daddu $rd, $at, $rd
2286 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2288 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HigherExpr),
2289 IDLoc, Instructions);
2290 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2291 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2293 emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, Instructions);
2294 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2296 emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, Instructions);
2301 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2302 // (d)la $rd, sym/sym($rs) => lui $rd, %highest(sym)
2303 // lui $at, %hi(sym)
2304 // daddiu $rd, $rd, %higher(sym)
2305 // daddiu $at, $at, %lo(sym)
2306 // dsll32 $rd, $rd, 0
2307 // daddu $rd, $rd, $at
2308 // (daddu $rd, $rd, $rs)
2309 emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2311 emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc,
2313 emitRRX(Mips::DADDiu, DstReg, DstReg, MCOperand::createExpr(HigherExpr),
2314 IDLoc, Instructions);
2315 emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr), IDLoc,
2317 emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, Instructions);
2318 emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, Instructions);
2320 emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, Instructions);
2325 // And now, the 32-bit symbol address expansion:
2326 // If $rs is the same as $rd:
2327 // (d)la $rd, sym($rd) => lui $at, %hi(sym)
2328 // ori $at, $at, %lo(sym)
2329 // addu $rd, $at, $rd
2330 // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2331 // (d)la $rd, sym/sym($rs) => lui $rd, %hi(sym)
2332 // ori $rd, $rd, %lo(sym)
2333 // (addu $rd, $rd, $rs)
2334 unsigned TmpReg = DstReg;
2335 if (UseSrcReg && (DstReg == SrcReg)) {
2336 // If $rs is the same as $rd, we need to use AT.
2337 // If it is not available we exit.
2338 unsigned ATReg = getATReg(IDLoc);
2344 emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, Instructions);
2345 emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr), IDLoc,
2349 emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, Instructions);
2351 assert(DstReg == TmpReg);
2356 bool MipsAsmParser::expandUncondBranchMMPseudo(
2357 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
2358 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2359 "unexpected number of operands");
2361 MCOperand Offset = Inst.getOperand(0);
2362 if (Offset.isExpr()) {
2364 Inst.setOpcode(Mips::BEQ_MM);
2365 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2366 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2367 Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2369 assert(Offset.isImm() && "expected immediate operand kind");
2370 if (isIntN(11, Offset.getImm())) {
2371 // If offset fits into 11 bits then this instruction becomes microMIPS
2372 // 16-bit unconditional branch instruction.
2373 Inst.setOpcode(Mips::B16_MM);
2375 if (!isIntN(17, Offset.getImm()))
2376 Error(IDLoc, "branch target out of range");
2377 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2378 Error(IDLoc, "branch to misaligned address");
2380 Inst.setOpcode(Mips::BEQ_MM);
2381 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2382 Inst.addOperand(MCOperand::createReg(Mips::ZERO));
2383 Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2386 Instructions.push_back(Inst);
2388 // If .set reorder is active, emit a NOP after the branch instruction.
2389 if (AssemblerOptions.back()->isReorder())
2390 createNop(true, IDLoc, Instructions);
2395 bool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc,
2396 SmallVectorImpl<MCInst> &Instructions) {
2397 const MCOperand &DstRegOp = Inst.getOperand(0);
2398 assert(DstRegOp.isReg() && "expected register operand kind");
2400 const MCOperand &ImmOp = Inst.getOperand(1);
2401 assert(ImmOp.isImm() && "expected immediate operand kind");
2403 const MCOperand &MemOffsetOp = Inst.getOperand(2);
2404 assert(MemOffsetOp.isImm() && "expected immediate operand kind");
2406 unsigned OpCode = 0;
2407 switch(Inst.getOpcode()) {
2415 llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2419 int64_t ImmValue = ImmOp.getImm();
2420 if (ImmValue == 0) {
2422 BranchInst.setOpcode(OpCode);
2423 BranchInst.addOperand(DstRegOp);
2424 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2425 BranchInst.addOperand(MemOffsetOp);
2426 Instructions.push_back(BranchInst);
2428 warnIfNoMacro(IDLoc);
2430 unsigned ATReg = getATReg(IDLoc);
2434 if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2435 IDLoc, Instructions))
2439 BranchInst.setOpcode(OpCode);
2440 BranchInst.addOperand(DstRegOp);
2441 BranchInst.addOperand(MCOperand::createReg(ATReg));
2442 BranchInst.addOperand(MemOffsetOp);
2443 Instructions.push_back(BranchInst);
2448 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2449 SmallVectorImpl<MCInst> &Instructions,
2450 bool isLoad, bool isImmOpnd) {
2452 unsigned ImmOffset, HiOffset, LoOffset;
2453 const MCExpr *ExprOffset;
2455 // 1st operand is either the source or destination register.
2456 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2457 unsigned RegOpNum = Inst.getOperand(0).getReg();
2458 // 2nd operand is the base register.
2459 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2460 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2461 // 3rd operand is either an immediate or expression.
2463 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2464 ImmOffset = Inst.getOperand(2).getImm();
2465 LoOffset = ImmOffset & 0x0000ffff;
2466 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2467 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2468 if (LoOffset & 0x8000)
2471 ExprOffset = Inst.getOperand(2).getExpr();
2472 // All instructions will have the same location.
2473 TempInst.setLoc(IDLoc);
2474 // These are some of the types of expansions we perform here:
2475 // 1) lw $8, sym => lui $8, %hi(sym)
2476 // lw $8, %lo(sym)($8)
2477 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2479 // lw $8, %lo(offset)($9)
2480 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2482 // lw $8, %lo(offset)($at)
2483 // 4) sw $8, sym => lui $at, %hi(sym)
2484 // sw $8, %lo(sym)($at)
2485 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2487 // sw $8, %lo(offset)($at)
2488 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2489 // ldc1 $f0, %lo(sym)($at)
2491 // For load instructions we can use the destination register as a temporary
2492 // if base and dst are different (examples 1 and 2) and if the base register
2493 // is general purpose otherwise we must use $at (example 6) and error if it's
2494 // not available. For stores we must use $at (examples 4 and 5) because we
2495 // must not clobber the source register setting up the offset.
2496 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2497 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2498 unsigned RegClassIDOp0 =
2499 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2500 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2501 (RegClassIDOp0 == Mips::GPR64RegClassID);
2502 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2503 TmpRegNum = RegOpNum;
2505 // At this point we need AT to perform the expansions and we exit if it is
2507 TmpRegNum = getATReg(IDLoc);
2512 TempInst.setOpcode(Mips::LUi);
2513 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2515 TempInst.addOperand(MCOperand::createImm(HiOffset));
2517 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2518 TempInst.addOperand(MCOperand::createExpr(HiExpr));
2520 // Add the instruction to the list.
2521 Instructions.push_back(TempInst);
2522 // Prepare TempInst for next instruction.
2524 // Add temp register to base.
2525 if (BaseRegNum != Mips::ZERO) {
2526 TempInst.setOpcode(Mips::ADDu);
2527 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2528 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2529 TempInst.addOperand(MCOperand::createReg(BaseRegNum));
2530 Instructions.push_back(TempInst);
2533 // And finally, create original instruction with low part
2534 // of offset and new base.
2535 TempInst.setOpcode(Inst.getOpcode());
2536 TempInst.addOperand(MCOperand::createReg(RegOpNum));
2537 TempInst.addOperand(MCOperand::createReg(TmpRegNum));
2539 TempInst.addOperand(MCOperand::createImm(LoOffset));
2541 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2542 TempInst.addOperand(MCOperand::createExpr(LoExpr));
2544 Instructions.push_back(TempInst);
2549 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2550 SmallVectorImpl<MCInst> &Instructions) {
2551 unsigned OpNum = Inst.getNumOperands();
2552 unsigned Opcode = Inst.getOpcode();
2553 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2555 assert (Inst.getOperand(OpNum - 1).isImm() &&
2556 Inst.getOperand(OpNum - 2).isReg() &&
2557 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2559 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2560 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2561 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2562 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2563 // It can be implemented as SWM16 or LWM16 instruction.
2564 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2566 Inst.setOpcode(NewOpcode);
2567 Instructions.push_back(Inst);
2571 bool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2572 SmallVectorImpl<MCInst> &Instructions) {
2573 unsigned PseudoOpcode = Inst.getOpcode();
2574 unsigned SrcReg = Inst.getOperand(0).getReg();
2575 unsigned TrgReg = Inst.getOperand(1).getReg();
2576 const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2578 unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2579 bool ReverseOrderSLT, IsUnsigned, AcceptsEquality;
2581 switch (PseudoOpcode) {
2584 AcceptsEquality = false;
2585 ReverseOrderSLT = false;
2586 IsUnsigned = (PseudoOpcode == Mips::BLTU);
2587 ZeroSrcOpcode = Mips::BGTZ;
2588 ZeroTrgOpcode = Mips::BLTZ;
2592 AcceptsEquality = true;
2593 ReverseOrderSLT = true;
2594 IsUnsigned = (PseudoOpcode == Mips::BLEU);
2595 ZeroSrcOpcode = Mips::BGEZ;
2596 ZeroTrgOpcode = Mips::BLEZ;
2600 AcceptsEquality = true;
2601 ReverseOrderSLT = false;
2602 IsUnsigned = (PseudoOpcode == Mips::BGEU);
2603 ZeroSrcOpcode = Mips::BLEZ;
2604 ZeroTrgOpcode = Mips::BGEZ;
2608 AcceptsEquality = false;
2609 ReverseOrderSLT = true;
2610 IsUnsigned = (PseudoOpcode == Mips::BGTU);
2611 ZeroSrcOpcode = Mips::BLTZ;
2612 ZeroTrgOpcode = Mips::BGTZ;
2615 llvm_unreachable("unknown opcode for branch pseudo-instruction");
2619 bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2620 bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2621 if (IsSrcRegZero && IsTrgRegZero) {
2622 // FIXME: All of these Opcode-specific if's are needed for compatibility
2623 // with GAS' behaviour. However, they may not generate the most efficient
2624 // code in some circumstances.
2625 if (PseudoOpcode == Mips::BLT) {
2626 BranchInst.setOpcode(Mips::BLTZ);
2627 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2628 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2629 Instructions.push_back(BranchInst);
2632 if (PseudoOpcode == Mips::BLE) {
2633 BranchInst.setOpcode(Mips::BLEZ);
2634 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2635 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2636 Instructions.push_back(BranchInst);
2637 Warning(IDLoc, "branch is always taken");
2640 if (PseudoOpcode == Mips::BGE) {
2641 BranchInst.setOpcode(Mips::BGEZ);
2642 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2643 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2644 Instructions.push_back(BranchInst);
2645 Warning(IDLoc, "branch is always taken");
2648 if (PseudoOpcode == Mips::BGT) {
2649 BranchInst.setOpcode(Mips::BGTZ);
2650 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2651 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2652 Instructions.push_back(BranchInst);
2655 if (PseudoOpcode == Mips::BGTU) {
2656 BranchInst.setOpcode(Mips::BNE);
2657 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2658 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2659 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2660 Instructions.push_back(BranchInst);
2663 if (AcceptsEquality) {
2664 // If both registers are $0 and the pseudo-branch accepts equality, it
2665 // will always be taken, so we emit an unconditional branch.
2666 BranchInst.setOpcode(Mips::BEQ);
2667 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2668 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2669 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2670 Instructions.push_back(BranchInst);
2671 Warning(IDLoc, "branch is always taken");
2674 // If both registers are $0 and the pseudo-branch does not accept
2675 // equality, it will never be taken, so we don't have to emit anything.
2678 if (IsSrcRegZero || IsTrgRegZero) {
2679 if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2680 (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2681 // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2682 // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2683 // the pseudo-branch will never be taken, so we don't emit anything.
2684 // This only applies to unsigned pseudo-branches.
2687 if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2688 (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2689 // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2690 // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2691 // the pseudo-branch will always be taken, so we emit an unconditional
2693 // This only applies to unsigned pseudo-branches.
2694 BranchInst.setOpcode(Mips::BEQ);
2695 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2696 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2697 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2698 Instructions.push_back(BranchInst);
2699 Warning(IDLoc, "branch is always taken");
2703 // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2704 // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2705 // the pseudo-branch will be taken only when the non-zero register is
2706 // different from 0, so we emit a BNEZ.
2708 // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2709 // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2710 // the pseudo-branch will be taken only when the non-zero register is
2711 // equal to 0, so we emit a BEQZ.
2713 // Because only BLEU and BGEU branch on equality, we can use the
2714 // AcceptsEquality variable to decide when to emit the BEQZ.
2715 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2716 BranchInst.addOperand(
2717 MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2718 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2719 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2720 Instructions.push_back(BranchInst);
2723 // If we have a signed pseudo-branch and one of the registers is $0,
2724 // we can use an appropriate compare-to-zero branch. We select which one
2725 // to use in the switch statement above.
2726 BranchInst.setOpcode(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode);
2727 BranchInst.addOperand(MCOperand::createReg(IsSrcRegZero ? TrgReg : SrcReg));
2728 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2729 Instructions.push_back(BranchInst);
2733 // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2734 // expansions. If it is not available, we return.
2735 unsigned ATRegNum = getATReg(IDLoc);
2739 warnIfNoMacro(IDLoc);
2741 // SLT fits well with 2 of our 4 pseudo-branches:
2742 // BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2743 // BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2744 // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2745 // This is accomplished by using a BNEZ with the result of the SLT.
2747 // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2748 // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2749 // Because only BGE and BLE branch on equality, we can use the
2750 // AcceptsEquality variable to decide when to emit the BEQZ.
2751 // Note that the order of the SLT arguments doesn't change between
2754 // The same applies to the unsigned variants, except that SLTu is used
2757 SetInst.setOpcode(IsUnsigned ? Mips::SLTu : Mips::SLT);
2758 SetInst.addOperand(MCOperand::createReg(ATRegNum));
2759 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? TrgReg : SrcReg));
2760 SetInst.addOperand(MCOperand::createReg(ReverseOrderSLT ? SrcReg : TrgReg));
2761 Instructions.push_back(SetInst);
2763 BranchInst.setOpcode(AcceptsEquality ? Mips::BEQ : Mips::BNE);
2764 BranchInst.addOperand(MCOperand::createReg(ATRegNum));
2765 BranchInst.addOperand(MCOperand::createReg(Mips::ZERO));
2766 BranchInst.addOperand(MCOperand::createExpr(OffsetExpr));
2767 Instructions.push_back(BranchInst);
2771 bool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc,
2772 SmallVectorImpl<MCInst> &Instructions,
2773 const bool IsMips64, const bool Signed) {
2774 if (hasMips32r6()) {
2775 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2779 warnIfNoMacro(IDLoc);
2781 const MCOperand &RsRegOp = Inst.getOperand(0);
2782 assert(RsRegOp.isReg() && "expected register operand kind");
2783 unsigned RsReg = RsRegOp.getReg();
2785 const MCOperand &RtRegOp = Inst.getOperand(1);
2786 assert(RtRegOp.isReg() && "expected register operand kind");
2787 unsigned RtReg = RtRegOp.getReg();
2792 DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
2793 ZeroReg = Mips::ZERO_64;
2795 DivOp = Signed ? Mips::SDIV : Mips::UDIV;
2796 ZeroReg = Mips::ZERO;
2799 bool UseTraps = useTraps();
2801 if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
2802 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
2803 Warning(IDLoc, "dividing zero by zero");
2805 if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
2807 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2811 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2815 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2820 if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
2821 Warning(IDLoc, "division by zero");
2824 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2828 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2833 // FIXME: The values for these two BranchTarget variables may be different in
2834 // micromips. These magic numbers need to be removed.
2835 unsigned BranchTargetNoTraps;
2836 unsigned BranchTarget;
2839 BranchTarget = IsMips64 ? 12 : 8;
2840 emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, Instructions);
2842 BranchTarget = IsMips64 ? 20 : 16;
2843 BranchTargetNoTraps = 8;
2844 // Branch to the li instruction.
2845 emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc,
2849 emitRR(DivOp, RsReg, RtReg, IDLoc, Instructions);
2852 emitII(Mips::BREAK, 0x7, 0, IDLoc, Instructions);
2855 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2859 unsigned ATReg = getATReg(IDLoc);
2863 emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, Instructions);
2865 // Branch to the mflo instruction.
2866 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2867 emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, Instructions);
2868 emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, Instructions);
2870 // Branch to the mflo instruction.
2871 emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, Instructions);
2872 emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, Instructions);
2876 emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, Instructions);
2878 // Branch to the mflo instruction.
2879 emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, Instructions);
2880 emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, Instructions);
2881 emitII(Mips::BREAK, 0x6, 0, IDLoc, Instructions);
2883 emitR(Mips::MFLO, RsReg, IDLoc, Instructions);
2887 bool MipsAsmParser::expandUlhu(MCInst &Inst, SMLoc IDLoc,
2888 SmallVectorImpl<MCInst> &Instructions) {
2889 if (hasMips32r6() || hasMips64r6()) {
2890 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2894 warnIfNoMacro(IDLoc);
2896 const MCOperand &DstRegOp = Inst.getOperand(0);
2897 assert(DstRegOp.isReg() && "expected register operand kind");
2899 const MCOperand &SrcRegOp = Inst.getOperand(1);
2900 assert(SrcRegOp.isReg() && "expected register operand kind");
2902 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2903 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2905 unsigned DstReg = DstRegOp.getReg();
2906 unsigned SrcReg = SrcRegOp.getReg();
2907 int64_t OffsetValue = OffsetImmOp.getImm();
2909 // NOTE: We always need AT for ULHU, as it is always used as the source
2910 // register for one of the LBu's.
2911 unsigned ATReg = getATReg(IDLoc);
2915 // When the value of offset+1 does not fit in 16 bits, we have to load the
2916 // offset in AT, (D)ADDu the original source register (if there was one), and
2917 // then use AT as the source register for the 2 generated LBu's.
2918 bool LoadedOffsetInAT = false;
2919 if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
2920 LoadedOffsetInAT = true;
2922 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
2923 true, IDLoc, Instructions))
2926 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
2927 // because it will make our output more similar to GAS'. For example,
2928 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
2929 // instead of just an "ori $1, $9, 32768".
2930 // NOTE: If there is no source register specified in the ULHU, the parser
2931 // will interpret it as $0.
2932 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
2933 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
2936 unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
2937 unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
2938 unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
2940 int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
2942 FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2943 SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2945 FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
2946 SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
2949 unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
2952 TmpInst.setOpcode(Mips::LBu);
2953 TmpInst.addOperand(MCOperand::createReg(FirstLbuDstReg));
2954 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2955 TmpInst.addOperand(MCOperand::createImm(FirstLbuOffset));
2956 Instructions.push_back(TmpInst);
2959 TmpInst.setOpcode(Mips::LBu);
2960 TmpInst.addOperand(MCOperand::createReg(SecondLbuDstReg));
2961 TmpInst.addOperand(MCOperand::createReg(LbuSrcReg));
2962 TmpInst.addOperand(MCOperand::createImm(SecondLbuOffset));
2963 Instructions.push_back(TmpInst);
2966 TmpInst.setOpcode(Mips::SLL);
2967 TmpInst.addOperand(MCOperand::createReg(SllReg));
2968 TmpInst.addOperand(MCOperand::createReg(SllReg));
2969 TmpInst.addOperand(MCOperand::createImm(8));
2970 Instructions.push_back(TmpInst);
2973 TmpInst.setOpcode(Mips::OR);
2974 TmpInst.addOperand(MCOperand::createReg(DstReg));
2975 TmpInst.addOperand(MCOperand::createReg(DstReg));
2976 TmpInst.addOperand(MCOperand::createReg(ATReg));
2977 Instructions.push_back(TmpInst);
2982 bool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc,
2983 SmallVectorImpl<MCInst> &Instructions) {
2984 if (hasMips32r6() || hasMips64r6()) {
2985 Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
2989 const MCOperand &DstRegOp = Inst.getOperand(0);
2990 assert(DstRegOp.isReg() && "expected register operand kind");
2992 const MCOperand &SrcRegOp = Inst.getOperand(1);
2993 assert(SrcRegOp.isReg() && "expected register operand kind");
2995 const MCOperand &OffsetImmOp = Inst.getOperand(2);
2996 assert(OffsetImmOp.isImm() && "expected immediate operand kind");
2998 unsigned SrcReg = SrcRegOp.getReg();
2999 int64_t OffsetValue = OffsetImmOp.getImm();
3002 // When the value of offset+3 does not fit in 16 bits, we have to load the
3003 // offset in AT, (D)ADDu the original source register (if there was one), and
3004 // then use AT as the source register for the generated LWL and LWR.
3005 bool LoadedOffsetInAT = false;
3006 if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3007 ATReg = getATReg(IDLoc);
3010 LoadedOffsetInAT = true;
3012 warnIfNoMacro(IDLoc);
3014 if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3015 true, IDLoc, Instructions))
3018 // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3019 // because it will make our output more similar to GAS'. For example,
3020 // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3021 // instead of just an "ori $1, $9, 32768".
3022 // NOTE: If there is no source register specified in the ULW, the parser
3023 // will interpret it as $0.
3024 if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3025 createAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), Instructions);
3028 unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3029 int64_t LeftLoadOffset = 0, RightLoadOffset = 0;
3031 LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3032 RightLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3034 LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3035 RightLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3038 MCInst LeftLoadInst;
3039 LeftLoadInst.setOpcode(Mips::LWL);
3040 LeftLoadInst.addOperand(DstRegOp);
3041 LeftLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3042 LeftLoadInst.addOperand(MCOperand::createImm(LeftLoadOffset));
3043 Instructions.push_back(LeftLoadInst);
3045 MCInst RightLoadInst;
3046 RightLoadInst.setOpcode(Mips::LWR);
3047 RightLoadInst.addOperand(DstRegOp);
3048 RightLoadInst.addOperand(MCOperand::createReg(FinalSrcReg));
3049 RightLoadInst.addOperand(MCOperand::createImm(RightLoadOffset ));
3050 Instructions.push_back(RightLoadInst);
3055 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
3056 SmallVectorImpl<MCInst> &Instructions) {
3058 if (hasShortDelaySlot) {
3059 NopInst.setOpcode(Mips::MOVE16_MM);
3060 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3061 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3063 NopInst.setOpcode(Mips::SLL);
3064 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3065 NopInst.addOperand(MCOperand::createReg(Mips::ZERO));
3066 NopInst.addOperand(MCOperand::createImm(0));
3068 Instructions.push_back(NopInst);
3071 void MipsAsmParser::createAddu(unsigned DstReg, unsigned SrcReg,
3072 unsigned TrgReg, bool Is64Bit,
3073 SmallVectorImpl<MCInst> &Instructions) {
3074 emitRRR(Is64Bit ? Mips::DADDu : Mips::ADDu, DstReg, SrcReg, TrgReg, SMLoc(),
3078 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3079 // As described by the Mips32r2 spec, the registers Rd and Rs for
3080 // jalr.hb must be different.
3081 unsigned Opcode = Inst.getOpcode();
3083 if (Opcode == Mips::JALR_HB &&
3084 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
3085 return Match_RequiresDifferentSrcAndDst;
3087 return Match_Success;
3090 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3091 OperandVector &Operands,
3093 uint64_t &ErrorInfo,
3094 bool MatchingInlineAsm) {
3097 SmallVector<MCInst, 8> Instructions;
3098 unsigned MatchResult =
3099 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3101 switch (MatchResult) {
3102 case Match_Success: {
3103 if (processInstruction(Inst, IDLoc, Instructions))
3105 for (unsigned i = 0; i < Instructions.size(); i++)
3106 Out.EmitInstruction(Instructions[i], STI);
3109 case Match_MissingFeature:
3110 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3112 case Match_InvalidOperand: {
3113 SMLoc ErrorLoc = IDLoc;
3114 if (ErrorInfo != ~0ULL) {
3115 if (ErrorInfo >= Operands.size())
3116 return Error(IDLoc, "too few operands for instruction");
3118 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
3119 if (ErrorLoc == SMLoc())
3123 return Error(ErrorLoc, "invalid operand for instruction");
3125 case Match_MnemonicFail:
3126 return Error(IDLoc, "invalid instruction");
3127 case Match_RequiresDifferentSrcAndDst:
3128 return Error(IDLoc, "source and destination must be different");
3131 llvm_unreachable("Implement any new match types added!");
3134 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
3135 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
3136 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
3137 ") without \".set noat\"");
3140 void MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
3141 if (!AssemblerOptions.back()->isMacro())
3142 Warning(Loc, "macro instruction expanded into multiple instructions");
3146 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
3147 SMRange Range, bool ShowColors) {
3148 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
3149 Range, SMFixIt(Range, FixMsg),
3153 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
3156 CC = StringSwitch<unsigned>(Name)
3192 if (!(isABI_N32() || isABI_N64()))
3195 if (12 <= CC && CC <= 15) {
3196 // Name is one of t4-t7
3197 AsmToken RegTok = getLexer().peekTok();
3198 SMRange RegRange = RegTok.getLocRange();
3200 StringRef FixedName = StringSwitch<StringRef>(Name)
3206 assert(FixedName != "" && "Register name is not one of t4-t7.");
3208 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
3209 "Did you mean $" + FixedName + "?", RegRange);
3212 // Although SGI documentation just cuts out t0-t3 for n32/n64,
3213 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
3214 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
3215 if (8 <= CC && CC <= 11)
3219 CC = StringSwitch<unsigned>(Name)
3231 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
3234 CC = StringSwitch<unsigned>(Name)
3235 .Case("hwr_cpunum", 0)
3236 .Case("hwr_synci_step", 1)
3238 .Case("hwr_ccres", 3)
3239 .Case("hwr_ulr", 29)
3245 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
3247 if (Name[0] == 'f') {
3248 StringRef NumString = Name.substr(1);
3250 if (NumString.getAsInteger(10, IntVal))
3251 return -1; // This is not an integer.
3252 if (IntVal > 31) // Maximum index for fpu register.
3259 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
3261 if (Name.startswith("fcc")) {
3262 StringRef NumString = Name.substr(3);
3264 if (NumString.getAsInteger(10, IntVal))
3265 return -1; // This is not an integer.
3266 if (IntVal > 7) // There are only 8 fcc registers.
3273 int MipsAsmParser::matchACRegisterName(StringRef Name) {
3275 if (Name.startswith("ac")) {
3276 StringRef NumString = Name.substr(2);
3278 if (NumString.getAsInteger(10, IntVal))
3279 return -1; // This is not an integer.
3280 if (IntVal > 3) // There are only 3 acc registers.
3287 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
3290 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
3299 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
3302 CC = StringSwitch<unsigned>(Name)
3305 .Case("msaaccess", 2)
3307 .Case("msamodify", 4)
3308 .Case("msarequest", 5)
3310 .Case("msaunmap", 7)
3316 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
3317 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
3319 reportParseError(Loc,
3320 "pseudo-instruction requires $at, which is not available");
3323 unsigned AT = getReg(
3324 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
3328 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
3329 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
3332 unsigned MipsAsmParser::getGPR(int RegNo) {
3333 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
3337 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
3339 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
3342 return getReg(RegClass, RegNum);
3345 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
3346 MCAsmParser &Parser = getParser();
3347 DEBUG(dbgs() << "parseOperand\n");
3349 // Check if the current operand has a custom associated parser, if so, try to
3350 // custom parse the operand, or fallback to the general approach.
3351 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
3352 if (ResTy == MatchOperand_Success)
3354 // If there wasn't a custom match, try the generic matcher below. Otherwise,
3355 // there was a match, but an error occurred, in which case, just return that
3356 // the operand parsing failed.
3357 if (ResTy == MatchOperand_ParseFail)
3360 DEBUG(dbgs() << ".. Generic Parser\n");
3362 switch (getLexer().getKind()) {
3364 Error(Parser.getTok().getLoc(), "unexpected token in operand");
3366 case AsmToken::Dollar: {
3367 // Parse the register.
3368 SMLoc S = Parser.getTok().getLoc();
3370 // Almost all registers have been parsed by custom parsers. There is only
3371 // one exception to this. $zero (and it's alias $0) will reach this point
3372 // for div, divu, and similar instructions because it is not an operand
3373 // to the instruction definition but an explicit register. Special case
3374 // this situation for now.
3375 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
3378 // Maybe it is a symbol reference.
3379 StringRef Identifier;
3380 if (Parser.parseIdentifier(Identifier))
3383 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3384 MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
3385 // Otherwise create a symbol reference.
3387 MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
3389 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
3392 // Else drop to expression parsing.
3393 case AsmToken::LParen:
3394 case AsmToken::Minus:
3395 case AsmToken::Plus:
3396 case AsmToken::Integer:
3397 case AsmToken::Tilde:
3398 case AsmToken::String: {
3399 DEBUG(dbgs() << ".. generic integer\n");
3400 OperandMatchResultTy ResTy = parseImm(Operands);
3401 return ResTy != MatchOperand_Success;
3403 case AsmToken::Percent: {
3404 // It is a symbol reference or constant expression.
3405 const MCExpr *IdVal;
3406 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
3407 if (parseRelocOperand(IdVal))
3410 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3412 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3414 } // case AsmToken::Percent
3415 } // switch(getLexer().getKind())
3419 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
3420 StringRef RelocStr) {
3422 // Check the type of the expression.
3423 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
3424 // It's a constant, evaluate reloc value.
3426 switch (getVariantKind(RelocStr)) {
3427 case MCSymbolRefExpr::VK_Mips_ABS_LO:
3428 // Get the 1st 16-bits.
3429 Val = MCE->getValue() & 0xffff;
3431 case MCSymbolRefExpr::VK_Mips_ABS_HI:
3432 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
3433 // 16 bits being negative.
3434 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
3436 case MCSymbolRefExpr::VK_Mips_HIGHER:
3437 // Get the 3rd 16-bits.
3438 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
3440 case MCSymbolRefExpr::VK_Mips_HIGHEST:
3441 // Get the 4th 16-bits.
3442 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
3445 report_fatal_error("unsupported reloc value");
3447 return MCConstantExpr::create(Val, getContext());
3450 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
3451 // It's a symbol, create a symbolic expression from the symbol.
3452 const MCSymbol *Symbol = &MSRE->getSymbol();
3453 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3454 Res = MCSymbolRefExpr::create(Symbol, VK, getContext());
3458 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3459 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
3461 // Try to create target expression.
3462 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
3463 return MipsMCExpr::create(VK, Expr, getContext());
3465 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
3466 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
3467 Res = MCBinaryExpr::create(BE->getOpcode(), LExp, RExp, getContext());
3471 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
3472 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
3473 Res = MCUnaryExpr::create(UN->getOpcode(), UnExp, getContext());
3476 // Just return the original expression.
3480 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
3482 switch (Expr->getKind()) {
3483 case MCExpr::Constant:
3485 case MCExpr::SymbolRef:
3486 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
3487 case MCExpr::Binary:
3488 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
3489 if (!isEvaluated(BE->getLHS()))
3491 return isEvaluated(BE->getRHS());
3494 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
3495 case MCExpr::Target:
3501 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
3502 MCAsmParser &Parser = getParser();
3503 Parser.Lex(); // Eat the % token.
3504 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
3505 if (Tok.isNot(AsmToken::Identifier))
3508 std::string Str = Tok.getIdentifier();
3510 Parser.Lex(); // Eat the identifier.
3511 // Now make an expression from the rest of the operand.
3512 const MCExpr *IdVal;
3515 if (getLexer().getKind() == AsmToken::LParen) {
3517 Parser.Lex(); // Eat the '(' token.
3518 if (getLexer().getKind() == AsmToken::Percent) {
3519 Parser.Lex(); // Eat the % token.
3520 const AsmToken &nextTok = Parser.getTok();
3521 if (nextTok.isNot(AsmToken::Identifier))
3524 Str += nextTok.getIdentifier();
3525 Parser.Lex(); // Eat the identifier.
3526 if (getLexer().getKind() != AsmToken::LParen)
3531 if (getParser().parseParenExpression(IdVal, EndLoc))
3534 while (getLexer().getKind() == AsmToken::RParen)
3535 Parser.Lex(); // Eat the ')' token.
3538 return true; // Parenthesis must follow the relocation operand.
3540 Res = evaluateRelocExpr(IdVal, Str);
3544 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
3546 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
3547 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
3548 if (ResTy == MatchOperand_Success) {
3549 assert(Operands.size() == 1);
3550 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
3551 StartLoc = Operand.getStartLoc();
3552 EndLoc = Operand.getEndLoc();
3554 // AFAIK, we only support numeric registers and named GPR's in CFI
3556 // Don't worry about eating tokens before failing. Using an unrecognised
3557 // register is a parse error.
3558 if (Operand.isGPRAsmReg()) {
3559 // Resolve to GPR32 or GPR64 appropriately.
3560 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
3563 return (RegNo == (unsigned)-1);
3566 assert(Operands.size() == 0);
3567 return (RegNo == (unsigned)-1);
3570 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
3571 MCAsmParser &Parser = getParser();
3574 unsigned NumOfLParen = 0;
3576 while (getLexer().getKind() == AsmToken::LParen) {
3581 switch (getLexer().getKind()) {
3584 case AsmToken::Identifier:
3585 case AsmToken::LParen:
3586 case AsmToken::Integer:
3587 case AsmToken::Minus:
3588 case AsmToken::Plus:
3590 Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
3592 Result = (getParser().parseExpression(Res));
3593 while (getLexer().getKind() == AsmToken::RParen)
3596 case AsmToken::Percent:
3597 Result = parseRelocOperand(Res);
3602 MipsAsmParser::OperandMatchResultTy
3603 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
3604 MCAsmParser &Parser = getParser();
3605 DEBUG(dbgs() << "parseMemOperand\n");
3606 const MCExpr *IdVal = nullptr;
3608 bool isParenExpr = false;
3609 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
3610 // First operand is the offset.
3611 S = Parser.getTok().getLoc();
3613 if (getLexer().getKind() == AsmToken::LParen) {
3618 if (getLexer().getKind() != AsmToken::Dollar) {
3619 if (parseMemOffset(IdVal, isParenExpr))
3620 return MatchOperand_ParseFail;
3622 const AsmToken &Tok = Parser.getTok(); // Get the next token.
3623 if (Tok.isNot(AsmToken::LParen)) {
3624 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
3625 if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
3627 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3628 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3629 return MatchOperand_Success;
3631 if (Tok.is(AsmToken::EndOfStatement)) {
3633 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3635 // Zero register assumed, add a memory operand with ZERO as its base.
3636 // "Base" will be managed by k_Memory.
3637 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
3640 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
3641 return MatchOperand_Success;
3643 Error(Parser.getTok().getLoc(), "'(' expected");
3644 return MatchOperand_ParseFail;
3647 Parser.Lex(); // Eat the '(' token.
3650 Res = parseAnyRegister(Operands);
3651 if (Res != MatchOperand_Success)
3654 if (Parser.getTok().isNot(AsmToken::RParen)) {
3655 Error(Parser.getTok().getLoc(), "')' expected");
3656 return MatchOperand_ParseFail;
3659 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3661 Parser.Lex(); // Eat the ')' token.
3664 IdVal = MCConstantExpr::create(0, getContext());
3666 // Replace the register operand with the memory operand.
3667 std::unique_ptr<MipsOperand> op(
3668 static_cast<MipsOperand *>(Operands.back().release()));
3669 // Remove the register from the operands.
3670 // "op" will be managed by k_Memory.
3671 Operands.pop_back();
3672 // Add the memory operand.
3673 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
3675 if (IdVal->evaluateAsAbsolute(Imm))
3676 IdVal = MCConstantExpr::create(Imm, getContext());
3677 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
3678 IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
3682 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
3683 return MatchOperand_Success;
3686 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
3687 MCAsmParser &Parser = getParser();
3688 MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
3690 SMLoc S = Parser.getTok().getLoc();
3692 if (Sym->isVariable())
3693 Expr = Sym->getVariableValue();
3696 if (Expr->getKind() == MCExpr::SymbolRef) {
3697 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3698 StringRef DefSymbol = Ref->getSymbol().getName();
3699 if (DefSymbol.startswith("$")) {
3700 OperandMatchResultTy ResTy =
3701 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
3702 if (ResTy == MatchOperand_Success) {
3705 } else if (ResTy == MatchOperand_ParseFail)
3706 llvm_unreachable("Should never ParseFail");
3709 } else if (Expr->getKind() == MCExpr::Constant) {
3711 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
3713 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
3720 MipsAsmParser::OperandMatchResultTy
3721 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
3722 StringRef Identifier,
3724 int Index = matchCPURegisterName(Identifier);
3726 Operands.push_back(MipsOperand::createGPRReg(
3727 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3728 return MatchOperand_Success;
3731 Index = matchHWRegsRegisterName(Identifier);
3733 Operands.push_back(MipsOperand::createHWRegsReg(
3734 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3735 return MatchOperand_Success;
3738 Index = matchFPURegisterName(Identifier);
3740 Operands.push_back(MipsOperand::createFGRReg(
3741 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3742 return MatchOperand_Success;
3745 Index = matchFCCRegisterName(Identifier);
3747 Operands.push_back(MipsOperand::createFCCReg(
3748 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3749 return MatchOperand_Success;
3752 Index = matchACRegisterName(Identifier);
3754 Operands.push_back(MipsOperand::createACCReg(
3755 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3756 return MatchOperand_Success;
3759 Index = matchMSA128RegisterName(Identifier);
3761 Operands.push_back(MipsOperand::createMSA128Reg(
3762 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3763 return MatchOperand_Success;
3766 Index = matchMSA128CtrlRegisterName(Identifier);
3768 Operands.push_back(MipsOperand::createMSACtrlReg(
3769 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
3770 return MatchOperand_Success;
3773 return MatchOperand_NoMatch;
3776 MipsAsmParser::OperandMatchResultTy
3777 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
3778 MCAsmParser &Parser = getParser();
3779 auto Token = Parser.getLexer().peekTok(false);
3781 if (Token.is(AsmToken::Identifier)) {
3782 DEBUG(dbgs() << ".. identifier\n");
3783 StringRef Identifier = Token.getIdentifier();
3784 OperandMatchResultTy ResTy =
3785 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
3787 } else if (Token.is(AsmToken::Integer)) {
3788 DEBUG(dbgs() << ".. integer\n");
3789 Operands.push_back(MipsOperand::createNumericReg(
3790 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
3792 return MatchOperand_Success;
3795 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
3797 return MatchOperand_NoMatch;
3800 MipsAsmParser::OperandMatchResultTy
3801 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
3802 MCAsmParser &Parser = getParser();
3803 DEBUG(dbgs() << "parseAnyRegister\n");
3805 auto Token = Parser.getTok();
3807 SMLoc S = Token.getLoc();
3809 if (Token.isNot(AsmToken::Dollar)) {
3810 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
3811 if (Token.is(AsmToken::Identifier)) {
3812 if (searchSymbolAlias(Operands))
3813 return MatchOperand_Success;
3815 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
3816 return MatchOperand_NoMatch;
3818 DEBUG(dbgs() << ".. $\n");
3820 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
3821 if (ResTy == MatchOperand_Success) {
3823 Parser.Lex(); // identifier
3828 MipsAsmParser::OperandMatchResultTy
3829 MipsAsmParser::parseImm(OperandVector &Operands) {
3830 MCAsmParser &Parser = getParser();
3831 switch (getLexer().getKind()) {
3833 return MatchOperand_NoMatch;
3834 case AsmToken::LParen:
3835 case AsmToken::Minus:
3836 case AsmToken::Plus:
3837 case AsmToken::Integer:
3838 case AsmToken::Tilde:
3839 case AsmToken::String:
3843 const MCExpr *IdVal;
3844 SMLoc S = Parser.getTok().getLoc();
3845 if (getParser().parseExpression(IdVal))
3846 return MatchOperand_ParseFail;
3848 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3849 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
3850 return MatchOperand_Success;
3853 MipsAsmParser::OperandMatchResultTy
3854 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
3855 MCAsmParser &Parser = getParser();
3856 DEBUG(dbgs() << "parseJumpTarget\n");
3858 SMLoc S = getLexer().getLoc();
3860 // Integers and expressions are acceptable
3861 OperandMatchResultTy ResTy = parseImm(Operands);
3862 if (ResTy != MatchOperand_NoMatch)
3865 // Registers are a valid target and have priority over symbols.
3866 ResTy = parseAnyRegister(Operands);
3867 if (ResTy != MatchOperand_NoMatch)
3870 const MCExpr *Expr = nullptr;
3871 if (Parser.parseExpression(Expr)) {
3872 // We have no way of knowing if a symbol was consumed so we must ParseFail
3873 return MatchOperand_ParseFail;
3876 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
3877 return MatchOperand_Success;
3880 MipsAsmParser::OperandMatchResultTy
3881 MipsAsmParser::parseInvNum(OperandVector &Operands) {
3882 MCAsmParser &Parser = getParser();
3883 const MCExpr *IdVal;
3884 // If the first token is '$' we may have register operand.
3885 if (Parser.getTok().is(AsmToken::Dollar))
3886 return MatchOperand_NoMatch;
3887 SMLoc S = Parser.getTok().getLoc();
3888 if (getParser().parseExpression(IdVal))
3889 return MatchOperand_ParseFail;
3890 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
3891 assert(MCE && "Unexpected MCExpr type.");
3892 int64_t Val = MCE->getValue();
3893 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
3894 Operands.push_back(MipsOperand::CreateImm(
3895 MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
3896 return MatchOperand_Success;
3899 MipsAsmParser::OperandMatchResultTy
3900 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3901 MCAsmParser &Parser = getParser();
3902 switch (getLexer().getKind()) {
3904 return MatchOperand_NoMatch;
3905 case AsmToken::LParen:
3906 case AsmToken::Plus:
3907 case AsmToken::Minus:
3908 case AsmToken::Integer:
3913 SMLoc S = Parser.getTok().getLoc();
3915 if (getParser().parseExpression(Expr))
3916 return MatchOperand_ParseFail;
3919 if (!Expr->evaluateAsAbsolute(Val)) {
3920 Error(S, "expected immediate value");
3921 return MatchOperand_ParseFail;
3924 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3925 // and because the CPU always adds one to the immediate field, the allowed
3926 // range becomes 1..4. We'll only check the range here and will deal
3927 // with the addition/subtraction when actually decoding/encoding
3929 if (Val < 1 || Val > 4) {
3930 Error(S, "immediate not in range (1..4)");
3931 return MatchOperand_ParseFail;
3935 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3936 return MatchOperand_Success;
3939 MipsAsmParser::OperandMatchResultTy
3940 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3941 MCAsmParser &Parser = getParser();
3942 SmallVector<unsigned, 10> Regs;
3944 unsigned PrevReg = Mips::NoRegister;
3945 bool RegRange = false;
3946 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3948 if (Parser.getTok().isNot(AsmToken::Dollar))
3949 return MatchOperand_ParseFail;
3951 SMLoc S = Parser.getTok().getLoc();
3952 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3953 SMLoc E = getLexer().getLoc();
3954 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3955 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3957 // Remove last register operand because registers from register range
3958 // should be inserted first.
3959 if (RegNo == Mips::RA) {
3960 Regs.push_back(RegNo);
3962 unsigned TmpReg = PrevReg + 1;
3963 while (TmpReg <= RegNo) {
3964 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3965 Error(E, "invalid register operand");
3966 return MatchOperand_ParseFail;
3970 Regs.push_back(TmpReg++);
3976 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3977 (RegNo != Mips::RA)) {
3978 Error(E, "$16 or $31 expected");
3979 return MatchOperand_ParseFail;
3980 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3981 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3982 Error(E, "invalid register operand");
3983 return MatchOperand_ParseFail;
3984 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3985 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3986 Error(E, "consecutive register numbers expected");
3987 return MatchOperand_ParseFail;
3990 Regs.push_back(RegNo);
3993 if (Parser.getTok().is(AsmToken::Minus))
3996 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3997 !Parser.getTok().isNot(AsmToken::Comma)) {
3998 Error(E, "',' or '-' expected");
3999 return MatchOperand_ParseFail;
4002 Lex(); // Consume comma or minus
4003 if (Parser.getTok().isNot(AsmToken::Dollar))
4009 SMLoc E = Parser.getTok().getLoc();
4010 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4011 parseMemOperand(Operands);
4012 return MatchOperand_Success;
4015 MipsAsmParser::OperandMatchResultTy
4016 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4017 MCAsmParser &Parser = getParser();
4019 SMLoc S = Parser.getTok().getLoc();
4020 if (parseAnyRegister(Operands) != MatchOperand_Success)
4021 return MatchOperand_ParseFail;
4023 SMLoc E = Parser.getTok().getLoc();
4024 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
4025 unsigned Reg = Op.getGPR32Reg();
4026 Operands.pop_back();
4027 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
4028 return MatchOperand_Success;
4031 MipsAsmParser::OperandMatchResultTy
4032 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4033 MCAsmParser &Parser = getParser();
4034 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4035 SmallVector<unsigned, 10> Regs;
4037 if (Parser.getTok().isNot(AsmToken::Dollar))
4038 return MatchOperand_ParseFail;
4040 SMLoc S = Parser.getTok().getLoc();
4042 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4043 return MatchOperand_ParseFail;
4045 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4046 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4047 Regs.push_back(RegNo);
4049 SMLoc E = Parser.getTok().getLoc();
4050 if (Parser.getTok().isNot(AsmToken::Comma)) {
4051 Error(E, "',' expected");
4052 return MatchOperand_ParseFail;
4058 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4059 return MatchOperand_ParseFail;
4061 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4062 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4063 Regs.push_back(RegNo);
4065 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4067 return MatchOperand_Success;
4070 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
4072 MCSymbolRefExpr::VariantKind VK =
4073 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
4074 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
4075 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
4076 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
4077 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
4078 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
4079 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
4080 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
4081 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
4082 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
4083 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
4084 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
4085 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
4086 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
4087 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
4088 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
4089 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
4090 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
4091 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
4092 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
4093 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
4094 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
4095 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
4096 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
4097 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
4098 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
4099 .Default(MCSymbolRefExpr::VK_None);
4101 assert(VK != MCSymbolRefExpr::VK_None);
4106 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
4108 /// ::= '(', register, ')'
4109 /// handle it before we iterate so we don't get tripped up by the lack of
4111 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
4112 MCAsmParser &Parser = getParser();
4113 if (getLexer().is(AsmToken::LParen)) {
4115 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
4117 if (parseOperand(Operands, Name)) {
4118 SMLoc Loc = getLexer().getLoc();
4119 Parser.eatToEndOfStatement();
4120 return Error(Loc, "unexpected token in argument list");
4122 if (Parser.getTok().isNot(AsmToken::RParen)) {
4123 SMLoc Loc = getLexer().getLoc();
4124 Parser.eatToEndOfStatement();
4125 return Error(Loc, "unexpected token, expected ')'");
4128 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
4134 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
4135 /// either one of these.
4136 /// ::= '[', register, ']'
4137 /// ::= '[', integer, ']'
4138 /// handle it before we iterate so we don't get tripped up by the lack of
4140 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
4141 OperandVector &Operands) {
4142 MCAsmParser &Parser = getParser();
4143 if (getLexer().is(AsmToken::LBrac)) {
4145 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
4147 if (parseOperand(Operands, Name)) {
4148 SMLoc Loc = getLexer().getLoc();
4149 Parser.eatToEndOfStatement();
4150 return Error(Loc, "unexpected token in argument list");
4152 if (Parser.getTok().isNot(AsmToken::RBrac)) {
4153 SMLoc Loc = getLexer().getLoc();
4154 Parser.eatToEndOfStatement();
4155 return Error(Loc, "unexpected token, expected ']'");
4158 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
4164 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4165 SMLoc NameLoc, OperandVector &Operands) {
4166 MCAsmParser &Parser = getParser();
4167 DEBUG(dbgs() << "ParseInstruction\n");
4169 // We have reached first instruction, module directive are now forbidden.
4170 getTargetStreamer().forbidModuleDirective();
4172 // Check if we have valid mnemonic
4173 if (!mnemonicIsValid(Name, 0)) {
4174 Parser.eatToEndOfStatement();
4175 return Error(NameLoc, "unknown instruction");
4177 // First operand in MCInst is instruction mnemonic.
4178 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4180 // Read the remaining operands.
4181 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4182 // Read the first operand.
4183 if (parseOperand(Operands, Name)) {
4184 SMLoc Loc = getLexer().getLoc();
4185 Parser.eatToEndOfStatement();
4186 return Error(Loc, "unexpected token in argument list");
4188 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
4190 // AFAIK, parenthesis suffixes are never on the first operand
4192 while (getLexer().is(AsmToken::Comma)) {
4193 Parser.Lex(); // Eat the comma.
4194 // Parse and remember the operand.
4195 if (parseOperand(Operands, Name)) {
4196 SMLoc Loc = getLexer().getLoc();
4197 Parser.eatToEndOfStatement();
4198 return Error(Loc, "unexpected token in argument list");
4200 // Parse bracket and parenthesis suffixes before we iterate
4201 if (getLexer().is(AsmToken::LBrac)) {
4202 if (parseBracketSuffix(Name, Operands))
4204 } else if (getLexer().is(AsmToken::LParen) &&
4205 parseParenSuffix(Name, Operands))
4209 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4210 SMLoc Loc = getLexer().getLoc();
4211 Parser.eatToEndOfStatement();
4212 return Error(Loc, "unexpected token in argument list");
4214 Parser.Lex(); // Consume the EndOfStatement.
4218 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
4219 MCAsmParser &Parser = getParser();
4220 SMLoc Loc = getLexer().getLoc();
4221 Parser.eatToEndOfStatement();
4222 return Error(Loc, ErrorMsg);
4225 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4226 return Error(Loc, ErrorMsg);
4229 bool MipsAsmParser::parseSetNoAtDirective() {
4230 MCAsmParser &Parser = getParser();
4231 // Line should look like: ".set noat".
4233 // Set the $at register to $0.
4234 AssemblerOptions.back()->setATRegIndex(0);
4236 Parser.Lex(); // Eat "noat".
4238 // If this is not the end of the statement, report an error.
4239 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4240 reportParseError("unexpected token, expected end of statement");
4244 getTargetStreamer().emitDirectiveSetNoAt();
4245 Parser.Lex(); // Consume the EndOfStatement.
4249 bool MipsAsmParser::parseSetAtDirective() {
4250 // Line can be: ".set at", which sets $at to $1
4251 // or ".set at=$reg", which sets $at to $reg.
4252 MCAsmParser &Parser = getParser();
4253 Parser.Lex(); // Eat "at".
4255 if (getLexer().is(AsmToken::EndOfStatement)) {
4256 // No register was specified, so we set $at to $1.
4257 AssemblerOptions.back()->setATRegIndex(1);
4259 getTargetStreamer().emitDirectiveSetAt();
4260 Parser.Lex(); // Consume the EndOfStatement.
4264 if (getLexer().isNot(AsmToken::Equal)) {
4265 reportParseError("unexpected token, expected equals sign");
4268 Parser.Lex(); // Eat "=".
4270 if (getLexer().isNot(AsmToken::Dollar)) {
4271 if (getLexer().is(AsmToken::EndOfStatement)) {
4272 reportParseError("no register specified");
4275 reportParseError("unexpected token, expected dollar sign '$'");
4279 Parser.Lex(); // Eat "$".
4281 // Find out what "reg" is.
4283 const AsmToken &Reg = Parser.getTok();
4284 if (Reg.is(AsmToken::Identifier)) {
4285 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4286 } else if (Reg.is(AsmToken::Integer)) {
4287 AtRegNo = Reg.getIntVal();
4289 reportParseError("unexpected token, expected identifier or integer");
4293 // Check if $reg is a valid register. If it is, set $at to $reg.
4294 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4295 reportParseError("invalid register");
4298 Parser.Lex(); // Eat "reg".
4300 // If this is not the end of the statement, report an error.
4301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4302 reportParseError("unexpected token, expected end of statement");
4306 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4308 Parser.Lex(); // Consume the EndOfStatement.
4312 bool MipsAsmParser::parseSetReorderDirective() {
4313 MCAsmParser &Parser = getParser();
4315 // If this is not the end of the statement, report an error.
4316 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4317 reportParseError("unexpected token, expected end of statement");
4320 AssemblerOptions.back()->setReorder();
4321 getTargetStreamer().emitDirectiveSetReorder();
4322 Parser.Lex(); // Consume the EndOfStatement.
4326 bool MipsAsmParser::parseSetNoReorderDirective() {
4327 MCAsmParser &Parser = getParser();
4329 // If this is not the end of the statement, report an error.
4330 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4331 reportParseError("unexpected token, expected end of statement");
4334 AssemblerOptions.back()->setNoReorder();
4335 getTargetStreamer().emitDirectiveSetNoReorder();
4336 Parser.Lex(); // Consume the EndOfStatement.
4340 bool MipsAsmParser::parseSetMacroDirective() {
4341 MCAsmParser &Parser = getParser();
4343 // If this is not the end of the statement, report an error.
4344 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4345 reportParseError("unexpected token, expected end of statement");
4348 AssemblerOptions.back()->setMacro();
4349 getTargetStreamer().emitDirectiveSetMacro();
4350 Parser.Lex(); // Consume the EndOfStatement.
4354 bool MipsAsmParser::parseSetNoMacroDirective() {
4355 MCAsmParser &Parser = getParser();
4357 // If this is not the end of the statement, report an error.
4358 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4359 reportParseError("unexpected token, expected end of statement");
4362 if (AssemblerOptions.back()->isReorder()) {
4363 reportParseError("`noreorder' must be set before `nomacro'");
4366 AssemblerOptions.back()->setNoMacro();
4367 getTargetStreamer().emitDirectiveSetNoMacro();
4368 Parser.Lex(); // Consume the EndOfStatement.
4372 bool MipsAsmParser::parseSetMsaDirective() {
4373 MCAsmParser &Parser = getParser();
4376 // If this is not the end of the statement, report an error.
4377 if (getLexer().isNot(AsmToken::EndOfStatement))
4378 return reportParseError("unexpected token, expected end of statement");
4380 setFeatureBits(Mips::FeatureMSA, "msa");
4381 getTargetStreamer().emitDirectiveSetMsa();
4385 bool MipsAsmParser::parseSetNoMsaDirective() {
4386 MCAsmParser &Parser = getParser();
4389 // If this is not the end of the statement, report an error.
4390 if (getLexer().isNot(AsmToken::EndOfStatement))
4391 return reportParseError("unexpected token, expected end of statement");
4393 clearFeatureBits(Mips::FeatureMSA, "msa");
4394 getTargetStreamer().emitDirectiveSetNoMsa();
4398 bool MipsAsmParser::parseSetNoDspDirective() {
4399 MCAsmParser &Parser = getParser();
4400 Parser.Lex(); // Eat "nodsp".
4402 // If this is not the end of the statement, report an error.
4403 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4404 reportParseError("unexpected token, expected end of statement");
4408 clearFeatureBits(Mips::FeatureDSP, "dsp");
4409 getTargetStreamer().emitDirectiveSetNoDsp();
4413 bool MipsAsmParser::parseSetMips16Directive() {
4414 MCAsmParser &Parser = getParser();
4415 Parser.Lex(); // Eat "mips16".
4417 // If this is not the end of the statement, report an error.
4418 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4419 reportParseError("unexpected token, expected end of statement");
4423 setFeatureBits(Mips::FeatureMips16, "mips16");
4424 getTargetStreamer().emitDirectiveSetMips16();
4425 Parser.Lex(); // Consume the EndOfStatement.
4429 bool MipsAsmParser::parseSetNoMips16Directive() {
4430 MCAsmParser &Parser = getParser();
4431 Parser.Lex(); // Eat "nomips16".
4433 // If this is not the end of the statement, report an error.
4434 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4435 reportParseError("unexpected token, expected end of statement");
4439 clearFeatureBits(Mips::FeatureMips16, "mips16");
4440 getTargetStreamer().emitDirectiveSetNoMips16();
4441 Parser.Lex(); // Consume the EndOfStatement.
4445 bool MipsAsmParser::parseSetFpDirective() {
4446 MCAsmParser &Parser = getParser();
4447 MipsABIFlagsSection::FpABIKind FpAbiVal;
4448 // Line can be: .set fp=32
4451 Parser.Lex(); // Eat fp token
4452 AsmToken Tok = Parser.getTok();
4453 if (Tok.isNot(AsmToken::Equal)) {
4454 reportParseError("unexpected token, expected equals sign '='");
4457 Parser.Lex(); // Eat '=' token.
4458 Tok = Parser.getTok();
4460 if (!parseFpABIValue(FpAbiVal, ".set"))
4463 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4464 reportParseError("unexpected token, expected end of statement");
4467 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
4468 Parser.Lex(); // Consume the EndOfStatement.
4472 bool MipsAsmParser::parseSetOddSPRegDirective() {
4473 MCAsmParser &Parser = getParser();
4475 Parser.Lex(); // Eat "oddspreg".
4476 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4477 reportParseError("unexpected token, expected end of statement");
4481 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4482 getTargetStreamer().emitDirectiveSetOddSPReg();
4486 bool MipsAsmParser::parseSetNoOddSPRegDirective() {
4487 MCAsmParser &Parser = getParser();
4489 Parser.Lex(); // Eat "nooddspreg".
4490 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4491 reportParseError("unexpected token, expected end of statement");
4495 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4496 getTargetStreamer().emitDirectiveSetNoOddSPReg();
4500 bool MipsAsmParser::parseSetPopDirective() {
4501 MCAsmParser &Parser = getParser();
4502 SMLoc Loc = getLexer().getLoc();
4505 if (getLexer().isNot(AsmToken::EndOfStatement))
4506 return reportParseError("unexpected token, expected end of statement");
4508 // Always keep an element on the options "stack" to prevent the user
4509 // from changing the initial options. This is how we remember them.
4510 if (AssemblerOptions.size() == 2)
4511 return reportParseError(Loc, ".set pop with no .set push");
4513 AssemblerOptions.pop_back();
4514 setAvailableFeatures(
4515 ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
4516 STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
4518 getTargetStreamer().emitDirectiveSetPop();
4522 bool MipsAsmParser::parseSetPushDirective() {
4523 MCAsmParser &Parser = getParser();
4525 if (getLexer().isNot(AsmToken::EndOfStatement))
4526 return reportParseError("unexpected token, expected end of statement");
4528 // Create a copy of the current assembler options environment and push it.
4529 AssemblerOptions.push_back(
4530 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
4532 getTargetStreamer().emitDirectiveSetPush();
4536 bool MipsAsmParser::parseSetSoftFloatDirective() {
4537 MCAsmParser &Parser = getParser();
4539 if (getLexer().isNot(AsmToken::EndOfStatement))
4540 return reportParseError("unexpected token, expected end of statement");
4542 setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4543 getTargetStreamer().emitDirectiveSetSoftFloat();
4547 bool MipsAsmParser::parseSetHardFloatDirective() {
4548 MCAsmParser &Parser = getParser();
4550 if (getLexer().isNot(AsmToken::EndOfStatement))
4551 return reportParseError("unexpected token, expected end of statement");
4553 clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
4554 getTargetStreamer().emitDirectiveSetHardFloat();
4558 bool MipsAsmParser::parseSetAssignment() {
4560 const MCExpr *Value;
4561 MCAsmParser &Parser = getParser();
4563 if (Parser.parseIdentifier(Name))
4564 reportParseError("expected identifier after .set");
4566 if (getLexer().isNot(AsmToken::Comma))
4567 return reportParseError("unexpected token, expected comma");
4570 if (Parser.parseExpression(Value))
4571 return reportParseError("expected valid expression after comma");
4573 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
4574 Sym->setVariableValue(Value);
4579 bool MipsAsmParser::parseSetMips0Directive() {
4580 MCAsmParser &Parser = getParser();
4582 if (getLexer().isNot(AsmToken::EndOfStatement))
4583 return reportParseError("unexpected token, expected end of statement");
4585 // Reset assembler options to their initial values.
4586 setAvailableFeatures(
4587 ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
4588 STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
4589 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
4591 getTargetStreamer().emitDirectiveSetMips0();
4595 bool MipsAsmParser::parseSetArchDirective() {
4596 MCAsmParser &Parser = getParser();
4598 if (getLexer().isNot(AsmToken::Equal))
4599 return reportParseError("unexpected token, expected equals sign");
4603 if (Parser.parseIdentifier(Arch))
4604 return reportParseError("expected arch identifier");
4606 StringRef ArchFeatureName =
4607 StringSwitch<StringRef>(Arch)
4608 .Case("mips1", "mips1")
4609 .Case("mips2", "mips2")
4610 .Case("mips3", "mips3")
4611 .Case("mips4", "mips4")
4612 .Case("mips5", "mips5")
4613 .Case("mips32", "mips32")
4614 .Case("mips32r2", "mips32r2")
4615 .Case("mips32r3", "mips32r3")
4616 .Case("mips32r5", "mips32r5")
4617 .Case("mips32r6", "mips32r6")
4618 .Case("mips64", "mips64")
4619 .Case("mips64r2", "mips64r2")
4620 .Case("mips64r3", "mips64r3")
4621 .Case("mips64r5", "mips64r5")
4622 .Case("mips64r6", "mips64r6")
4623 .Case("cnmips", "cnmips")
4624 .Case("r4000", "mips3") // This is an implementation of Mips3.
4627 if (ArchFeatureName.empty())
4628 return reportParseError("unsupported architecture");
4630 selectArch(ArchFeatureName);
4631 getTargetStreamer().emitDirectiveSetArch(Arch);
4635 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
4636 MCAsmParser &Parser = getParser();
4638 if (getLexer().isNot(AsmToken::EndOfStatement))
4639 return reportParseError("unexpected token, expected end of statement");
4643 llvm_unreachable("Unimplemented feature");
4644 case Mips::FeatureDSP:
4645 setFeatureBits(Mips::FeatureDSP, "dsp");
4646 getTargetStreamer().emitDirectiveSetDsp();
4648 case Mips::FeatureMicroMips:
4649 getTargetStreamer().emitDirectiveSetMicroMips();
4651 case Mips::FeatureMips1:
4652 selectArch("mips1");
4653 getTargetStreamer().emitDirectiveSetMips1();
4655 case Mips::FeatureMips2:
4656 selectArch("mips2");
4657 getTargetStreamer().emitDirectiveSetMips2();
4659 case Mips::FeatureMips3:
4660 selectArch("mips3");
4661 getTargetStreamer().emitDirectiveSetMips3();
4663 case Mips::FeatureMips4:
4664 selectArch("mips4");
4665 getTargetStreamer().emitDirectiveSetMips4();
4667 case Mips::FeatureMips5:
4668 selectArch("mips5");
4669 getTargetStreamer().emitDirectiveSetMips5();
4671 case Mips::FeatureMips32:
4672 selectArch("mips32");
4673 getTargetStreamer().emitDirectiveSetMips32();
4675 case Mips::FeatureMips32r2:
4676 selectArch("mips32r2");
4677 getTargetStreamer().emitDirectiveSetMips32R2();
4679 case Mips::FeatureMips32r3:
4680 selectArch("mips32r3");
4681 getTargetStreamer().emitDirectiveSetMips32R3();
4683 case Mips::FeatureMips32r5:
4684 selectArch("mips32r5");
4685 getTargetStreamer().emitDirectiveSetMips32R5();
4687 case Mips::FeatureMips32r6:
4688 selectArch("mips32r6");
4689 getTargetStreamer().emitDirectiveSetMips32R6();
4691 case Mips::FeatureMips64:
4692 selectArch("mips64");
4693 getTargetStreamer().emitDirectiveSetMips64();
4695 case Mips::FeatureMips64r2:
4696 selectArch("mips64r2");
4697 getTargetStreamer().emitDirectiveSetMips64R2();
4699 case Mips::FeatureMips64r3:
4700 selectArch("mips64r3");
4701 getTargetStreamer().emitDirectiveSetMips64R3();
4703 case Mips::FeatureMips64r5:
4704 selectArch("mips64r5");
4705 getTargetStreamer().emitDirectiveSetMips64R5();
4707 case Mips::FeatureMips64r6:
4708 selectArch("mips64r6");
4709 getTargetStreamer().emitDirectiveSetMips64R6();
4715 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
4716 MCAsmParser &Parser = getParser();
4717 if (getLexer().isNot(AsmToken::Comma)) {
4718 SMLoc Loc = getLexer().getLoc();
4719 Parser.eatToEndOfStatement();
4720 return Error(Loc, ErrorStr);
4723 Parser.Lex(); // Eat the comma.
4727 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
4728 if (AssemblerOptions.back()->isReorder())
4729 Warning(Loc, ".cpload should be inside a noreorder section");
4731 if (inMips16Mode()) {
4732 reportParseError(".cpload is not supported in Mips16 mode");
4736 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
4737 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
4738 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4739 reportParseError("expected register containing function address");
4743 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
4744 if (!RegOpnd.isGPRAsmReg()) {
4745 reportParseError(RegOpnd.getStartLoc(), "invalid register");
4749 // If this is not the end of the statement, report an error.
4750 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4751 reportParseError("unexpected token, expected end of statement");
4755 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
4759 bool MipsAsmParser::parseDirectiveCPSetup() {
4760 MCAsmParser &Parser = getParser();
4763 bool SaveIsReg = true;
4765 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4766 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4767 if (ResTy == MatchOperand_NoMatch) {
4768 reportParseError("expected register containing function address");
4769 Parser.eatToEndOfStatement();
4773 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4774 if (!FuncRegOpnd.isGPRAsmReg()) {
4775 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
4776 Parser.eatToEndOfStatement();
4780 FuncReg = FuncRegOpnd.getGPR32Reg();
4783 if (!eatComma("unexpected token, expected comma"))
4786 ResTy = parseAnyRegister(TmpReg);
4787 if (ResTy == MatchOperand_NoMatch) {
4788 const AsmToken &Tok = Parser.getTok();
4789 if (Tok.is(AsmToken::Integer)) {
4790 Save = Tok.getIntVal();
4794 reportParseError("expected save register or stack offset");
4795 Parser.eatToEndOfStatement();
4799 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4800 if (!SaveOpnd.isGPRAsmReg()) {
4801 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
4802 Parser.eatToEndOfStatement();
4805 Save = SaveOpnd.getGPR32Reg();
4808 if (!eatComma("unexpected token, expected comma"))
4812 if (Parser.parseExpression(Expr)) {
4813 reportParseError("expected expression");
4817 if (Expr->getKind() != MCExpr::SymbolRef) {
4818 reportParseError("expected symbol");
4821 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
4823 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
4828 bool MipsAsmParser::parseDirectiveNaN() {
4829 MCAsmParser &Parser = getParser();
4830 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4831 const AsmToken &Tok = Parser.getTok();
4833 if (Tok.getString() == "2008") {
4835 getTargetStreamer().emitDirectiveNaN2008();
4837 } else if (Tok.getString() == "legacy") {
4839 getTargetStreamer().emitDirectiveNaNLegacy();
4843 // If we don't recognize the option passed to the .nan
4844 // directive (e.g. no option or unknown option), emit an error.
4845 reportParseError("invalid option in .nan directive");
4849 bool MipsAsmParser::parseDirectiveSet() {
4850 MCAsmParser &Parser = getParser();
4851 // Get the next token.
4852 const AsmToken &Tok = Parser.getTok();
4854 if (Tok.getString() == "noat") {
4855 return parseSetNoAtDirective();
4856 } else if (Tok.getString() == "at") {
4857 return parseSetAtDirective();
4858 } else if (Tok.getString() == "arch") {
4859 return parseSetArchDirective();
4860 } else if (Tok.getString() == "fp") {
4861 return parseSetFpDirective();
4862 } else if (Tok.getString() == "oddspreg") {
4863 return parseSetOddSPRegDirective();
4864 } else if (Tok.getString() == "nooddspreg") {
4865 return parseSetNoOddSPRegDirective();
4866 } else if (Tok.getString() == "pop") {
4867 return parseSetPopDirective();
4868 } else if (Tok.getString() == "push") {
4869 return parseSetPushDirective();
4870 } else if (Tok.getString() == "reorder") {
4871 return parseSetReorderDirective();
4872 } else if (Tok.getString() == "noreorder") {
4873 return parseSetNoReorderDirective();
4874 } else if (Tok.getString() == "macro") {
4875 return parseSetMacroDirective();
4876 } else if (Tok.getString() == "nomacro") {
4877 return parseSetNoMacroDirective();
4878 } else if (Tok.getString() == "mips16") {
4879 return parseSetMips16Directive();
4880 } else if (Tok.getString() == "nomips16") {
4881 return parseSetNoMips16Directive();
4882 } else if (Tok.getString() == "nomicromips") {
4883 getTargetStreamer().emitDirectiveSetNoMicroMips();
4884 Parser.eatToEndOfStatement();
4886 } else if (Tok.getString() == "micromips") {
4887 return parseSetFeature(Mips::FeatureMicroMips);
4888 } else if (Tok.getString() == "mips0") {
4889 return parseSetMips0Directive();
4890 } else if (Tok.getString() == "mips1") {
4891 return parseSetFeature(Mips::FeatureMips1);
4892 } else if (Tok.getString() == "mips2") {
4893 return parseSetFeature(Mips::FeatureMips2);
4894 } else if (Tok.getString() == "mips3") {
4895 return parseSetFeature(Mips::FeatureMips3);
4896 } else if (Tok.getString() == "mips4") {
4897 return parseSetFeature(Mips::FeatureMips4);
4898 } else if (Tok.getString() == "mips5") {
4899 return parseSetFeature(Mips::FeatureMips5);
4900 } else if (Tok.getString() == "mips32") {
4901 return parseSetFeature(Mips::FeatureMips32);
4902 } else if (Tok.getString() == "mips32r2") {
4903 return parseSetFeature(Mips::FeatureMips32r2);
4904 } else if (Tok.getString() == "mips32r3") {
4905 return parseSetFeature(Mips::FeatureMips32r3);
4906 } else if (Tok.getString() == "mips32r5") {
4907 return parseSetFeature(Mips::FeatureMips32r5);
4908 } else if (Tok.getString() == "mips32r6") {
4909 return parseSetFeature(Mips::FeatureMips32r6);
4910 } else if (Tok.getString() == "mips64") {
4911 return parseSetFeature(Mips::FeatureMips64);
4912 } else if (Tok.getString() == "mips64r2") {
4913 return parseSetFeature(Mips::FeatureMips64r2);
4914 } else if (Tok.getString() == "mips64r3") {
4915 return parseSetFeature(Mips::FeatureMips64r3);
4916 } else if (Tok.getString() == "mips64r5") {
4917 return parseSetFeature(Mips::FeatureMips64r5);
4918 } else if (Tok.getString() == "mips64r6") {
4919 return parseSetFeature(Mips::FeatureMips64r6);
4920 } else if (Tok.getString() == "dsp") {
4921 return parseSetFeature(Mips::FeatureDSP);
4922 } else if (Tok.getString() == "nodsp") {
4923 return parseSetNoDspDirective();
4924 } else if (Tok.getString() == "msa") {
4925 return parseSetMsaDirective();
4926 } else if (Tok.getString() == "nomsa") {
4927 return parseSetNoMsaDirective();
4928 } else if (Tok.getString() == "softfloat") {
4929 return parseSetSoftFloatDirective();
4930 } else if (Tok.getString() == "hardfloat") {
4931 return parseSetHardFloatDirective();
4933 // It is just an identifier, look for an assignment.
4934 parseSetAssignment();
4941 /// parseDataDirective
4942 /// ::= .word [ expression (, expression)* ]
4943 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
4944 MCAsmParser &Parser = getParser();
4945 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4947 const MCExpr *Value;
4948 if (getParser().parseExpression(Value))
4951 getParser().getStreamer().EmitValue(Value, Size);
4953 if (getLexer().is(AsmToken::EndOfStatement))
4956 if (getLexer().isNot(AsmToken::Comma))
4957 return Error(L, "unexpected token, expected comma");
4966 /// parseDirectiveGpWord
4967 /// ::= .gpword local_sym
4968 bool MipsAsmParser::parseDirectiveGpWord() {
4969 MCAsmParser &Parser = getParser();
4970 const MCExpr *Value;
4971 // EmitGPRel32Value requires an expression, so we are using base class
4972 // method to evaluate the expression.
4973 if (getParser().parseExpression(Value))
4975 getParser().getStreamer().EmitGPRel32Value(Value);
4977 if (getLexer().isNot(AsmToken::EndOfStatement))
4978 return Error(getLexer().getLoc(),
4979 "unexpected token, expected end of statement");
4980 Parser.Lex(); // Eat EndOfStatement token.
4984 /// parseDirectiveGpDWord
4985 /// ::= .gpdword local_sym
4986 bool MipsAsmParser::parseDirectiveGpDWord() {
4987 MCAsmParser &Parser = getParser();
4988 const MCExpr *Value;
4989 // EmitGPRel64Value requires an expression, so we are using base class
4990 // method to evaluate the expression.
4991 if (getParser().parseExpression(Value))
4993 getParser().getStreamer().EmitGPRel64Value(Value);
4995 if (getLexer().isNot(AsmToken::EndOfStatement))
4996 return Error(getLexer().getLoc(),
4997 "unexpected token, expected end of statement");
4998 Parser.Lex(); // Eat EndOfStatement token.
5002 bool MipsAsmParser::parseDirectiveOption() {
5003 MCAsmParser &Parser = getParser();
5004 // Get the option token.
5005 AsmToken Tok = Parser.getTok();
5006 // At the moment only identifiers are supported.
5007 if (Tok.isNot(AsmToken::Identifier)) {
5008 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
5009 Parser.eatToEndOfStatement();
5013 StringRef Option = Tok.getIdentifier();
5015 if (Option == "pic0") {
5016 // MipsAsmParser needs to know if the current PIC mode changes.
5017 IsPicEnabled = false;
5019 getTargetStreamer().emitDirectiveOptionPic0();
5021 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5022 Error(Parser.getTok().getLoc(),
5023 "unexpected token, expected end of statement");
5024 Parser.eatToEndOfStatement();
5029 if (Option == "pic2") {
5030 // MipsAsmParser needs to know if the current PIC mode changes.
5031 IsPicEnabled = true;
5033 getTargetStreamer().emitDirectiveOptionPic2();
5035 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5036 Error(Parser.getTok().getLoc(),
5037 "unexpected token, expected end of statement");
5038 Parser.eatToEndOfStatement();
5044 Warning(Parser.getTok().getLoc(),
5045 "unknown option, expected 'pic0' or 'pic2'");
5046 Parser.eatToEndOfStatement();
5050 /// parseInsnDirective
5052 bool MipsAsmParser::parseInsnDirective() {
5053 // If this is not the end of the statement, report an error.
5054 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5055 reportParseError("unexpected token, expected end of statement");
5059 // The actual label marking happens in
5060 // MipsELFStreamer::createPendingLabelRelocs().
5061 getTargetStreamer().emitDirectiveInsn();
5063 getParser().Lex(); // Eat EndOfStatement token.
5067 /// parseDirectiveModule
5068 /// ::= .module oddspreg
5069 /// ::= .module nooddspreg
5070 /// ::= .module fp=value
5071 /// ::= .module softfloat
5072 /// ::= .module hardfloat
5073 bool MipsAsmParser::parseDirectiveModule() {
5074 MCAsmParser &Parser = getParser();
5075 MCAsmLexer &Lexer = getLexer();
5076 SMLoc L = Lexer.getLoc();
5078 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5079 // TODO : get a better message.
5080 reportParseError(".module directive must appear before any code");
5085 if (Parser.parseIdentifier(Option)) {
5086 reportParseError("expected .module option identifier");
5090 if (Option == "oddspreg") {
5091 clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5093 // Synchronize the abiflags information with the FeatureBits information we
5095 getTargetStreamer().updateABIInfo(*this);
5097 // If printing assembly, use the recently updated abiflags information.
5098 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5099 // emitted at the end).
5100 getTargetStreamer().emitDirectiveModuleOddSPReg();
5102 // If this is not the end of the statement, report an error.
5103 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5104 reportParseError("unexpected token, expected end of statement");
5108 return false; // parseDirectiveModule has finished successfully.
5109 } else if (Option == "nooddspreg") {
5111 Error(L, "'.module nooddspreg' requires the O32 ABI");
5115 setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5117 // Synchronize the abiflags information with the FeatureBits information we
5119 getTargetStreamer().updateABIInfo(*this);
5121 // If printing assembly, use the recently updated abiflags information.
5122 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5123 // emitted at the end).
5124 getTargetStreamer().emitDirectiveModuleOddSPReg();
5126 // If this is not the end of the statement, report an error.
5127 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5128 reportParseError("unexpected token, expected end of statement");
5132 return false; // parseDirectiveModule has finished successfully.
5133 } else if (Option == "fp") {
5134 return parseDirectiveModuleFP();
5135 } else if (Option == "softfloat") {
5136 setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5138 // Synchronize the ABI Flags information with the FeatureBits information we
5140 getTargetStreamer().updateABIInfo(*this);
5142 // If printing assembly, use the recently updated ABI Flags information.
5143 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5145 getTargetStreamer().emitDirectiveModuleSoftFloat();
5147 // If this is not the end of the statement, report an error.
5148 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5149 reportParseError("unexpected token, expected end of statement");
5153 return false; // parseDirectiveModule has finished successfully.
5154 } else if (Option == "hardfloat") {
5155 clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5157 // Synchronize the ABI Flags information with the FeatureBits information we
5159 getTargetStreamer().updateABIInfo(*this);
5161 // If printing assembly, use the recently updated ABI Flags information.
5162 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5164 getTargetStreamer().emitDirectiveModuleHardFloat();
5166 // If this is not the end of the statement, report an error.
5167 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5168 reportParseError("unexpected token, expected end of statement");
5172 return false; // parseDirectiveModule has finished successfully.
5174 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5178 /// parseDirectiveModuleFP
5182 bool MipsAsmParser::parseDirectiveModuleFP() {
5183 MCAsmParser &Parser = getParser();
5184 MCAsmLexer &Lexer = getLexer();
5186 if (Lexer.isNot(AsmToken::Equal)) {
5187 reportParseError("unexpected token, expected equals sign '='");
5190 Parser.Lex(); // Eat '=' token.
5192 MipsABIFlagsSection::FpABIKind FpABI;
5193 if (!parseFpABIValue(FpABI, ".module"))
5196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5197 reportParseError("unexpected token, expected end of statement");
5201 // Synchronize the abiflags information with the FeatureBits information we
5203 getTargetStreamer().updateABIInfo(*this);
5205 // If printing assembly, use the recently updated abiflags information.
5206 // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5207 // emitted at the end).
5208 getTargetStreamer().emitDirectiveModuleFP();
5210 Parser.Lex(); // Consume the EndOfStatement.
5214 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5215 StringRef Directive) {
5216 MCAsmParser &Parser = getParser();
5217 MCAsmLexer &Lexer = getLexer();
5218 bool ModuleLevelOptions = Directive == ".module";
5220 if (Lexer.is(AsmToken::Identifier)) {
5221 StringRef Value = Parser.getTok().getString();
5224 if (Value != "xx") {
5225 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5230 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5234 FpABI = MipsABIFlagsSection::FpABIKind::XX;
5235 if (ModuleLevelOptions) {
5236 setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5237 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5239 setFeatureBits(Mips::FeatureFPXX, "fpxx");
5240 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5245 if (Lexer.is(AsmToken::Integer)) {
5246 unsigned Value = Parser.getTok().getIntVal();
5249 if (Value != 32 && Value != 64) {
5250 reportParseError("unsupported value, expected 'xx', '32' or '64'");
5256 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
5260 FpABI = MipsABIFlagsSection::FpABIKind::S32;
5261 if (ModuleLevelOptions) {
5262 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5263 clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5265 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5266 clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
5269 FpABI = MipsABIFlagsSection::FpABIKind::S64;
5270 if (ModuleLevelOptions) {
5271 clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
5272 setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
5274 clearFeatureBits(Mips::FeatureFPXX, "fpxx");
5275 setFeatureBits(Mips::FeatureFP64Bit, "fp64");
5285 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
5286 MCAsmParser &Parser = getParser();
5287 StringRef IDVal = DirectiveID.getString();
5289 if (IDVal == ".cpload")
5290 return parseDirectiveCpLoad(DirectiveID.getLoc());
5291 if (IDVal == ".dword") {
5292 parseDataDirective(8, DirectiveID.getLoc());
5295 if (IDVal == ".ent") {
5296 StringRef SymbolName;
5298 if (Parser.parseIdentifier(SymbolName)) {
5299 reportParseError("expected identifier after .ent");
5303 // There's an undocumented extension that allows an integer to
5304 // follow the name of the procedure which AFAICS is ignored by GAS.
5305 // Example: .ent foo,2
5306 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5307 if (getLexer().isNot(AsmToken::Comma)) {
5308 // Even though we accept this undocumented extension for compatibility
5309 // reasons, the additional integer argument does not actually change
5310 // the behaviour of the '.ent' directive, so we would like to discourage
5311 // its use. We do this by not referring to the extended version in
5312 // error messages which are not directly related to its use.
5313 reportParseError("unexpected token, expected end of statement");
5316 Parser.Lex(); // Eat the comma.
5317 const MCExpr *DummyNumber;
5318 int64_t DummyNumberVal;
5319 // If the user was explicitly trying to use the extended version,
5320 // we still give helpful extension-related error messages.
5321 if (Parser.parseExpression(DummyNumber)) {
5322 reportParseError("expected number after comma");
5325 if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
5326 reportParseError("expected an absolute expression after comma");
5331 // If this is not the end of the statement, report an error.
5332 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5333 reportParseError("unexpected token, expected end of statement");
5337 MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
5339 getTargetStreamer().emitDirectiveEnt(*Sym);
5344 if (IDVal == ".end") {
5345 StringRef SymbolName;
5347 if (Parser.parseIdentifier(SymbolName)) {
5348 reportParseError("expected identifier after .end");
5352 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5353 reportParseError("unexpected token, expected end of statement");
5357 if (CurrentFn == nullptr) {
5358 reportParseError(".end used without .ent");
5362 if ((SymbolName != CurrentFn->getName())) {
5363 reportParseError(".end symbol does not match .ent symbol");
5367 getTargetStreamer().emitDirectiveEnd(SymbolName);
5368 CurrentFn = nullptr;
5372 if (IDVal == ".frame") {
5373 // .frame $stack_reg, frame_size_in_bytes, $return_reg
5374 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
5375 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5376 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5377 reportParseError("expected stack register");
5381 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5382 if (!StackRegOpnd.isGPRAsmReg()) {
5383 reportParseError(StackRegOpnd.getStartLoc(),
5384 "expected general purpose register");
5387 unsigned StackReg = StackRegOpnd.getGPR32Reg();
5389 if (Parser.getTok().is(AsmToken::Comma))
5392 reportParseError("unexpected token, expected comma");
5396 // Parse the frame size.
5397 const MCExpr *FrameSize;
5398 int64_t FrameSizeVal;
5400 if (Parser.parseExpression(FrameSize)) {
5401 reportParseError("expected frame size value");
5405 if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
5406 reportParseError("frame size not an absolute expression");
5410 if (Parser.getTok().is(AsmToken::Comma))
5413 reportParseError("unexpected token, expected comma");
5417 // Parse the return register.
5419 ResTy = parseAnyRegister(TmpReg);
5420 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5421 reportParseError("expected return register");
5425 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5426 if (!ReturnRegOpnd.isGPRAsmReg()) {
5427 reportParseError(ReturnRegOpnd.getStartLoc(),
5428 "expected general purpose register");
5432 // If this is not the end of the statement, report an error.
5433 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5434 reportParseError("unexpected token, expected end of statement");
5438 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
5439 ReturnRegOpnd.getGPR32Reg());
5443 if (IDVal == ".set") {
5444 return parseDirectiveSet();
5447 if (IDVal == ".mask" || IDVal == ".fmask") {
5448 // .mask bitmask, frame_offset
5449 // bitmask: One bit for each register used.
5450 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
5451 // first register is expected to be saved.
5453 // .mask 0x80000000, -4
5454 // .fmask 0x80000000, -4
5457 // Parse the bitmask
5458 const MCExpr *BitMask;
5461 if (Parser.parseExpression(BitMask)) {
5462 reportParseError("expected bitmask value");
5466 if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
5467 reportParseError("bitmask not an absolute expression");
5471 if (Parser.getTok().is(AsmToken::Comma))
5474 reportParseError("unexpected token, expected comma");
5478 // Parse the frame_offset
5479 const MCExpr *FrameOffset;
5480 int64_t FrameOffsetVal;
5482 if (Parser.parseExpression(FrameOffset)) {
5483 reportParseError("expected frame offset value");
5487 if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
5488 reportParseError("frame offset not an absolute expression");
5492 // If this is not the end of the statement, report an error.
5493 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5494 reportParseError("unexpected token, expected end of statement");
5498 if (IDVal == ".mask")
5499 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
5501 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
5505 if (IDVal == ".nan")
5506 return parseDirectiveNaN();
5508 if (IDVal == ".gpword") {
5509 parseDirectiveGpWord();
5513 if (IDVal == ".gpdword") {
5514 parseDirectiveGpDWord();
5518 if (IDVal == ".word") {
5519 parseDataDirective(4, DirectiveID.getLoc());
5523 if (IDVal == ".option")
5524 return parseDirectiveOption();
5526 if (IDVal == ".abicalls") {
5527 getTargetStreamer().emitDirectiveAbiCalls();
5528 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
5529 Error(Parser.getTok().getLoc(),
5530 "unexpected token, expected end of statement");
5532 Parser.eatToEndOfStatement();
5537 if (IDVal == ".cpsetup")
5538 return parseDirectiveCPSetup();
5540 if (IDVal == ".module")
5541 return parseDirectiveModule();
5543 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
5544 return parseInternalDirectiveReallowModule();
5546 if (IDVal == ".insn")
5547 return parseInsnDirective();
5552 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
5553 // If this is not the end of the statement, report an error.
5554 if (getLexer().isNot(AsmToken::EndOfStatement)) {
5555 reportParseError("unexpected token, expected end of statement");
5559 getTargetStreamer().reallowModuleDirective();
5561 getParser().Lex(); // Eat EndOfStatement token.
5565 extern "C" void LLVMInitializeMipsAsmParser() {
5566 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
5567 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
5568 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
5569 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
5572 #define GET_REGISTER_MATCHER
5573 #define GET_MATCHER_IMPLEMENTATION
5574 #include "MipsGenAsmMatcher.inc"