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/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/TargetRegistry.h"
35 #define DEBUG_TYPE "mips-asm-parser"
42 class MipsAssemblerOptions {
44 MipsAssemblerOptions(uint64_t Features_) :
45 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
47 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
48 ATReg = Opts->getATRegNum();
49 Reorder = Opts->isReorder();
50 Macro = Opts->isMacro();
51 Features = Opts->getFeatures();
54 unsigned getATRegNum() const { return ATReg; }
55 bool setATReg(unsigned Reg);
57 bool isReorder() const { return Reorder; }
58 void setReorder() { Reorder = true; }
59 void setNoReorder() { Reorder = false; }
61 bool isMacro() const { return Macro; }
62 void setMacro() { Macro = true; }
63 void setNoMacro() { Macro = false; }
65 uint64_t getFeatures() const { return Features; }
66 void setFeatures(uint64_t Features_) { Features = Features_; }
68 // Set of features that are either architecture features or referenced
69 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
70 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
71 // The reason we need this mask is explained in the selectArch function.
72 // FIXME: Ideally we would like TableGen to generate this information.
73 static const uint64_t AllArchRelatedMask =
74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
79 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
80 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
91 class MipsAsmParser : public MCTargetAsmParser {
92 MipsTargetStreamer &getTargetStreamer() {
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
100 // nullptr, which indicates that no function is currently
101 // selected. This usually happens after an '.end func'
104 // Print a warning along with its fix-it message at the given range.
105 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
106 SMRange Range, bool ShowColors = true);
108 #define GET_ASSEMBLER_HEADER
109 #include "MipsGenAsmMatcher.inc"
111 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
113 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
114 OperandVector &Operands, MCStreamer &Out,
116 bool MatchingInlineAsm) override;
118 /// Parse a register as used in CFI directives
119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
121 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
123 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
125 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
126 SMLoc NameLoc, OperandVector &Operands) override;
128 bool ParseDirective(AsmToken DirectiveID) override;
130 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
132 MipsAsmParser::OperandMatchResultTy
133 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
134 StringRef Identifier, SMLoc S);
136 MipsAsmParser::OperandMatchResultTy
137 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
139 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
141 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy
150 parseRegisterPair (OperandVector &Operands);
152 MipsAsmParser::OperandMatchResultTy
153 parseRegisterList (OperandVector &Operands);
155 bool searchSymbolAlias(OperandVector &Operands);
157 bool parseOperand(OperandVector &, StringRef Mnemonic);
159 bool needsExpansion(MCInst &Inst);
161 // Expands assembly pseudo instructions.
162 // Returns false on success, true otherwise.
163 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
164 SmallVectorImpl<MCInst> &Instructions);
166 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
169 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
174 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
177 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
183 bool reportParseError(Twine ErrorMsg);
184 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
186 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
187 bool parseRelocOperand(const MCExpr *&Res);
189 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
191 bool isEvaluated(const MCExpr *Expr);
192 bool parseSetMips0Directive();
193 bool parseSetArchDirective();
194 bool parseSetFeature(uint64_t Feature);
195 bool parseDirectiveCpLoad(SMLoc Loc);
196 bool parseDirectiveCPSetup();
197 bool parseDirectiveNaN();
198 bool parseDirectiveSet();
199 bool parseDirectiveOption();
201 bool parseSetAtDirective();
202 bool parseSetNoAtDirective();
203 bool parseSetMacroDirective();
204 bool parseSetNoMacroDirective();
205 bool parseSetMsaDirective();
206 bool parseSetNoMsaDirective();
207 bool parseSetNoDspDirective();
208 bool parseSetReorderDirective();
209 bool parseSetNoReorderDirective();
210 bool parseSetMips16Directive();
211 bool parseSetNoMips16Directive();
212 bool parseSetFpDirective();
213 bool parseSetPopDirective();
214 bool parseSetPushDirective();
216 bool parseSetAssignment();
218 bool parseDataDirective(unsigned Size, SMLoc L);
219 bool parseDirectiveGpWord();
220 bool parseDirectiveGpDWord();
221 bool parseDirectiveModule();
222 bool parseDirectiveModuleFP();
223 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
224 StringRef Directive);
226 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
228 bool eatComma(StringRef ErrorStr);
230 int matchCPURegisterName(StringRef Symbol);
232 int matchHWRegsRegisterName(StringRef Symbol);
234 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
236 int matchFPURegisterName(StringRef Name);
238 int matchFCCRegisterName(StringRef Name);
240 int matchACRegisterName(StringRef Name);
242 int matchMSA128RegisterName(StringRef Name);
244 int matchMSA128CtrlRegisterName(StringRef Name);
246 unsigned getReg(int RC, int RegNo);
248 unsigned getGPR(int RegNo);
250 int getATReg(SMLoc Loc);
252 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
253 SmallVectorImpl<MCInst> &Instructions);
255 // Helper function that checks if the value of a vector index is within the
256 // boundaries of accepted values for each RegisterKind
257 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
258 bool validateMSAIndex(int Val, int RegKind);
260 // Selects a new architecture by updating the FeatureBits with the necessary
261 // info including implied dependencies.
262 // Internally, it clears all the feature bits related to *any* architecture
263 // and selects the new one using the ToggleFeature functionality of the
264 // MCSubtargetInfo object that handles implied dependencies. The reason we
265 // clear all the arch related bits manually is because ToggleFeature only
266 // clears the features that imply the feature being cleared and not the
267 // features implied by the feature being cleared. This is easier to see
269 // --------------------------------------------------
270 // | Feature | Implies |
271 // | -------------------------------------------------|
272 // | FeatureMips1 | None |
273 // | FeatureMips2 | FeatureMips1 |
274 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
275 // | FeatureMips4 | FeatureMips3 |
277 // --------------------------------------------------
279 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
280 // FeatureMipsGP64 | FeatureMips1)
281 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
282 void selectArch(StringRef ArchFeature) {
283 uint64_t FeatureBits = STI.getFeatureBits();
284 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
285 STI.setFeatureBits(FeatureBits);
286 setAvailableFeatures(
287 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
288 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
291 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
292 if (!(STI.getFeatureBits() & Feature)) {
293 setAvailableFeatures(
294 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
296 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
299 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
300 if (STI.getFeatureBits() & Feature) {
301 setAvailableFeatures(
302 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
304 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
308 enum MipsMatchResultTy {
309 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
310 #define GET_OPERAND_DIAGNOSTIC_TYPES
311 #include "MipsGenAsmMatcher.inc"
312 #undef GET_OPERAND_DIAGNOSTIC_TYPES
316 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
317 const MCInstrInfo &MII, const MCTargetOptions &Options)
318 : MCTargetAsmParser(), STI(sti) {
319 MCAsmParserExtension::Initialize(parser);
321 // Initialize the set of available features.
322 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
324 // Remember the initial assembler options. The user can not modify these.
325 AssemblerOptions.push_back(
326 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
328 // Create an assembler options environment for the user to modify.
329 AssemblerOptions.push_back(
330 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
332 getTargetStreamer().updateABIInfo(*this);
334 // Assert exactly one ABI was chosen.
335 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
336 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
337 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
338 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
340 if (!isABI_O32() && !useOddSPReg() != 0)
341 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
346 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
347 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
349 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
350 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
351 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
352 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
353 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
354 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
356 bool useOddSPReg() const {
357 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
360 bool inMicroMipsMode() const {
361 return STI.getFeatureBits() & Mips::FeatureMicroMips;
363 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
364 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
365 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
366 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
367 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
368 bool hasMips32() const {
369 return (STI.getFeatureBits() & Mips::FeatureMips32);
371 bool hasMips64() const {
372 return (STI.getFeatureBits() & Mips::FeatureMips64);
374 bool hasMips32r2() const {
375 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
377 bool hasMips64r2() const {
378 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
380 bool hasMips32r6() const {
381 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
383 bool hasMips64r6() const {
384 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
386 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
387 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
388 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
390 bool inMips16Mode() const {
391 return STI.getFeatureBits() & Mips::FeatureMips16;
393 // TODO: see how can we get this info.
394 bool abiUsesSoftFloat() const { return false; }
396 /// Warn if RegNo is the current assembler temporary.
397 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
403 /// MipsOperand - Instances of this class represent a parsed Mips machine
405 class MipsOperand : public MCParsedAsmOperand {
407 /// Broad categories of register classes
408 /// The exact class is finalized by the render method.
410 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
411 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
413 RegKind_FCC = 4, /// FCC
414 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
415 RegKind_MSACtrl = 16, /// MSA control registers
416 RegKind_COP2 = 32, /// COP2
417 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
419 RegKind_CCR = 128, /// CCR
420 RegKind_HWRegs = 256, /// HWRegs
421 RegKind_COP3 = 512, /// COP3
423 /// Potentially any (e.g. $1)
424 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
425 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
426 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
431 k_Immediate, /// An immediate (possibly involving symbol references)
432 k_Memory, /// Base + Offset Memory Address
433 k_PhysRegister, /// A physical register from the Mips namespace
434 k_RegisterIndex, /// A register index in one or more RegKind.
435 k_Token, /// A simple token
436 k_RegList, /// A physical register list
437 k_RegPair /// A pair of physical register
441 MipsOperand(KindTy K, MipsAsmParser &Parser)
442 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
445 /// For diagnostics, and checking the assembler temporary
446 MipsAsmParser &AsmParser;
454 unsigned Num; /// Register Number
458 unsigned Index; /// Index into the register class
459 RegKind Kind; /// Bitfield of the kinds it could possibly be
460 const MCRegisterInfo *RegInfo;
473 SmallVector<unsigned, 10> *List;
478 struct PhysRegOp PhysReg;
479 struct RegIdxOp RegIdx;
482 struct RegListOp RegList;
485 SMLoc StartLoc, EndLoc;
487 /// Internal constructor for register kinds
488 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
489 const MCRegisterInfo *RegInfo,
491 MipsAsmParser &Parser) {
492 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
493 Op->RegIdx.Index = Index;
494 Op->RegIdx.RegInfo = RegInfo;
495 Op->RegIdx.Kind = RegKind;
502 /// Coerce the register to GPR32 and return the real register for the current
504 unsigned getGPR32Reg() const {
505 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
506 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
507 unsigned ClassID = Mips::GPR32RegClassID;
508 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
511 /// Coerce the register to GPR32 and return the real register for the current
513 unsigned getGPRMM16Reg() const {
514 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
515 unsigned ClassID = Mips::GPR32RegClassID;
516 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
519 /// Coerce the register to GPR64 and return the real register for the current
521 unsigned getGPR64Reg() const {
522 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
523 unsigned ClassID = Mips::GPR64RegClassID;
524 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
528 /// Coerce the register to AFGR64 and return the real register for the current
530 unsigned getAFGR64Reg() const {
531 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
532 if (RegIdx.Index % 2 != 0)
533 AsmParser.Warning(StartLoc, "Float register should be even.");
534 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
535 .getRegister(RegIdx.Index / 2);
538 /// Coerce the register to FGR64 and return the real register for the current
540 unsigned getFGR64Reg() const {
541 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
542 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
543 .getRegister(RegIdx.Index);
546 /// Coerce the register to FGR32 and return the real register for the current
548 unsigned getFGR32Reg() const {
549 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
550 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
551 .getRegister(RegIdx.Index);
554 /// Coerce the register to FGRH32 and return the real register for the current
556 unsigned getFGRH32Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
558 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
559 .getRegister(RegIdx.Index);
562 /// Coerce the register to FCC and return the real register for the current
564 unsigned getFCCReg() const {
565 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
566 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
567 .getRegister(RegIdx.Index);
570 /// Coerce the register to MSA128 and return the real register for the current
572 unsigned getMSA128Reg() const {
573 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
574 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
576 unsigned ClassID = Mips::MSA128BRegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to MSACtrl and return the real register for the
582 unsigned getMSACtrlReg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
584 unsigned ClassID = Mips::MSACtrlRegClassID;
585 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
588 /// Coerce the register to COP2 and return the real register for the
590 unsigned getCOP2Reg() const {
591 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
592 unsigned ClassID = Mips::COP2RegClassID;
593 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
596 /// Coerce the register to COP3 and return the real register for the
598 unsigned getCOP3Reg() const {
599 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
600 unsigned ClassID = Mips::COP3RegClassID;
601 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
604 /// Coerce the register to ACC64DSP and return the real register for the
606 unsigned getACC64DSPReg() const {
607 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
608 unsigned ClassID = Mips::ACC64DSPRegClassID;
609 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
612 /// Coerce the register to HI32DSP and return the real register for the
614 unsigned getHI32DSPReg() const {
615 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
616 unsigned ClassID = Mips::HI32DSPRegClassID;
617 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
620 /// Coerce the register to LO32DSP and return the real register for the
622 unsigned getLO32DSPReg() const {
623 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
624 unsigned ClassID = Mips::LO32DSPRegClassID;
625 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
628 /// Coerce the register to CCR and return the real register for the
630 unsigned getCCRReg() const {
631 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
632 unsigned ClassID = Mips::CCRRegClassID;
633 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
636 /// Coerce the register to HWRegs and return the real register for the
638 unsigned getHWRegsReg() const {
639 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
640 unsigned ClassID = Mips::HWRegsRegClassID;
641 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
645 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
646 // Add as immediate when possible. Null MCExpr = 0.
648 Inst.addOperand(MCOperand::CreateImm(0));
649 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
650 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
652 Inst.addOperand(MCOperand::CreateExpr(Expr));
655 void addRegOperands(MCInst &Inst, unsigned N) const {
656 llvm_unreachable("Use a custom parser instead");
659 /// Render the operand to an MCInst as a GPR32
660 /// Asserts if the wrong number of operands are requested, or the operand
661 /// is not a k_RegisterIndex compatible with RegKind_GPR
662 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
663 assert(N == 1 && "Invalid number of operands!");
664 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
667 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
668 assert(N == 1 && "Invalid number of operands!");
669 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
672 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
673 assert(N == 1 && "Invalid number of operands!");
674 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
677 /// Render the operand to an MCInst as a GPR64
678 /// Asserts if the wrong number of operands are requested, or the operand
679 /// is not a k_RegisterIndex compatible with RegKind_GPR
680 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
681 assert(N == 1 && "Invalid number of operands!");
682 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
685 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 1 && "Invalid number of operands!");
687 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
690 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
691 assert(N == 1 && "Invalid number of operands!");
692 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
695 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
696 assert(N == 1 && "Invalid number of operands!");
697 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
698 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
699 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
700 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
704 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
705 assert(N == 1 && "Invalid number of operands!");
706 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
709 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
710 assert(N == 1 && "Invalid number of operands!");
711 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
714 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
715 assert(N == 1 && "Invalid number of operands!");
716 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
719 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
720 assert(N == 1 && "Invalid number of operands!");
721 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
724 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
725 assert(N == 1 && "Invalid number of operands!");
726 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
729 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
730 assert(N == 1 && "Invalid number of operands!");
731 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
734 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
735 assert(N == 1 && "Invalid number of operands!");
736 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
739 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
740 assert(N == 1 && "Invalid number of operands!");
741 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
744 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
749 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
754 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
759 void addImmOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 const MCExpr *Expr = getImm();
765 void addMemOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 2 && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
770 const MCExpr *Expr = getMemOff();
774 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 2 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
779 const MCExpr *Expr = getMemOff();
783 void addRegListOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
786 for (auto RegNo : getRegList())
787 Inst.addOperand(MCOperand::CreateReg(RegNo));
790 void addRegPairOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 2 && "Invalid number of operands!");
792 unsigned RegNo = getRegPair();
793 Inst.addOperand(MCOperand::CreateReg(RegNo++));
794 Inst.addOperand(MCOperand::CreateReg(RegNo));
797 bool isReg() const override {
798 // As a special case until we sort out the definition of div/divu, pretend
799 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
800 if (isGPRAsmReg() && RegIdx.Index == 0)
803 return Kind == k_PhysRegister;
805 bool isRegIdx() const { return Kind == k_RegisterIndex; }
806 bool isImm() const override { return Kind == k_Immediate; }
807 bool isConstantImm() const {
808 return isImm() && dyn_cast<MCConstantExpr>(getImm());
810 bool isToken() const override {
811 // Note: It's not possible to pretend that other operand kinds are tokens.
812 // The matcher emitter checks tokens first.
813 return Kind == k_Token;
815 bool isMem() const override { return Kind == k_Memory; }
816 bool isConstantMemOff() const {
817 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
819 template <unsigned Bits> bool isMemWithSimmOffset() const {
820 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
822 bool isMemWithGRPMM16Base() const {
823 return isMem() && getMemBase()->isMM16AsmReg();
825 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
826 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
827 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
829 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
830 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
831 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
832 && (getMemBase()->getGPR32Reg() == Mips::SP);
834 bool isRegList16() const {
838 int Size = RegList.List->size();
839 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
840 RegList.List->back() != Mips::RA)
843 int PrevReg = *RegList.List->begin();
844 for (int i = 1; i < Size - 1; i++) {
845 int Reg = (*(RegList.List))[i];
846 if ( Reg != PrevReg + 1)
853 bool isInvNum() const { return Kind == k_Immediate; }
854 bool isLSAImm() const {
855 if (!isConstantImm())
857 int64_t Val = getConstantImm();
858 return 1 <= Val && Val <= 4;
860 bool isRegList() const { return Kind == k_RegList; }
862 StringRef getToken() const {
863 assert(Kind == k_Token && "Invalid access!");
864 return StringRef(Tok.Data, Tok.Length);
866 bool isRegPair() const { return Kind == k_RegPair; }
868 unsigned getReg() const override {
869 // As a special case until we sort out the definition of div/divu, pretend
870 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
871 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
872 RegIdx.Kind & RegKind_GPR)
873 return getGPR32Reg(); // FIXME: GPR64 too
875 assert(Kind == k_PhysRegister && "Invalid access!");
879 const MCExpr *getImm() const {
880 assert((Kind == k_Immediate) && "Invalid access!");
884 int64_t getConstantImm() const {
885 const MCExpr *Val = getImm();
886 return static_cast<const MCConstantExpr *>(Val)->getValue();
889 MipsOperand *getMemBase() const {
890 assert((Kind == k_Memory) && "Invalid access!");
894 const MCExpr *getMemOff() const {
895 assert((Kind == k_Memory) && "Invalid access!");
899 int64_t getConstantMemOff() const {
900 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
903 const SmallVectorImpl<unsigned> &getRegList() const {
904 assert((Kind == k_RegList) && "Invalid access!");
905 return *(RegList.List);
908 unsigned getRegPair() const {
909 assert((Kind == k_RegPair) && "Invalid access!");
913 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
914 MipsAsmParser &Parser) {
915 auto Op = make_unique<MipsOperand>(k_Token, Parser);
916 Op->Tok.Data = Str.data();
917 Op->Tok.Length = Str.size();
923 /// Create a numeric register (e.g. $1). The exact register remains
924 /// unresolved until an instruction successfully matches
925 static std::unique_ptr<MipsOperand>
926 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
927 SMLoc E, MipsAsmParser &Parser) {
928 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
929 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
932 /// Create a register that is definitely a GPR.
933 /// This is typically only used for named registers such as $gp.
934 static std::unique_ptr<MipsOperand>
935 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
936 MipsAsmParser &Parser) {
937 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
940 /// Create a register that is definitely a FGR.
941 /// This is typically only used for named registers such as $f0.
942 static std::unique_ptr<MipsOperand>
943 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
944 MipsAsmParser &Parser) {
945 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
948 /// Create a register that is definitely a HWReg.
949 /// This is typically only used for named registers such as $hwr_cpunum.
950 static std::unique_ptr<MipsOperand>
951 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
952 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
953 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
956 /// Create a register that is definitely an FCC.
957 /// This is typically only used for named registers such as $fcc0.
958 static std::unique_ptr<MipsOperand>
959 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
960 MipsAsmParser &Parser) {
961 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
964 /// Create a register that is definitely an ACC.
965 /// This is typically only used for named registers such as $ac0.
966 static std::unique_ptr<MipsOperand>
967 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
968 MipsAsmParser &Parser) {
969 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
972 /// Create a register that is definitely an MSA128.
973 /// This is typically only used for named registers such as $w0.
974 static std::unique_ptr<MipsOperand>
975 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
976 SMLoc E, MipsAsmParser &Parser) {
977 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
980 /// Create a register that is definitely an MSACtrl.
981 /// This is typically only used for named registers such as $msaaccess.
982 static std::unique_ptr<MipsOperand>
983 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
984 SMLoc E, MipsAsmParser &Parser) {
985 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
988 static std::unique_ptr<MipsOperand>
989 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
990 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
997 static std::unique_ptr<MipsOperand>
998 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
999 SMLoc E, MipsAsmParser &Parser) {
1000 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1001 Op->Mem.Base = Base.release();
1008 static std::unique_ptr<MipsOperand>
1009 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1010 MipsAsmParser &Parser) {
1011 assert (Regs.size() > 0 && "Empty list not allowed");
1013 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1014 Op->RegList.List = new SmallVector<unsigned, 10>();
1015 for (auto Reg : Regs)
1016 Op->RegList.List->push_back(Reg);
1017 Op->StartLoc = StartLoc;
1018 Op->EndLoc = EndLoc;
1022 static std::unique_ptr<MipsOperand>
1023 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1024 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1025 Op->RegIdx.Index = RegNo;
1031 bool isGPRAsmReg() const {
1032 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1034 bool isMM16AsmReg() const {
1035 if (!(isRegIdx() && RegIdx.Kind))
1037 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1038 || RegIdx.Index == 16 || RegIdx.Index == 17);
1040 bool isMM16AsmRegZero() const {
1041 if (!(isRegIdx() && RegIdx.Kind))
1043 return (RegIdx.Index == 0 ||
1044 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1045 RegIdx.Index == 17);
1047 bool isFGRAsmReg() const {
1048 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1049 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1051 bool isHWRegsAsmReg() const {
1052 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1054 bool isCCRAsmReg() const {
1055 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1057 bool isFCCAsmReg() const {
1058 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1060 if (!AsmParser.hasEightFccRegisters())
1061 return RegIdx.Index == 0;
1062 return RegIdx.Index <= 7;
1064 bool isACCAsmReg() const {
1065 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1067 bool isCOP2AsmReg() const {
1068 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1070 bool isCOP3AsmReg() const {
1071 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1073 bool isMSA128AsmReg() const {
1074 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1076 bool isMSACtrlAsmReg() const {
1077 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1080 /// getStartLoc - Get the location of the first token of this operand.
1081 SMLoc getStartLoc() const override { return StartLoc; }
1082 /// getEndLoc - Get the location of the last token of this operand.
1083 SMLoc getEndLoc() const override { return EndLoc; }
1085 virtual ~MipsOperand() {
1093 delete RegList.List;
1094 case k_PhysRegister:
1095 case k_RegisterIndex:
1102 void print(raw_ostream &OS) const override {
1111 Mem.Base->print(OS);
1116 case k_PhysRegister:
1117 OS << "PhysReg<" << PhysReg.Num << ">";
1119 case k_RegisterIndex:
1120 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1127 for (auto Reg : (*RegList.List))
1132 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1136 }; // class MipsOperand
1140 extern const MCInstrDesc MipsInsts[];
1142 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1143 return MipsInsts[Opcode];
1146 static bool hasShortDelaySlot(unsigned Opcode) {
1149 case Mips::JALRS_MM:
1150 case Mips::JALRS16_MM:
1151 case Mips::BGEZALS_MM:
1152 case Mips::BLTZALS_MM:
1159 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1160 SmallVectorImpl<MCInst> &Instructions) {
1161 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1165 if (MCID.isBranch() || MCID.isCall()) {
1166 const unsigned Opcode = Inst.getOpcode();
1176 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1177 Offset = Inst.getOperand(2);
1178 if (!Offset.isImm())
1179 break; // We'll deal with this situation later on when applying fixups.
1180 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1181 return Error(IDLoc, "branch target out of range");
1182 if (OffsetToAlignment(Offset.getImm(),
1183 1LL << (inMicroMipsMode() ? 1 : 2)))
1184 return Error(IDLoc, "branch to misaligned address");
1198 case Mips::BGEZAL_MM:
1199 case Mips::BLTZAL_MM:
1202 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1203 Offset = Inst.getOperand(1);
1204 if (!Offset.isImm())
1205 break; // We'll deal with this situation later on when applying fixups.
1206 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1207 return Error(IDLoc, "branch target out of range");
1208 if (OffsetToAlignment(Offset.getImm(),
1209 1LL << (inMicroMipsMode() ? 1 : 2)))
1210 return Error(IDLoc, "branch to misaligned address");
1212 case Mips::BEQZ16_MM:
1213 case Mips::BNEZ16_MM:
1214 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1215 Offset = Inst.getOperand(1);
1216 if (!Offset.isImm())
1217 break; // We'll deal with this situation later on when applying fixups.
1218 if (!isIntN(8, Offset.getImm()))
1219 return Error(IDLoc, "branch target out of range");
1220 if (OffsetToAlignment(Offset.getImm(), 2LL))
1221 return Error(IDLoc, "branch to misaligned address");
1226 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1227 // We still accept it but it is a normal nop.
1228 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1229 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1230 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1234 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1235 // If this instruction has a delay slot and .set reorder is active,
1236 // emit a NOP after it.
1237 Instructions.push_back(Inst);
1239 if (hasShortDelaySlot(Inst.getOpcode())) {
1240 NopInst.setOpcode(Mips::MOVE16_MM);
1241 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1242 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1244 NopInst.setOpcode(Mips::SLL);
1245 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1246 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1247 NopInst.addOperand(MCOperand::CreateImm(0));
1249 Instructions.push_back(NopInst);
1253 if (MCID.mayLoad() || MCID.mayStore()) {
1254 // Check the offset of memory operand, if it is a symbol
1255 // reference or immediate we may have to expand instructions.
1256 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1257 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1258 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1259 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1260 MCOperand &Op = Inst.getOperand(i);
1262 int MemOffset = Op.getImm();
1263 if (MemOffset < -32768 || MemOffset > 32767) {
1264 // Offset can't exceed 16bit value.
1265 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1268 } else if (Op.isExpr()) {
1269 const MCExpr *Expr = Op.getExpr();
1270 if (Expr->getKind() == MCExpr::SymbolRef) {
1271 const MCSymbolRefExpr *SR =
1272 static_cast<const MCSymbolRefExpr *>(Expr);
1273 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1275 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1278 } else if (!isEvaluated(Expr)) {
1279 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1287 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1288 if (inMicroMipsMode()) {
1292 switch (Inst.getOpcode()) {
1295 case Mips::ADDIUS5_MM:
1296 Opnd = Inst.getOperand(2);
1298 return Error(IDLoc, "expected immediate operand kind");
1299 Imm = Opnd.getImm();
1300 if (Imm < -8 || Imm > 7)
1301 return Error(IDLoc, "immediate operand value out of range");
1303 case Mips::ADDIUSP_MM:
1304 Opnd = Inst.getOperand(0);
1306 return Error(IDLoc, "expected immediate operand kind");
1307 Imm = Opnd.getImm();
1308 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1310 return Error(IDLoc, "immediate operand value out of range");
1312 case Mips::SLL16_MM:
1313 case Mips::SRL16_MM:
1314 Opnd = Inst.getOperand(2);
1316 return Error(IDLoc, "expected immediate operand kind");
1317 Imm = Opnd.getImm();
1318 if (Imm < 1 || Imm > 8)
1319 return Error(IDLoc, "immediate operand value out of range");
1322 Opnd = Inst.getOperand(1);
1324 return Error(IDLoc, "expected immediate operand kind");
1325 Imm = Opnd.getImm();
1326 if (Imm < -1 || Imm > 126)
1327 return Error(IDLoc, "immediate operand value out of range");
1329 case Mips::ADDIUR2_MM:
1330 Opnd = Inst.getOperand(2);
1332 return Error(IDLoc, "expected immediate operand kind");
1333 Imm = Opnd.getImm();
1334 if (!(Imm == 1 || Imm == -1 ||
1335 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1336 return Error(IDLoc, "immediate operand value out of range");
1338 case Mips::ADDIUR1SP_MM:
1339 Opnd = Inst.getOperand(1);
1341 return Error(IDLoc, "expected immediate operand kind");
1342 Imm = Opnd.getImm();
1343 if (OffsetToAlignment(Imm, 4LL))
1344 return Error(IDLoc, "misaligned immediate operand value");
1345 if (Imm < 0 || Imm > 255)
1346 return Error(IDLoc, "immediate operand value out of range");
1348 case Mips::ANDI16_MM:
1349 Opnd = Inst.getOperand(2);
1351 return Error(IDLoc, "expected immediate operand kind");
1352 Imm = Opnd.getImm();
1353 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1354 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1355 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1356 return Error(IDLoc, "immediate operand value out of range");
1358 case Mips::LBU16_MM:
1359 Opnd = Inst.getOperand(2);
1361 return Error(IDLoc, "expected immediate operand kind");
1362 Imm = Opnd.getImm();
1363 if (Imm < -1 || Imm > 14)
1364 return Error(IDLoc, "immediate operand value out of range");
1367 Opnd = Inst.getOperand(2);
1369 return Error(IDLoc, "expected immediate operand kind");
1370 Imm = Opnd.getImm();
1371 if (Imm < 0 || Imm > 15)
1372 return Error(IDLoc, "immediate operand value out of range");
1374 case Mips::LHU16_MM:
1376 Opnd = Inst.getOperand(2);
1378 return Error(IDLoc, "expected immediate operand kind");
1379 Imm = Opnd.getImm();
1380 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1381 return Error(IDLoc, "immediate operand value out of range");
1385 Opnd = Inst.getOperand(2);
1387 return Error(IDLoc, "expected immediate operand kind");
1388 Imm = Opnd.getImm();
1389 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1390 return Error(IDLoc, "immediate operand value out of range");
1394 Opnd = Inst.getOperand(2);
1396 return Error(IDLoc, "expected immediate operand kind");
1397 Imm = Opnd.getImm();
1398 if (!isUInt<5>(Imm))
1399 return Error(IDLoc, "immediate operand value out of range");
1401 case Mips::ADDIUPC_MM:
1402 MCOperand Opnd = Inst.getOperand(1);
1404 return Error(IDLoc, "expected immediate operand kind");
1405 int Imm = Opnd.getImm();
1406 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1407 return Error(IDLoc, "immediate operand value out of range");
1412 if (needsExpansion(Inst))
1413 return expandInstruction(Inst, IDLoc, Instructions);
1415 Instructions.push_back(Inst);
1420 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1422 switch (Inst.getOpcode()) {
1423 case Mips::LoadImm32Reg:
1424 case Mips::LoadAddr32Imm:
1425 case Mips::LoadAddr32Reg:
1426 case Mips::LoadImm64Reg:
1427 case Mips::B_MM_Pseudo:
1434 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1435 SmallVectorImpl<MCInst> &Instructions) {
1436 switch (Inst.getOpcode()) {
1437 default: llvm_unreachable("unimplemented expansion");
1438 case Mips::LoadImm32Reg:
1439 return expandLoadImm(Inst, IDLoc, Instructions);
1440 case Mips::LoadImm64Reg:
1442 Error(IDLoc, "instruction requires a 64-bit architecture");
1445 return expandLoadImm(Inst, IDLoc, Instructions);
1446 case Mips::LoadAddr32Imm:
1447 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1448 case Mips::LoadAddr32Reg:
1449 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1450 case Mips::B_MM_Pseudo:
1451 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1456 template <bool PerformShift>
1457 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1458 SmallVectorImpl<MCInst> &Instructions) {
1461 tmpInst.setOpcode(Mips::DSLL);
1462 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1463 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1464 tmpInst.addOperand(MCOperand::CreateImm(16));
1465 tmpInst.setLoc(IDLoc);
1466 Instructions.push_back(tmpInst);
1469 tmpInst.setOpcode(Mips::ORi);
1470 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1471 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1472 tmpInst.addOperand(Operand);
1473 tmpInst.setLoc(IDLoc);
1474 Instructions.push_back(tmpInst);
1477 template <int Shift, bool PerformShift>
1478 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1479 SmallVectorImpl<MCInst> &Instructions) {
1480 createShiftOr<PerformShift>(
1481 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1482 IDLoc, Instructions);
1486 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1487 SmallVectorImpl<MCInst> &Instructions) {
1489 const MCOperand &ImmOp = Inst.getOperand(1);
1490 assert(ImmOp.isImm() && "expected immediate operand kind");
1491 const MCOperand &RegOp = Inst.getOperand(0);
1492 assert(RegOp.isReg() && "expected register operand kind");
1494 int64_t ImmValue = ImmOp.getImm();
1495 tmpInst.setLoc(IDLoc);
1496 // FIXME: gas has a special case for values that are 000...1111, which
1497 // becomes a li -1 and then a dsrl
1498 if (0 <= ImmValue && ImmValue <= 65535) {
1499 // For 0 <= j <= 65535.
1500 // li d,j => ori d,$zero,j
1501 tmpInst.setOpcode(Mips::ORi);
1502 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1503 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1504 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1505 Instructions.push_back(tmpInst);
1506 } else if (ImmValue < 0 && ImmValue >= -32768) {
1507 // For -32768 <= j < 0.
1508 // li d,j => addiu d,$zero,j
1509 tmpInst.setOpcode(Mips::ADDiu);
1510 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1511 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1512 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1513 Instructions.push_back(tmpInst);
1514 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1515 // For any value of j that is representable as a 32-bit integer, create
1517 // li d,j => lui d,hi16(j)
1519 tmpInst.setOpcode(Mips::LUi);
1520 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1521 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1522 Instructions.push_back(tmpInst);
1523 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1524 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1526 Error(IDLoc, "instruction requires a 64-bit architecture");
1530 // <------- lo32 ------>
1531 // <------- hi32 ------>
1532 // <- hi16 -> <- lo16 ->
1533 // _________________________________
1535 // | 16-bytes | 16-bytes | 16-bytes |
1536 // |__________|__________|__________|
1538 // For any value of j that is representable as a 48-bit integer, create
1540 // li d,j => lui d,hi16(j)
1541 // ori d,d,hi16(lo32(j))
1543 // ori d,d,lo16(lo32(j))
1544 tmpInst.setOpcode(Mips::LUi);
1545 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1547 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1548 Instructions.push_back(tmpInst);
1549 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1550 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1553 Error(IDLoc, "instruction requires a 64-bit architecture");
1557 // <------- hi32 ------> <------- lo32 ------>
1558 // <- hi16 -> <- lo16 ->
1559 // ___________________________________________
1561 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1562 // |__________|__________|__________|__________|
1564 // For any value of j that isn't representable as a 48-bit integer.
1565 // li d,j => lui d,hi16(j)
1566 // ori d,d,lo16(hi32(j))
1568 // ori d,d,hi16(lo32(j))
1570 // ori d,d,lo16(lo32(j))
1571 tmpInst.setOpcode(Mips::LUi);
1572 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1574 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1575 Instructions.push_back(tmpInst);
1576 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1577 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1578 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1584 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1585 SmallVectorImpl<MCInst> &Instructions) {
1587 const MCOperand &ImmOp = Inst.getOperand(2);
1588 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1589 "expected immediate operand kind");
1590 if (!ImmOp.isImm()) {
1591 expandLoadAddressSym(Inst, IDLoc, Instructions);
1594 const MCOperand &SrcRegOp = Inst.getOperand(1);
1595 assert(SrcRegOp.isReg() && "expected register operand kind");
1596 const MCOperand &DstRegOp = Inst.getOperand(0);
1597 assert(DstRegOp.isReg() && "expected register operand kind");
1598 int ImmValue = ImmOp.getImm();
1599 if (-32768 <= ImmValue && ImmValue <= 65535) {
1600 // For -32768 <= j <= 65535.
1601 // la d,j(s) => addiu d,s,j
1602 tmpInst.setOpcode(Mips::ADDiu);
1603 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1604 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1605 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1606 Instructions.push_back(tmpInst);
1608 // For any other value of j that is representable as a 32-bit integer.
1609 // la d,j(s) => lui d,hi16(j)
1612 tmpInst.setOpcode(Mips::LUi);
1613 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1614 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1615 Instructions.push_back(tmpInst);
1617 tmpInst.setOpcode(Mips::ORi);
1618 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1619 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1620 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1621 Instructions.push_back(tmpInst);
1623 tmpInst.setOpcode(Mips::ADDu);
1624 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1625 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1626 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1627 Instructions.push_back(tmpInst);
1633 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1634 SmallVectorImpl<MCInst> &Instructions) {
1636 const MCOperand &ImmOp = Inst.getOperand(1);
1637 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1638 "expected immediate operand kind");
1639 if (!ImmOp.isImm()) {
1640 expandLoadAddressSym(Inst, IDLoc, Instructions);
1643 const MCOperand &RegOp = Inst.getOperand(0);
1644 assert(RegOp.isReg() && "expected register operand kind");
1645 int ImmValue = ImmOp.getImm();
1646 if (-32768 <= ImmValue && ImmValue <= 65535) {
1647 // For -32768 <= j <= 65535.
1648 // la d,j => addiu d,$zero,j
1649 tmpInst.setOpcode(Mips::ADDiu);
1650 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1651 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1652 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1653 Instructions.push_back(tmpInst);
1655 // For any other value of j that is representable as a 32-bit integer.
1656 // la d,j => lui d,hi16(j)
1658 tmpInst.setOpcode(Mips::LUi);
1659 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1660 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1661 Instructions.push_back(tmpInst);
1663 tmpInst.setOpcode(Mips::ORi);
1664 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1665 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1666 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1667 Instructions.push_back(tmpInst);
1673 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1674 SmallVectorImpl<MCInst> &Instructions) {
1675 // FIXME: If we do have a valid at register to use, we should generate a
1676 // slightly shorter sequence here.
1678 int ExprOperandNo = 1;
1679 // Sometimes the assembly parser will get the immediate expression as
1680 // a $zero + an immediate.
1681 if (Inst.getNumOperands() == 3) {
1682 assert(Inst.getOperand(1).getReg() ==
1683 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1686 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1687 assert(SymOp.isExpr() && "expected symbol operand kind");
1688 const MCOperand &RegOp = Inst.getOperand(0);
1689 unsigned RegNo = RegOp.getReg();
1690 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1691 const MCSymbolRefExpr *HiExpr =
1692 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1693 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1694 const MCSymbolRefExpr *LoExpr =
1695 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1696 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1698 // If it's a 64-bit architecture, expand to:
1699 // la d,sym => lui d,highest(sym)
1700 // ori d,d,higher(sym)
1702 // ori d,d,hi16(sym)
1704 // ori d,d,lo16(sym)
1705 const MCSymbolRefExpr *HighestExpr =
1706 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1707 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1708 const MCSymbolRefExpr *HigherExpr =
1709 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1710 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1712 tmpInst.setOpcode(Mips::LUi);
1713 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1714 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1715 Instructions.push_back(tmpInst);
1717 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1719 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1721 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1724 // Otherwise, expand to:
1725 // la d,sym => lui d,hi16(sym)
1726 // ori d,d,lo16(sym)
1727 tmpInst.setOpcode(Mips::LUi);
1728 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1729 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1730 Instructions.push_back(tmpInst);
1732 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1737 bool MipsAsmParser::expandUncondBranchMMPseudo(
1738 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1739 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1740 "unexpected number of operands");
1742 MCOperand Offset = Inst.getOperand(0);
1743 if (Offset.isExpr()) {
1745 Inst.setOpcode(Mips::BEQ_MM);
1746 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1747 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1748 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1750 assert(Offset.isImm() && "expected immediate operand kind");
1751 if (isIntN(11, Offset.getImm())) {
1752 // If offset fits into 11 bits then this instruction becomes microMIPS
1753 // 16-bit unconditional branch instruction.
1754 Inst.setOpcode(Mips::B16_MM);
1756 if (!isIntN(17, Offset.getImm()))
1757 Error(IDLoc, "branch target out of range");
1758 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1759 Error(IDLoc, "branch to misaligned address");
1761 Inst.setOpcode(Mips::BEQ_MM);
1762 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1763 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1764 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1767 Instructions.push_back(Inst);
1769 if (AssemblerOptions.back()->isReorder()) {
1770 // If .set reorder is active, emit a NOP after the branch instruction.
1772 NopInst.setOpcode(Mips::MOVE16_MM);
1773 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1774 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1775 Instructions.push_back(NopInst);
1780 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1781 SmallVectorImpl<MCInst> &Instructions,
1782 bool isLoad, bool isImmOpnd) {
1783 const MCSymbolRefExpr *SR;
1785 unsigned ImmOffset, HiOffset, LoOffset;
1786 const MCExpr *ExprOffset;
1788 // 1st operand is either the source or destination register.
1789 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1790 unsigned RegOpNum = Inst.getOperand(0).getReg();
1791 // 2nd operand is the base register.
1792 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1793 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1794 // 3rd operand is either an immediate or expression.
1796 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1797 ImmOffset = Inst.getOperand(2).getImm();
1798 LoOffset = ImmOffset & 0x0000ffff;
1799 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1800 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1801 if (LoOffset & 0x8000)
1804 ExprOffset = Inst.getOperand(2).getExpr();
1805 // All instructions will have the same location.
1806 TempInst.setLoc(IDLoc);
1807 // These are some of the types of expansions we perform here:
1808 // 1) lw $8, sym => lui $8, %hi(sym)
1809 // lw $8, %lo(sym)($8)
1810 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1812 // lw $8, %lo(offset)($9)
1813 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1815 // lw $8, %lo(offset)($at)
1816 // 4) sw $8, sym => lui $at, %hi(sym)
1817 // sw $8, %lo(sym)($at)
1818 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1820 // sw $8, %lo(offset)($at)
1821 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1822 // ldc1 $f0, %lo(sym)($at)
1824 // For load instructions we can use the destination register as a temporary
1825 // if base and dst are different (examples 1 and 2) and if the base register
1826 // is general purpose otherwise we must use $at (example 6) and error if it's
1827 // not available. For stores we must use $at (examples 4 and 5) because we
1828 // must not clobber the source register setting up the offset.
1829 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1830 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1831 unsigned RegClassIDOp0 =
1832 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1833 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1834 (RegClassIDOp0 == Mips::GPR64RegClassID);
1835 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1836 TmpRegNum = RegOpNum;
1838 int AT = getATReg(IDLoc);
1839 // At this point we need AT to perform the expansions and we exit if it is
1844 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1847 TempInst.setOpcode(Mips::LUi);
1848 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1850 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1852 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1853 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1854 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1855 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1857 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1859 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1860 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1863 // Add the instruction to the list.
1864 Instructions.push_back(TempInst);
1865 // Prepare TempInst for next instruction.
1867 // Add temp register to base.
1868 TempInst.setOpcode(Mips::ADDu);
1869 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1870 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1871 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1872 Instructions.push_back(TempInst);
1874 // And finally, create original instruction with low part
1875 // of offset and new base.
1876 TempInst.setOpcode(Inst.getOpcode());
1877 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1878 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1880 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1882 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1883 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1884 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1886 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1888 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1889 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1892 Instructions.push_back(TempInst);
1896 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1897 // As described by the Mips32r2 spec, the registers Rd and Rs for
1898 // jalr.hb must be different.
1899 unsigned Opcode = Inst.getOpcode();
1901 if (Opcode == Mips::JALR_HB &&
1902 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1903 return Match_RequiresDifferentSrcAndDst;
1905 return Match_Success;
1908 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1909 OperandVector &Operands,
1911 uint64_t &ErrorInfo,
1912 bool MatchingInlineAsm) {
1915 SmallVector<MCInst, 8> Instructions;
1916 unsigned MatchResult =
1917 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1919 switch (MatchResult) {
1920 case Match_Success: {
1921 if (processInstruction(Inst, IDLoc, Instructions))
1923 for (unsigned i = 0; i < Instructions.size(); i++)
1924 Out.EmitInstruction(Instructions[i], STI);
1927 case Match_MissingFeature:
1928 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1930 case Match_InvalidOperand: {
1931 SMLoc ErrorLoc = IDLoc;
1932 if (ErrorInfo != ~0ULL) {
1933 if (ErrorInfo >= Operands.size())
1934 return Error(IDLoc, "too few operands for instruction");
1936 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1937 if (ErrorLoc == SMLoc())
1941 return Error(ErrorLoc, "invalid operand for instruction");
1943 case Match_MnemonicFail:
1944 return Error(IDLoc, "invalid instruction");
1945 case Match_RequiresDifferentSrcAndDst:
1946 return Error(IDLoc, "source and destination must be different");
1949 llvm_unreachable("Implement any new match types added!");
1952 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1953 if ((RegIndex != 0) &&
1954 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1956 Warning(Loc, "used $at without \".set noat\"");
1958 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1959 Twine(RegIndex) + "\"");
1964 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1965 SMRange Range, bool ShowColors) {
1966 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1967 Range, SMFixIt(Range, FixMsg),
1971 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1974 CC = StringSwitch<unsigned>(Name)
2010 if (!(isABI_N32() || isABI_N64()))
2013 if (12 <= CC && CC <= 15) {
2014 // Name is one of t4-t7
2015 AsmToken RegTok = getLexer().peekTok();
2016 SMRange RegRange = RegTok.getLocRange();
2018 StringRef FixedName = StringSwitch<StringRef>(Name)
2024 assert(FixedName != "" && "Register name is not one of t4-t7.");
2026 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2027 "Did you mean $" + FixedName + "?", RegRange);
2030 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2031 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2032 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2033 if (8 <= CC && CC <= 11)
2037 CC = StringSwitch<unsigned>(Name)
2049 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2052 CC = StringSwitch<unsigned>(Name)
2053 .Case("hwr_cpunum", 0)
2054 .Case("hwr_synci_step", 1)
2056 .Case("hwr_ccres", 3)
2057 .Case("hwr_ulr", 29)
2063 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2065 if (Name[0] == 'f') {
2066 StringRef NumString = Name.substr(1);
2068 if (NumString.getAsInteger(10, IntVal))
2069 return -1; // This is not an integer.
2070 if (IntVal > 31) // Maximum index for fpu register.
2077 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2079 if (Name.startswith("fcc")) {
2080 StringRef NumString = Name.substr(3);
2082 if (NumString.getAsInteger(10, IntVal))
2083 return -1; // This is not an integer.
2084 if (IntVal > 7) // There are only 8 fcc registers.
2091 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2093 if (Name.startswith("ac")) {
2094 StringRef NumString = Name.substr(2);
2096 if (NumString.getAsInteger(10, IntVal))
2097 return -1; // This is not an integer.
2098 if (IntVal > 3) // There are only 3 acc registers.
2105 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2108 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2117 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2120 CC = StringSwitch<unsigned>(Name)
2123 .Case("msaaccess", 2)
2125 .Case("msamodify", 4)
2126 .Case("msarequest", 5)
2128 .Case("msaunmap", 7)
2134 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2142 int MipsAsmParser::getATReg(SMLoc Loc) {
2143 int AT = AssemblerOptions.back()->getATRegNum();
2145 reportParseError(Loc,
2146 "pseudo-instruction requires $at, which is not available");
2150 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2151 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2154 unsigned MipsAsmParser::getGPR(int RegNo) {
2155 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2159 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2161 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2164 return getReg(RegClass, RegNum);
2167 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2168 MCAsmParser &Parser = getParser();
2169 DEBUG(dbgs() << "parseOperand\n");
2171 // Check if the current operand has a custom associated parser, if so, try to
2172 // custom parse the operand, or fallback to the general approach.
2173 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2174 if (ResTy == MatchOperand_Success)
2176 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2177 // there was a match, but an error occurred, in which case, just return that
2178 // the operand parsing failed.
2179 if (ResTy == MatchOperand_ParseFail)
2182 DEBUG(dbgs() << ".. Generic Parser\n");
2184 switch (getLexer().getKind()) {
2186 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2188 case AsmToken::Dollar: {
2189 // Parse the register.
2190 SMLoc S = Parser.getTok().getLoc();
2192 // Almost all registers have been parsed by custom parsers. There is only
2193 // one exception to this. $zero (and it's alias $0) will reach this point
2194 // for div, divu, and similar instructions because it is not an operand
2195 // to the instruction definition but an explicit register. Special case
2196 // this situation for now.
2197 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2200 // Maybe it is a symbol reference.
2201 StringRef Identifier;
2202 if (Parser.parseIdentifier(Identifier))
2205 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2206 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2207 // Otherwise create a symbol reference.
2209 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2211 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2214 // Else drop to expression parsing.
2215 case AsmToken::LParen:
2216 case AsmToken::Minus:
2217 case AsmToken::Plus:
2218 case AsmToken::Integer:
2219 case AsmToken::Tilde:
2220 case AsmToken::String: {
2221 DEBUG(dbgs() << ".. generic integer\n");
2222 OperandMatchResultTy ResTy = parseImm(Operands);
2223 return ResTy != MatchOperand_Success;
2225 case AsmToken::Percent: {
2226 // It is a symbol reference or constant expression.
2227 const MCExpr *IdVal;
2228 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2229 if (parseRelocOperand(IdVal))
2232 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2234 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2236 } // case AsmToken::Percent
2237 } // switch(getLexer().getKind())
2241 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2242 StringRef RelocStr) {
2244 // Check the type of the expression.
2245 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2246 // It's a constant, evaluate reloc value.
2248 switch (getVariantKind(RelocStr)) {
2249 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2250 // Get the 1st 16-bits.
2251 Val = MCE->getValue() & 0xffff;
2253 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2254 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2255 // 16 bits being negative.
2256 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2258 case MCSymbolRefExpr::VK_Mips_HIGHER:
2259 // Get the 3rd 16-bits.
2260 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2262 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2263 // Get the 4th 16-bits.
2264 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2267 report_fatal_error("unsupported reloc value");
2269 return MCConstantExpr::Create(Val, getContext());
2272 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2273 // It's a symbol, create a symbolic expression from the symbol.
2274 StringRef Symbol = MSRE->getSymbol().getName();
2275 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2276 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2280 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2281 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2283 // Try to create target expression.
2284 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2285 return MipsMCExpr::Create(VK, Expr, getContext());
2287 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2288 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2289 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2293 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2294 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2295 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2298 // Just return the original expression.
2302 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2304 switch (Expr->getKind()) {
2305 case MCExpr::Constant:
2307 case MCExpr::SymbolRef:
2308 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2309 case MCExpr::Binary:
2310 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2311 if (!isEvaluated(BE->getLHS()))
2313 return isEvaluated(BE->getRHS());
2316 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2317 case MCExpr::Target:
2323 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2324 MCAsmParser &Parser = getParser();
2325 Parser.Lex(); // Eat the % token.
2326 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2327 if (Tok.isNot(AsmToken::Identifier))
2330 std::string Str = Tok.getIdentifier().str();
2332 Parser.Lex(); // Eat the identifier.
2333 // Now make an expression from the rest of the operand.
2334 const MCExpr *IdVal;
2337 if (getLexer().getKind() == AsmToken::LParen) {
2339 Parser.Lex(); // Eat the '(' token.
2340 if (getLexer().getKind() == AsmToken::Percent) {
2341 Parser.Lex(); // Eat the % token.
2342 const AsmToken &nextTok = Parser.getTok();
2343 if (nextTok.isNot(AsmToken::Identifier))
2346 Str += nextTok.getIdentifier();
2347 Parser.Lex(); // Eat the identifier.
2348 if (getLexer().getKind() != AsmToken::LParen)
2353 if (getParser().parseParenExpression(IdVal, EndLoc))
2356 while (getLexer().getKind() == AsmToken::RParen)
2357 Parser.Lex(); // Eat the ')' token.
2360 return true; // Parenthesis must follow the relocation operand.
2362 Res = evaluateRelocExpr(IdVal, Str);
2366 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2368 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2369 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2370 if (ResTy == MatchOperand_Success) {
2371 assert(Operands.size() == 1);
2372 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2373 StartLoc = Operand.getStartLoc();
2374 EndLoc = Operand.getEndLoc();
2376 // AFAIK, we only support numeric registers and named GPR's in CFI
2378 // Don't worry about eating tokens before failing. Using an unrecognised
2379 // register is a parse error.
2380 if (Operand.isGPRAsmReg()) {
2381 // Resolve to GPR32 or GPR64 appropriately.
2382 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2385 return (RegNo == (unsigned)-1);
2388 assert(Operands.size() == 0);
2389 return (RegNo == (unsigned)-1);
2392 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2393 MCAsmParser &Parser = getParser();
2397 while (getLexer().getKind() == AsmToken::LParen)
2400 switch (getLexer().getKind()) {
2403 case AsmToken::Identifier:
2404 case AsmToken::LParen:
2405 case AsmToken::Integer:
2406 case AsmToken::Minus:
2407 case AsmToken::Plus:
2409 Result = getParser().parseParenExpression(Res, S);
2411 Result = (getParser().parseExpression(Res));
2412 while (getLexer().getKind() == AsmToken::RParen)
2415 case AsmToken::Percent:
2416 Result = parseRelocOperand(Res);
2421 MipsAsmParser::OperandMatchResultTy
2422 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2423 MCAsmParser &Parser = getParser();
2424 DEBUG(dbgs() << "parseMemOperand\n");
2425 const MCExpr *IdVal = nullptr;
2427 bool isParenExpr = false;
2428 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2429 // First operand is the offset.
2430 S = Parser.getTok().getLoc();
2432 if (getLexer().getKind() == AsmToken::LParen) {
2437 if (getLexer().getKind() != AsmToken::Dollar) {
2438 if (parseMemOffset(IdVal, isParenExpr))
2439 return MatchOperand_ParseFail;
2441 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2442 if (Tok.isNot(AsmToken::LParen)) {
2443 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2444 if (Mnemonic.getToken() == "la") {
2446 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2447 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2448 return MatchOperand_Success;
2450 if (Tok.is(AsmToken::EndOfStatement)) {
2452 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2454 // Zero register assumed, add a memory operand with ZERO as its base.
2455 // "Base" will be managed by k_Memory.
2456 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2459 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2460 return MatchOperand_Success;
2462 Error(Parser.getTok().getLoc(), "'(' expected");
2463 return MatchOperand_ParseFail;
2466 Parser.Lex(); // Eat the '(' token.
2469 Res = parseAnyRegister(Operands);
2470 if (Res != MatchOperand_Success)
2473 if (Parser.getTok().isNot(AsmToken::RParen)) {
2474 Error(Parser.getTok().getLoc(), "')' expected");
2475 return MatchOperand_ParseFail;
2478 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2480 Parser.Lex(); // Eat the ')' token.
2483 IdVal = MCConstantExpr::Create(0, getContext());
2485 // Replace the register operand with the memory operand.
2486 std::unique_ptr<MipsOperand> op(
2487 static_cast<MipsOperand *>(Operands.back().release()));
2488 // Remove the register from the operands.
2489 // "op" will be managed by k_Memory.
2490 Operands.pop_back();
2491 // Add the memory operand.
2492 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2494 if (IdVal->EvaluateAsAbsolute(Imm))
2495 IdVal = MCConstantExpr::Create(Imm, getContext());
2496 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2497 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2501 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2502 return MatchOperand_Success;
2505 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2506 MCAsmParser &Parser = getParser();
2507 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2509 SMLoc S = Parser.getTok().getLoc();
2511 if (Sym->isVariable())
2512 Expr = Sym->getVariableValue();
2515 if (Expr->getKind() == MCExpr::SymbolRef) {
2516 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2517 StringRef DefSymbol = Ref->getSymbol().getName();
2518 if (DefSymbol.startswith("$")) {
2519 OperandMatchResultTy ResTy =
2520 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2521 if (ResTy == MatchOperand_Success) {
2524 } else if (ResTy == MatchOperand_ParseFail)
2525 llvm_unreachable("Should never ParseFail");
2528 } else if (Expr->getKind() == MCExpr::Constant) {
2530 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2532 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2539 MipsAsmParser::OperandMatchResultTy
2540 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2541 StringRef Identifier,
2543 int Index = matchCPURegisterName(Identifier);
2545 Operands.push_back(MipsOperand::createGPRReg(
2546 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2547 return MatchOperand_Success;
2550 Index = matchHWRegsRegisterName(Identifier);
2552 Operands.push_back(MipsOperand::createHWRegsReg(
2553 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2554 return MatchOperand_Success;
2557 Index = matchFPURegisterName(Identifier);
2559 Operands.push_back(MipsOperand::createFGRReg(
2560 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2561 return MatchOperand_Success;
2564 Index = matchFCCRegisterName(Identifier);
2566 Operands.push_back(MipsOperand::createFCCReg(
2567 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2568 return MatchOperand_Success;
2571 Index = matchACRegisterName(Identifier);
2573 Operands.push_back(MipsOperand::createACCReg(
2574 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2575 return MatchOperand_Success;
2578 Index = matchMSA128RegisterName(Identifier);
2580 Operands.push_back(MipsOperand::createMSA128Reg(
2581 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2582 return MatchOperand_Success;
2585 Index = matchMSA128CtrlRegisterName(Identifier);
2587 Operands.push_back(MipsOperand::createMSACtrlReg(
2588 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2589 return MatchOperand_Success;
2592 return MatchOperand_NoMatch;
2595 MipsAsmParser::OperandMatchResultTy
2596 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2597 MCAsmParser &Parser = getParser();
2598 auto Token = Parser.getLexer().peekTok(false);
2600 if (Token.is(AsmToken::Identifier)) {
2601 DEBUG(dbgs() << ".. identifier\n");
2602 StringRef Identifier = Token.getIdentifier();
2603 OperandMatchResultTy ResTy =
2604 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2606 } else if (Token.is(AsmToken::Integer)) {
2607 DEBUG(dbgs() << ".. integer\n");
2608 Operands.push_back(MipsOperand::createNumericReg(
2609 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2611 return MatchOperand_Success;
2614 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2616 return MatchOperand_NoMatch;
2619 MipsAsmParser::OperandMatchResultTy
2620 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2621 MCAsmParser &Parser = getParser();
2622 DEBUG(dbgs() << "parseAnyRegister\n");
2624 auto Token = Parser.getTok();
2626 SMLoc S = Token.getLoc();
2628 if (Token.isNot(AsmToken::Dollar)) {
2629 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2630 if (Token.is(AsmToken::Identifier)) {
2631 if (searchSymbolAlias(Operands))
2632 return MatchOperand_Success;
2634 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2635 return MatchOperand_NoMatch;
2637 DEBUG(dbgs() << ".. $\n");
2639 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2640 if (ResTy == MatchOperand_Success) {
2642 Parser.Lex(); // identifier
2647 MipsAsmParser::OperandMatchResultTy
2648 MipsAsmParser::parseImm(OperandVector &Operands) {
2649 MCAsmParser &Parser = getParser();
2650 switch (getLexer().getKind()) {
2652 return MatchOperand_NoMatch;
2653 case AsmToken::LParen:
2654 case AsmToken::Minus:
2655 case AsmToken::Plus:
2656 case AsmToken::Integer:
2657 case AsmToken::Tilde:
2658 case AsmToken::String:
2662 const MCExpr *IdVal;
2663 SMLoc S = Parser.getTok().getLoc();
2664 if (getParser().parseExpression(IdVal))
2665 return MatchOperand_ParseFail;
2667 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2668 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2669 return MatchOperand_Success;
2672 MipsAsmParser::OperandMatchResultTy
2673 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2674 MCAsmParser &Parser = getParser();
2675 DEBUG(dbgs() << "parseJumpTarget\n");
2677 SMLoc S = getLexer().getLoc();
2679 // Integers and expressions are acceptable
2680 OperandMatchResultTy ResTy = parseImm(Operands);
2681 if (ResTy != MatchOperand_NoMatch)
2684 // Registers are a valid target and have priority over symbols.
2685 ResTy = parseAnyRegister(Operands);
2686 if (ResTy != MatchOperand_NoMatch)
2689 const MCExpr *Expr = nullptr;
2690 if (Parser.parseExpression(Expr)) {
2691 // We have no way of knowing if a symbol was consumed so we must ParseFail
2692 return MatchOperand_ParseFail;
2695 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2696 return MatchOperand_Success;
2699 MipsAsmParser::OperandMatchResultTy
2700 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2701 MCAsmParser &Parser = getParser();
2702 const MCExpr *IdVal;
2703 // If the first token is '$' we may have register operand.
2704 if (Parser.getTok().is(AsmToken::Dollar))
2705 return MatchOperand_NoMatch;
2706 SMLoc S = Parser.getTok().getLoc();
2707 if (getParser().parseExpression(IdVal))
2708 return MatchOperand_ParseFail;
2709 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2710 assert(MCE && "Unexpected MCExpr type.");
2711 int64_t Val = MCE->getValue();
2712 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2713 Operands.push_back(MipsOperand::CreateImm(
2714 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2715 return MatchOperand_Success;
2718 MipsAsmParser::OperandMatchResultTy
2719 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2720 MCAsmParser &Parser = getParser();
2721 switch (getLexer().getKind()) {
2723 return MatchOperand_NoMatch;
2724 case AsmToken::LParen:
2725 case AsmToken::Plus:
2726 case AsmToken::Minus:
2727 case AsmToken::Integer:
2732 SMLoc S = Parser.getTok().getLoc();
2734 if (getParser().parseExpression(Expr))
2735 return MatchOperand_ParseFail;
2738 if (!Expr->EvaluateAsAbsolute(Val)) {
2739 Error(S, "expected immediate value");
2740 return MatchOperand_ParseFail;
2743 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2744 // and because the CPU always adds one to the immediate field, the allowed
2745 // range becomes 1..4. We'll only check the range here and will deal
2746 // with the addition/subtraction when actually decoding/encoding
2748 if (Val < 1 || Val > 4) {
2749 Error(S, "immediate not in range (1..4)");
2750 return MatchOperand_ParseFail;
2754 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2755 return MatchOperand_Success;
2758 MipsAsmParser::OperandMatchResultTy
2759 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2760 MCAsmParser &Parser = getParser();
2761 SmallVector<unsigned, 10> Regs;
2763 unsigned PrevReg = Mips::NoRegister;
2764 bool RegRange = false;
2765 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2767 if (Parser.getTok().isNot(AsmToken::Dollar))
2768 return MatchOperand_ParseFail;
2770 SMLoc S = Parser.getTok().getLoc();
2771 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2772 SMLoc E = getLexer().getLoc();
2773 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2774 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2776 // Remove last register operand because registers from register range
2777 // should be inserted first.
2778 if (RegNo == Mips::RA) {
2779 Regs.push_back(RegNo);
2781 unsigned TmpReg = PrevReg + 1;
2782 while (TmpReg <= RegNo) {
2783 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2784 Error(E, "invalid register operand");
2785 return MatchOperand_ParseFail;
2789 Regs.push_back(TmpReg++);
2795 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2796 (RegNo != Mips::RA)) {
2797 Error(E, "$16 or $31 expected");
2798 return MatchOperand_ParseFail;
2799 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2800 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2801 Error(E, "invalid register operand");
2802 return MatchOperand_ParseFail;
2803 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2804 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2805 Error(E, "consecutive register numbers expected");
2806 return MatchOperand_ParseFail;
2809 Regs.push_back(RegNo);
2812 if (Parser.getTok().is(AsmToken::Minus))
2815 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2816 !Parser.getTok().isNot(AsmToken::Comma)) {
2817 Error(E, "',' or '-' expected");
2818 return MatchOperand_ParseFail;
2821 Lex(); // Consume comma or minus
2822 if (Parser.getTok().isNot(AsmToken::Dollar))
2828 SMLoc E = Parser.getTok().getLoc();
2829 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2830 parseMemOperand(Operands);
2831 return MatchOperand_Success;
2834 MipsAsmParser::OperandMatchResultTy
2835 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
2836 MCAsmParser &Parser = getParser();
2838 SMLoc S = Parser.getTok().getLoc();
2839 if (parseAnyRegister(Operands) != MatchOperand_Success)
2840 return MatchOperand_ParseFail;
2842 SMLoc E = Parser.getTok().getLoc();
2843 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
2844 unsigned Reg = Op.getGPR32Reg();
2845 Operands.pop_back();
2846 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
2847 return MatchOperand_Success;
2850 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2852 MCSymbolRefExpr::VariantKind VK =
2853 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2854 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2855 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2856 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2857 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2858 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2859 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2860 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2861 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2862 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2863 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2864 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2865 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2866 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2867 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2868 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2869 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2870 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2871 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2872 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2873 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2874 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2875 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2876 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2877 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2878 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2879 .Default(MCSymbolRefExpr::VK_None);
2881 assert(VK != MCSymbolRefExpr::VK_None);
2886 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2888 /// ::= '(', register, ')'
2889 /// handle it before we iterate so we don't get tripped up by the lack of
2891 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2892 MCAsmParser &Parser = getParser();
2893 if (getLexer().is(AsmToken::LParen)) {
2895 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2897 if (parseOperand(Operands, Name)) {
2898 SMLoc Loc = getLexer().getLoc();
2899 Parser.eatToEndOfStatement();
2900 return Error(Loc, "unexpected token in argument list");
2902 if (Parser.getTok().isNot(AsmToken::RParen)) {
2903 SMLoc Loc = getLexer().getLoc();
2904 Parser.eatToEndOfStatement();
2905 return Error(Loc, "unexpected token, expected ')'");
2908 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2914 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2915 /// either one of these.
2916 /// ::= '[', register, ']'
2917 /// ::= '[', integer, ']'
2918 /// handle it before we iterate so we don't get tripped up by the lack of
2920 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2921 OperandVector &Operands) {
2922 MCAsmParser &Parser = getParser();
2923 if (getLexer().is(AsmToken::LBrac)) {
2925 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2927 if (parseOperand(Operands, Name)) {
2928 SMLoc Loc = getLexer().getLoc();
2929 Parser.eatToEndOfStatement();
2930 return Error(Loc, "unexpected token in argument list");
2932 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2933 SMLoc Loc = getLexer().getLoc();
2934 Parser.eatToEndOfStatement();
2935 return Error(Loc, "unexpected token, expected ']'");
2938 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2944 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2945 SMLoc NameLoc, OperandVector &Operands) {
2946 MCAsmParser &Parser = getParser();
2947 DEBUG(dbgs() << "ParseInstruction\n");
2949 // We have reached first instruction, module directive are now forbidden.
2950 getTargetStreamer().forbidModuleDirective();
2952 // Check if we have valid mnemonic
2953 if (!mnemonicIsValid(Name, 0)) {
2954 Parser.eatToEndOfStatement();
2955 return Error(NameLoc, "unknown instruction");
2957 // First operand in MCInst is instruction mnemonic.
2958 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2960 // Read the remaining operands.
2961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2962 // Read the first operand.
2963 if (parseOperand(Operands, Name)) {
2964 SMLoc Loc = getLexer().getLoc();
2965 Parser.eatToEndOfStatement();
2966 return Error(Loc, "unexpected token in argument list");
2968 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2970 // AFAIK, parenthesis suffixes are never on the first operand
2972 while (getLexer().is(AsmToken::Comma)) {
2973 Parser.Lex(); // Eat the comma.
2974 // Parse and remember the operand.
2975 if (parseOperand(Operands, Name)) {
2976 SMLoc Loc = getLexer().getLoc();
2977 Parser.eatToEndOfStatement();
2978 return Error(Loc, "unexpected token in argument list");
2980 // Parse bracket and parenthesis suffixes before we iterate
2981 if (getLexer().is(AsmToken::LBrac)) {
2982 if (parseBracketSuffix(Name, Operands))
2984 } else if (getLexer().is(AsmToken::LParen) &&
2985 parseParenSuffix(Name, Operands))
2989 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2990 SMLoc Loc = getLexer().getLoc();
2991 Parser.eatToEndOfStatement();
2992 return Error(Loc, "unexpected token in argument list");
2994 Parser.Lex(); // Consume the EndOfStatement.
2998 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2999 MCAsmParser &Parser = getParser();
3000 SMLoc Loc = getLexer().getLoc();
3001 Parser.eatToEndOfStatement();
3002 return Error(Loc, ErrorMsg);
3005 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3006 return Error(Loc, ErrorMsg);
3009 bool MipsAsmParser::parseSetNoAtDirective() {
3010 MCAsmParser &Parser = getParser();
3011 // Line should look like: ".set noat".
3013 AssemblerOptions.back()->setATReg(0);
3016 // If this is not the end of the statement, report an error.
3017 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3018 reportParseError("unexpected token, expected end of statement");
3021 Parser.Lex(); // Consume the EndOfStatement.
3025 bool MipsAsmParser::parseSetAtDirective() {
3026 MCAsmParser &Parser = getParser();
3027 // Line can be .set at - defaults to $1
3031 if (getLexer().is(AsmToken::EndOfStatement)) {
3032 AssemblerOptions.back()->setATReg(1);
3033 Parser.Lex(); // Consume the EndOfStatement.
3035 } else if (getLexer().is(AsmToken::Equal)) {
3036 getParser().Lex(); // Eat the '='.
3037 if (getLexer().isNot(AsmToken::Dollar)) {
3038 reportParseError("unexpected token, expected dollar sign '$'");
3041 Parser.Lex(); // Eat the '$'.
3042 const AsmToken &Reg = Parser.getTok();
3043 if (Reg.is(AsmToken::Identifier)) {
3044 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3045 } else if (Reg.is(AsmToken::Integer)) {
3046 AtRegNo = Reg.getIntVal();
3048 reportParseError("unexpected token, expected identifier or integer");
3052 if (AtRegNo < 0 || AtRegNo > 31) {
3053 reportParseError("unexpected token in statement");
3057 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3058 reportParseError("invalid register");
3061 getParser().Lex(); // Eat the register.
3063 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3064 reportParseError("unexpected token, expected end of statement");
3067 Parser.Lex(); // Consume the EndOfStatement.
3070 reportParseError("unexpected token in statement");
3075 bool MipsAsmParser::parseSetReorderDirective() {
3076 MCAsmParser &Parser = getParser();
3078 // If this is not the end of the statement, report an error.
3079 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3080 reportParseError("unexpected token, expected end of statement");
3083 AssemblerOptions.back()->setReorder();
3084 getTargetStreamer().emitDirectiveSetReorder();
3085 Parser.Lex(); // Consume the EndOfStatement.
3089 bool MipsAsmParser::parseSetNoReorderDirective() {
3090 MCAsmParser &Parser = getParser();
3092 // If this is not the end of the statement, report an error.
3093 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3094 reportParseError("unexpected token, expected end of statement");
3097 AssemblerOptions.back()->setNoReorder();
3098 getTargetStreamer().emitDirectiveSetNoReorder();
3099 Parser.Lex(); // Consume the EndOfStatement.
3103 bool MipsAsmParser::parseSetMacroDirective() {
3104 MCAsmParser &Parser = getParser();
3106 // If this is not the end of the statement, report an error.
3107 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3108 reportParseError("unexpected token, expected end of statement");
3111 AssemblerOptions.back()->setMacro();
3112 Parser.Lex(); // Consume the EndOfStatement.
3116 bool MipsAsmParser::parseSetNoMacroDirective() {
3117 MCAsmParser &Parser = getParser();
3119 // If this is not the end of the statement, report an error.
3120 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3121 reportParseError("unexpected token, expected end of statement");
3124 if (AssemblerOptions.back()->isReorder()) {
3125 reportParseError("`noreorder' must be set before `nomacro'");
3128 AssemblerOptions.back()->setNoMacro();
3129 Parser.Lex(); // Consume the EndOfStatement.
3133 bool MipsAsmParser::parseSetMsaDirective() {
3134 MCAsmParser &Parser = getParser();
3137 // If this is not the end of the statement, report an error.
3138 if (getLexer().isNot(AsmToken::EndOfStatement))
3139 return reportParseError("unexpected token, expected end of statement");
3141 setFeatureBits(Mips::FeatureMSA, "msa");
3142 getTargetStreamer().emitDirectiveSetMsa();
3146 bool MipsAsmParser::parseSetNoMsaDirective() {
3147 MCAsmParser &Parser = getParser();
3150 // If this is not the end of the statement, report an error.
3151 if (getLexer().isNot(AsmToken::EndOfStatement))
3152 return reportParseError("unexpected token, expected end of statement");
3154 clearFeatureBits(Mips::FeatureMSA, "msa");
3155 getTargetStreamer().emitDirectiveSetNoMsa();
3159 bool MipsAsmParser::parseSetNoDspDirective() {
3160 MCAsmParser &Parser = getParser();
3161 Parser.Lex(); // Eat "nodsp".
3163 // If this is not the end of the statement, report an error.
3164 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3165 reportParseError("unexpected token, expected end of statement");
3169 clearFeatureBits(Mips::FeatureDSP, "dsp");
3170 getTargetStreamer().emitDirectiveSetNoDsp();
3174 bool MipsAsmParser::parseSetMips16Directive() {
3175 MCAsmParser &Parser = getParser();
3176 Parser.Lex(); // Eat "mips16".
3178 // If this is not the end of the statement, report an error.
3179 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3180 reportParseError("unexpected token, expected end of statement");
3184 setFeatureBits(Mips::FeatureMips16, "mips16");
3185 getTargetStreamer().emitDirectiveSetMips16();
3186 Parser.Lex(); // Consume the EndOfStatement.
3190 bool MipsAsmParser::parseSetNoMips16Directive() {
3191 MCAsmParser &Parser = getParser();
3192 Parser.Lex(); // Eat "nomips16".
3194 // If this is not the end of the statement, report an error.
3195 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3196 reportParseError("unexpected token, expected end of statement");
3200 clearFeatureBits(Mips::FeatureMips16, "mips16");
3201 getTargetStreamer().emitDirectiveSetNoMips16();
3202 Parser.Lex(); // Consume the EndOfStatement.
3206 bool MipsAsmParser::parseSetFpDirective() {
3207 MCAsmParser &Parser = getParser();
3208 MipsABIFlagsSection::FpABIKind FpAbiVal;
3209 // Line can be: .set fp=32
3212 Parser.Lex(); // Eat fp token
3213 AsmToken Tok = Parser.getTok();
3214 if (Tok.isNot(AsmToken::Equal)) {
3215 reportParseError("unexpected token, expected equals sign '='");
3218 Parser.Lex(); // Eat '=' token.
3219 Tok = Parser.getTok();
3221 if (!parseFpABIValue(FpAbiVal, ".set"))
3224 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3225 reportParseError("unexpected token, expected end of statement");
3228 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3229 Parser.Lex(); // Consume the EndOfStatement.
3233 bool MipsAsmParser::parseSetPopDirective() {
3234 MCAsmParser &Parser = getParser();
3235 SMLoc Loc = getLexer().getLoc();
3238 if (getLexer().isNot(AsmToken::EndOfStatement))
3239 return reportParseError("unexpected token, expected end of statement");
3241 // Always keep an element on the options "stack" to prevent the user
3242 // from changing the initial options. This is how we remember them.
3243 if (AssemblerOptions.size() == 2)
3244 return reportParseError(Loc, ".set pop with no .set push");
3246 AssemblerOptions.pop_back();
3247 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3249 getTargetStreamer().emitDirectiveSetPop();
3253 bool MipsAsmParser::parseSetPushDirective() {
3254 MCAsmParser &Parser = getParser();
3256 if (getLexer().isNot(AsmToken::EndOfStatement))
3257 return reportParseError("unexpected token, expected end of statement");
3259 // Create a copy of the current assembler options environment and push it.
3260 AssemblerOptions.push_back(
3261 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3263 getTargetStreamer().emitDirectiveSetPush();
3267 bool MipsAsmParser::parseSetAssignment() {
3269 const MCExpr *Value;
3270 MCAsmParser &Parser = getParser();
3272 if (Parser.parseIdentifier(Name))
3273 reportParseError("expected identifier after .set");
3275 if (getLexer().isNot(AsmToken::Comma))
3276 return reportParseError("unexpected token, expected comma");
3279 if (Parser.parseExpression(Value))
3280 return reportParseError("expected valid expression after comma");
3282 // Check if the Name already exists as a symbol.
3283 MCSymbol *Sym = getContext().LookupSymbol(Name);
3285 return reportParseError("symbol already defined");
3286 Sym = getContext().GetOrCreateSymbol(Name);
3287 Sym->setVariableValue(Value);
3292 bool MipsAsmParser::parseSetMips0Directive() {
3293 MCAsmParser &Parser = getParser();
3295 if (getLexer().isNot(AsmToken::EndOfStatement))
3296 return reportParseError("unexpected token, expected end of statement");
3298 // Reset assembler options to their initial values.
3299 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3300 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3302 getTargetStreamer().emitDirectiveSetMips0();
3306 bool MipsAsmParser::parseSetArchDirective() {
3307 MCAsmParser &Parser = getParser();
3309 if (getLexer().isNot(AsmToken::Equal))
3310 return reportParseError("unexpected token, expected equals sign");
3314 if (Parser.parseIdentifier(Arch))
3315 return reportParseError("expected arch identifier");
3317 StringRef ArchFeatureName =
3318 StringSwitch<StringRef>(Arch)
3319 .Case("mips1", "mips1")
3320 .Case("mips2", "mips2")
3321 .Case("mips3", "mips3")
3322 .Case("mips4", "mips4")
3323 .Case("mips5", "mips5")
3324 .Case("mips32", "mips32")
3325 .Case("mips32r2", "mips32r2")
3326 .Case("mips32r6", "mips32r6")
3327 .Case("mips64", "mips64")
3328 .Case("mips64r2", "mips64r2")
3329 .Case("mips64r6", "mips64r6")
3330 .Case("cnmips", "cnmips")
3331 .Case("r4000", "mips3") // This is an implementation of Mips3.
3334 if (ArchFeatureName.empty())
3335 return reportParseError("unsupported architecture");
3337 selectArch(ArchFeatureName);
3338 getTargetStreamer().emitDirectiveSetArch(Arch);
3342 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3343 MCAsmParser &Parser = getParser();
3345 if (getLexer().isNot(AsmToken::EndOfStatement))
3346 return reportParseError("unexpected token, expected end of statement");
3350 llvm_unreachable("Unimplemented feature");
3351 case Mips::FeatureDSP:
3352 setFeatureBits(Mips::FeatureDSP, "dsp");
3353 getTargetStreamer().emitDirectiveSetDsp();
3355 case Mips::FeatureMicroMips:
3356 getTargetStreamer().emitDirectiveSetMicroMips();
3358 case Mips::FeatureMips1:
3359 selectArch("mips1");
3360 getTargetStreamer().emitDirectiveSetMips1();
3362 case Mips::FeatureMips2:
3363 selectArch("mips2");
3364 getTargetStreamer().emitDirectiveSetMips2();
3366 case Mips::FeatureMips3:
3367 selectArch("mips3");
3368 getTargetStreamer().emitDirectiveSetMips3();
3370 case Mips::FeatureMips4:
3371 selectArch("mips4");
3372 getTargetStreamer().emitDirectiveSetMips4();
3374 case Mips::FeatureMips5:
3375 selectArch("mips5");
3376 getTargetStreamer().emitDirectiveSetMips5();
3378 case Mips::FeatureMips32:
3379 selectArch("mips32");
3380 getTargetStreamer().emitDirectiveSetMips32();
3382 case Mips::FeatureMips32r2:
3383 selectArch("mips32r2");
3384 getTargetStreamer().emitDirectiveSetMips32R2();
3386 case Mips::FeatureMips32r6:
3387 selectArch("mips32r6");
3388 getTargetStreamer().emitDirectiveSetMips32R6();
3390 case Mips::FeatureMips64:
3391 selectArch("mips64");
3392 getTargetStreamer().emitDirectiveSetMips64();
3394 case Mips::FeatureMips64r2:
3395 selectArch("mips64r2");
3396 getTargetStreamer().emitDirectiveSetMips64R2();
3398 case Mips::FeatureMips64r6:
3399 selectArch("mips64r6");
3400 getTargetStreamer().emitDirectiveSetMips64R6();
3406 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3407 MCAsmParser &Parser = getParser();
3408 if (getLexer().isNot(AsmToken::Comma)) {
3409 SMLoc Loc = getLexer().getLoc();
3410 Parser.eatToEndOfStatement();
3411 return Error(Loc, ErrorStr);
3414 Parser.Lex(); // Eat the comma.
3418 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3419 if (AssemblerOptions.back()->isReorder())
3420 Warning(Loc, ".cpload should be inside a noreorder section");
3422 if (inMips16Mode()) {
3423 reportParseError(".cpload is not supported in Mips16 mode");
3427 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3428 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3429 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3430 reportParseError("expected register containing function address");
3434 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3435 if (!RegOpnd.isGPRAsmReg()) {
3436 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3440 // If this is not the end of the statement, report an error.
3441 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3442 reportParseError("unexpected token, expected end of statement");
3446 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3450 bool MipsAsmParser::parseDirectiveCPSetup() {
3451 MCAsmParser &Parser = getParser();
3454 bool SaveIsReg = true;
3456 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3457 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3458 if (ResTy == MatchOperand_NoMatch) {
3459 reportParseError("expected register containing function address");
3460 Parser.eatToEndOfStatement();
3464 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3465 if (!FuncRegOpnd.isGPRAsmReg()) {
3466 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3467 Parser.eatToEndOfStatement();
3471 FuncReg = FuncRegOpnd.getGPR32Reg();
3474 if (!eatComma("unexpected token, expected comma"))
3477 ResTy = parseAnyRegister(TmpReg);
3478 if (ResTy == MatchOperand_NoMatch) {
3479 const AsmToken &Tok = Parser.getTok();
3480 if (Tok.is(AsmToken::Integer)) {
3481 Save = Tok.getIntVal();
3485 reportParseError("expected save register or stack offset");
3486 Parser.eatToEndOfStatement();
3490 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3491 if (!SaveOpnd.isGPRAsmReg()) {
3492 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3493 Parser.eatToEndOfStatement();
3496 Save = SaveOpnd.getGPR32Reg();
3499 if (!eatComma("unexpected token, expected comma"))
3503 if (Parser.parseIdentifier(Name))
3504 reportParseError("expected identifier");
3505 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3507 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3511 bool MipsAsmParser::parseDirectiveNaN() {
3512 MCAsmParser &Parser = getParser();
3513 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3514 const AsmToken &Tok = Parser.getTok();
3516 if (Tok.getString() == "2008") {
3518 getTargetStreamer().emitDirectiveNaN2008();
3520 } else if (Tok.getString() == "legacy") {
3522 getTargetStreamer().emitDirectiveNaNLegacy();
3526 // If we don't recognize the option passed to the .nan
3527 // directive (e.g. no option or unknown option), emit an error.
3528 reportParseError("invalid option in .nan directive");
3532 bool MipsAsmParser::parseDirectiveSet() {
3533 MCAsmParser &Parser = getParser();
3534 // Get the next token.
3535 const AsmToken &Tok = Parser.getTok();
3537 if (Tok.getString() == "noat") {
3538 return parseSetNoAtDirective();
3539 } else if (Tok.getString() == "at") {
3540 return parseSetAtDirective();
3541 } else if (Tok.getString() == "arch") {
3542 return parseSetArchDirective();
3543 } else if (Tok.getString() == "fp") {
3544 return parseSetFpDirective();
3545 } else if (Tok.getString() == "pop") {
3546 return parseSetPopDirective();
3547 } else if (Tok.getString() == "push") {
3548 return parseSetPushDirective();
3549 } else if (Tok.getString() == "reorder") {
3550 return parseSetReorderDirective();
3551 } else if (Tok.getString() == "noreorder") {
3552 return parseSetNoReorderDirective();
3553 } else if (Tok.getString() == "macro") {
3554 return parseSetMacroDirective();
3555 } else if (Tok.getString() == "nomacro") {
3556 return parseSetNoMacroDirective();
3557 } else if (Tok.getString() == "mips16") {
3558 return parseSetMips16Directive();
3559 } else if (Tok.getString() == "nomips16") {
3560 return parseSetNoMips16Directive();
3561 } else if (Tok.getString() == "nomicromips") {
3562 getTargetStreamer().emitDirectiveSetNoMicroMips();
3563 Parser.eatToEndOfStatement();
3565 } else if (Tok.getString() == "micromips") {
3566 return parseSetFeature(Mips::FeatureMicroMips);
3567 } else if (Tok.getString() == "mips0") {
3568 return parseSetMips0Directive();
3569 } else if (Tok.getString() == "mips1") {
3570 return parseSetFeature(Mips::FeatureMips1);
3571 } else if (Tok.getString() == "mips2") {
3572 return parseSetFeature(Mips::FeatureMips2);
3573 } else if (Tok.getString() == "mips3") {
3574 return parseSetFeature(Mips::FeatureMips3);
3575 } else if (Tok.getString() == "mips4") {
3576 return parseSetFeature(Mips::FeatureMips4);
3577 } else if (Tok.getString() == "mips5") {
3578 return parseSetFeature(Mips::FeatureMips5);
3579 } else if (Tok.getString() == "mips32") {
3580 return parseSetFeature(Mips::FeatureMips32);
3581 } else if (Tok.getString() == "mips32r2") {
3582 return parseSetFeature(Mips::FeatureMips32r2);
3583 } else if (Tok.getString() == "mips32r6") {
3584 return parseSetFeature(Mips::FeatureMips32r6);
3585 } else if (Tok.getString() == "mips64") {
3586 return parseSetFeature(Mips::FeatureMips64);
3587 } else if (Tok.getString() == "mips64r2") {
3588 return parseSetFeature(Mips::FeatureMips64r2);
3589 } else if (Tok.getString() == "mips64r6") {
3590 return parseSetFeature(Mips::FeatureMips64r6);
3591 } else if (Tok.getString() == "dsp") {
3592 return parseSetFeature(Mips::FeatureDSP);
3593 } else if (Tok.getString() == "nodsp") {
3594 return parseSetNoDspDirective();
3595 } else if (Tok.getString() == "msa") {
3596 return parseSetMsaDirective();
3597 } else if (Tok.getString() == "nomsa") {
3598 return parseSetNoMsaDirective();
3600 // It is just an identifier, look for an assignment.
3601 parseSetAssignment();
3608 /// parseDataDirective
3609 /// ::= .word [ expression (, expression)* ]
3610 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3611 MCAsmParser &Parser = getParser();
3612 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3614 const MCExpr *Value;
3615 if (getParser().parseExpression(Value))
3618 getParser().getStreamer().EmitValue(Value, Size);
3620 if (getLexer().is(AsmToken::EndOfStatement))
3623 if (getLexer().isNot(AsmToken::Comma))
3624 return Error(L, "unexpected token, expected comma");
3633 /// parseDirectiveGpWord
3634 /// ::= .gpword local_sym
3635 bool MipsAsmParser::parseDirectiveGpWord() {
3636 MCAsmParser &Parser = getParser();
3637 const MCExpr *Value;
3638 // EmitGPRel32Value requires an expression, so we are using base class
3639 // method to evaluate the expression.
3640 if (getParser().parseExpression(Value))
3642 getParser().getStreamer().EmitGPRel32Value(Value);
3644 if (getLexer().isNot(AsmToken::EndOfStatement))
3645 return Error(getLexer().getLoc(),
3646 "unexpected token, expected end of statement");
3647 Parser.Lex(); // Eat EndOfStatement token.
3651 /// parseDirectiveGpDWord
3652 /// ::= .gpdword local_sym
3653 bool MipsAsmParser::parseDirectiveGpDWord() {
3654 MCAsmParser &Parser = getParser();
3655 const MCExpr *Value;
3656 // EmitGPRel64Value requires an expression, so we are using base class
3657 // method to evaluate the expression.
3658 if (getParser().parseExpression(Value))
3660 getParser().getStreamer().EmitGPRel64Value(Value);
3662 if (getLexer().isNot(AsmToken::EndOfStatement))
3663 return Error(getLexer().getLoc(),
3664 "unexpected token, expected end of statement");
3665 Parser.Lex(); // Eat EndOfStatement token.
3669 bool MipsAsmParser::parseDirectiveOption() {
3670 MCAsmParser &Parser = getParser();
3671 // Get the option token.
3672 AsmToken Tok = Parser.getTok();
3673 // At the moment only identifiers are supported.
3674 if (Tok.isNot(AsmToken::Identifier)) {
3675 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3676 Parser.eatToEndOfStatement();
3680 StringRef Option = Tok.getIdentifier();
3682 if (Option == "pic0") {
3683 getTargetStreamer().emitDirectiveOptionPic0();
3685 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3686 Error(Parser.getTok().getLoc(),
3687 "unexpected token, expected end of statement");
3688 Parser.eatToEndOfStatement();
3693 if (Option == "pic2") {
3694 getTargetStreamer().emitDirectiveOptionPic2();
3696 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3697 Error(Parser.getTok().getLoc(),
3698 "unexpected token, expected end of statement");
3699 Parser.eatToEndOfStatement();
3705 Warning(Parser.getTok().getLoc(),
3706 "unknown option, expected 'pic0' or 'pic2'");
3707 Parser.eatToEndOfStatement();
3711 /// parseDirectiveModule
3712 /// ::= .module oddspreg
3713 /// ::= .module nooddspreg
3714 /// ::= .module fp=value
3715 bool MipsAsmParser::parseDirectiveModule() {
3716 MCAsmParser &Parser = getParser();
3717 MCAsmLexer &Lexer = getLexer();
3718 SMLoc L = Lexer.getLoc();
3720 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3721 // TODO : get a better message.
3722 reportParseError(".module directive must appear before any code");
3726 if (Lexer.is(AsmToken::Identifier)) {
3727 StringRef Option = Parser.getTok().getString();
3730 if (Option == "oddspreg") {
3731 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3732 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3734 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3735 reportParseError("unexpected token, expected end of statement");
3740 } else if (Option == "nooddspreg") {
3742 Error(L, "'.module nooddspreg' requires the O32 ABI");
3746 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3747 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3749 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3750 reportParseError("unexpected token, expected end of statement");
3755 } else if (Option == "fp") {
3756 return parseDirectiveModuleFP();
3759 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3765 /// parseDirectiveModuleFP
3769 bool MipsAsmParser::parseDirectiveModuleFP() {
3770 MCAsmParser &Parser = getParser();
3771 MCAsmLexer &Lexer = getLexer();
3773 if (Lexer.isNot(AsmToken::Equal)) {
3774 reportParseError("unexpected token, expected equals sign '='");
3777 Parser.Lex(); // Eat '=' token.
3779 MipsABIFlagsSection::FpABIKind FpABI;
3780 if (!parseFpABIValue(FpABI, ".module"))
3783 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3784 reportParseError("unexpected token, expected end of statement");
3788 // Emit appropriate flags.
3789 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3790 Parser.Lex(); // Consume the EndOfStatement.
3794 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3795 StringRef Directive) {
3796 MCAsmParser &Parser = getParser();
3797 MCAsmLexer &Lexer = getLexer();
3799 if (Lexer.is(AsmToken::Identifier)) {
3800 StringRef Value = Parser.getTok().getString();
3803 if (Value != "xx") {
3804 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3809 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3813 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3817 if (Lexer.is(AsmToken::Integer)) {
3818 unsigned Value = Parser.getTok().getIntVal();
3821 if (Value != 32 && Value != 64) {
3822 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3828 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3832 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3834 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3842 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3843 MCAsmParser &Parser = getParser();
3844 StringRef IDVal = DirectiveID.getString();
3846 if (IDVal == ".cpload")
3847 return parseDirectiveCpLoad(DirectiveID.getLoc());
3848 if (IDVal == ".dword") {
3849 parseDataDirective(8, DirectiveID.getLoc());
3852 if (IDVal == ".ent") {
3853 StringRef SymbolName;
3855 if (Parser.parseIdentifier(SymbolName)) {
3856 reportParseError("expected identifier after .ent");
3860 // There's an undocumented extension that allows an integer to
3861 // follow the name of the procedure which AFAICS is ignored by GAS.
3862 // Example: .ent foo,2
3863 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3864 if (getLexer().isNot(AsmToken::Comma)) {
3865 // Even though we accept this undocumented extension for compatibility
3866 // reasons, the additional integer argument does not actually change
3867 // the behaviour of the '.ent' directive, so we would like to discourage
3868 // its use. We do this by not referring to the extended version in
3869 // error messages which are not directly related to its use.
3870 reportParseError("unexpected token, expected end of statement");
3873 Parser.Lex(); // Eat the comma.
3874 const MCExpr *DummyNumber;
3875 int64_t DummyNumberVal;
3876 // If the user was explicitly trying to use the extended version,
3877 // we still give helpful extension-related error messages.
3878 if (Parser.parseExpression(DummyNumber)) {
3879 reportParseError("expected number after comma");
3882 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3883 reportParseError("expected an absolute expression after comma");
3888 // If this is not the end of the statement, report an error.
3889 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3890 reportParseError("unexpected token, expected end of statement");
3894 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3896 getTargetStreamer().emitDirectiveEnt(*Sym);
3901 if (IDVal == ".end") {
3902 StringRef SymbolName;
3904 if (Parser.parseIdentifier(SymbolName)) {
3905 reportParseError("expected identifier after .end");
3909 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3910 reportParseError("unexpected token, expected end of statement");
3914 if (CurrentFn == nullptr) {
3915 reportParseError(".end used without .ent");
3919 if ((SymbolName != CurrentFn->getName())) {
3920 reportParseError(".end symbol does not match .ent symbol");
3924 getTargetStreamer().emitDirectiveEnd(SymbolName);
3925 CurrentFn = nullptr;
3929 if (IDVal == ".frame") {
3930 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3931 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3932 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3933 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3934 reportParseError("expected stack register");
3938 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3939 if (!StackRegOpnd.isGPRAsmReg()) {
3940 reportParseError(StackRegOpnd.getStartLoc(),
3941 "expected general purpose register");
3944 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3946 if (Parser.getTok().is(AsmToken::Comma))
3949 reportParseError("unexpected token, expected comma");
3953 // Parse the frame size.
3954 const MCExpr *FrameSize;
3955 int64_t FrameSizeVal;
3957 if (Parser.parseExpression(FrameSize)) {
3958 reportParseError("expected frame size value");
3962 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3963 reportParseError("frame size not an absolute expression");
3967 if (Parser.getTok().is(AsmToken::Comma))
3970 reportParseError("unexpected token, expected comma");
3974 // Parse the return register.
3976 ResTy = parseAnyRegister(TmpReg);
3977 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3978 reportParseError("expected return register");
3982 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3983 if (!ReturnRegOpnd.isGPRAsmReg()) {
3984 reportParseError(ReturnRegOpnd.getStartLoc(),
3985 "expected general purpose register");
3989 // If this is not the end of the statement, report an error.
3990 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3991 reportParseError("unexpected token, expected end of statement");
3995 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3996 ReturnRegOpnd.getGPR32Reg());
4000 if (IDVal == ".set") {
4001 return parseDirectiveSet();
4004 if (IDVal == ".mask" || IDVal == ".fmask") {
4005 // .mask bitmask, frame_offset
4006 // bitmask: One bit for each register used.
4007 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4008 // first register is expected to be saved.
4010 // .mask 0x80000000, -4
4011 // .fmask 0x80000000, -4
4014 // Parse the bitmask
4015 const MCExpr *BitMask;
4018 if (Parser.parseExpression(BitMask)) {
4019 reportParseError("expected bitmask value");
4023 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4024 reportParseError("bitmask not an absolute expression");
4028 if (Parser.getTok().is(AsmToken::Comma))
4031 reportParseError("unexpected token, expected comma");
4035 // Parse the frame_offset
4036 const MCExpr *FrameOffset;
4037 int64_t FrameOffsetVal;
4039 if (Parser.parseExpression(FrameOffset)) {
4040 reportParseError("expected frame offset value");
4044 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4045 reportParseError("frame offset not an absolute expression");
4049 // If this is not the end of the statement, report an error.
4050 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4051 reportParseError("unexpected token, expected end of statement");
4055 if (IDVal == ".mask")
4056 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4058 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4062 if (IDVal == ".nan")
4063 return parseDirectiveNaN();
4065 if (IDVal == ".gpword") {
4066 parseDirectiveGpWord();
4070 if (IDVal == ".gpdword") {
4071 parseDirectiveGpDWord();
4075 if (IDVal == ".word") {
4076 parseDataDirective(4, DirectiveID.getLoc());
4080 if (IDVal == ".option")
4081 return parseDirectiveOption();
4083 if (IDVal == ".abicalls") {
4084 getTargetStreamer().emitDirectiveAbiCalls();
4085 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4086 Error(Parser.getTok().getLoc(),
4087 "unexpected token, expected end of statement");
4089 Parser.eatToEndOfStatement();
4094 if (IDVal == ".cpsetup")
4095 return parseDirectiveCPSetup();
4097 if (IDVal == ".module")
4098 return parseDirectiveModule();
4103 extern "C" void LLVMInitializeMipsAsmParser() {
4104 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4105 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4106 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4107 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4110 #define GET_REGISTER_MATCHER
4111 #define GET_MATCHER_IMPLEMENTATION
4112 #include "MipsGenAsmMatcher.inc"