1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
36 #define DEBUG_TYPE "mips-asm-parser"
43 class MipsAssemblerOptions {
45 MipsAssemblerOptions(uint64_t Features_) :
46 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
48 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
49 ATReg = Opts->getATRegNum();
50 Reorder = Opts->isReorder();
51 Macro = Opts->isMacro();
52 Features = Opts->getFeatures();
55 unsigned getATRegNum() const { return ATReg; }
56 bool setATReg(unsigned Reg);
58 bool isReorder() const { return Reorder; }
59 void setReorder() { Reorder = true; }
60 void setNoReorder() { Reorder = false; }
62 bool isMacro() const { return Macro; }
63 void setMacro() { Macro = true; }
64 void setNoMacro() { Macro = false; }
66 uint64_t getFeatures() const { return Features; }
67 void setFeatures(uint64_t Features_) { Features = Features_; }
69 // Set of features that are either architecture features or referenced
70 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
71 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
72 // The reason we need this mask is explained in the selectArch function.
73 // FIXME: Ideally we would like TableGen to generate this information.
74 static const uint64_t AllArchRelatedMask =
75 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
76 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
77 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
78 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
79 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
80 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
81 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
92 class MipsAsmParser : public MCTargetAsmParser {
93 MipsTargetStreamer &getTargetStreamer() {
94 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
95 return static_cast<MipsTargetStreamer &>(TS);
100 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
101 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
102 // nullptr, which indicates that no function is currently
103 // selected. This usually happens after an '.end func'
106 // Print a warning along with its fix-it message at the given range.
107 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
108 SMRange Range, bool ShowColors = true);
110 #define GET_ASSEMBLER_HEADER
111 #include "MipsGenAsmMatcher.inc"
113 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
115 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
116 OperandVector &Operands, MCStreamer &Out,
118 bool MatchingInlineAsm) override;
120 /// Parse a register as used in CFI directives
121 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
123 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
125 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
127 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
128 SMLoc NameLoc, OperandVector &Operands) override;
130 bool ParseDirective(AsmToken DirectiveID) override;
132 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
134 MipsAsmParser::OperandMatchResultTy
135 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
136 StringRef Identifier, SMLoc S);
138 MipsAsmParser::OperandMatchResultTy
139 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
141 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy
152 parseRegisterPair (OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy
155 parseRegisterList (OperandVector &Operands);
157 bool searchSymbolAlias(OperandVector &Operands);
159 bool parseOperand(OperandVector &, StringRef Mnemonic);
161 bool needsExpansion(MCInst &Inst);
163 // Expands assembly pseudo instructions.
164 // Returns false on success, true otherwise.
165 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
166 SmallVectorImpl<MCInst> &Instructions);
168 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
169 SmallVectorImpl<MCInst> &Instructions);
171 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
172 SmallVectorImpl<MCInst> &Instructions);
174 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
176 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
185 bool reportParseError(Twine ErrorMsg);
186 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
188 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
189 bool parseRelocOperand(const MCExpr *&Res);
191 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
193 bool isEvaluated(const MCExpr *Expr);
194 bool parseSetMips0Directive();
195 bool parseSetArchDirective();
196 bool parseSetFeature(uint64_t Feature);
197 bool parseDirectiveCpLoad(SMLoc Loc);
198 bool parseDirectiveCPSetup();
199 bool parseDirectiveNaN();
200 bool parseDirectiveSet();
201 bool parseDirectiveOption();
203 bool parseSetAtDirective();
204 bool parseSetNoAtDirective();
205 bool parseSetMacroDirective();
206 bool parseSetNoMacroDirective();
207 bool parseSetMsaDirective();
208 bool parseSetNoMsaDirective();
209 bool parseSetNoDspDirective();
210 bool parseSetReorderDirective();
211 bool parseSetNoReorderDirective();
212 bool parseSetMips16Directive();
213 bool parseSetNoMips16Directive();
214 bool parseSetFpDirective();
215 bool parseSetPopDirective();
216 bool parseSetPushDirective();
218 bool parseSetAssignment();
220 bool parseDataDirective(unsigned Size, SMLoc L);
221 bool parseDirectiveGpWord();
222 bool parseDirectiveGpDWord();
223 bool parseDirectiveModule();
224 bool parseDirectiveModuleFP();
225 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
226 StringRef Directive);
228 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
230 bool eatComma(StringRef ErrorStr);
232 int matchCPURegisterName(StringRef Symbol);
234 int matchHWRegsRegisterName(StringRef Symbol);
236 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
238 int matchFPURegisterName(StringRef Name);
240 int matchFCCRegisterName(StringRef Name);
242 int matchACRegisterName(StringRef Name);
244 int matchMSA128RegisterName(StringRef Name);
246 int matchMSA128CtrlRegisterName(StringRef Name);
248 unsigned getReg(int RC, int RegNo);
250 unsigned getGPR(int RegNo);
252 int getATReg(SMLoc Loc);
254 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
255 SmallVectorImpl<MCInst> &Instructions);
257 // Helper function that checks if the value of a vector index is within the
258 // boundaries of accepted values for each RegisterKind
259 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
260 bool validateMSAIndex(int Val, int RegKind);
262 // Selects a new architecture by updating the FeatureBits with the necessary
263 // info including implied dependencies.
264 // Internally, it clears all the feature bits related to *any* architecture
265 // and selects the new one using the ToggleFeature functionality of the
266 // MCSubtargetInfo object that handles implied dependencies. The reason we
267 // clear all the arch related bits manually is because ToggleFeature only
268 // clears the features that imply the feature being cleared and not the
269 // features implied by the feature being cleared. This is easier to see
271 // --------------------------------------------------
272 // | Feature | Implies |
273 // | -------------------------------------------------|
274 // | FeatureMips1 | None |
275 // | FeatureMips2 | FeatureMips1 |
276 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
277 // | FeatureMips4 | FeatureMips3 |
279 // --------------------------------------------------
281 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
282 // FeatureMipsGP64 | FeatureMips1)
283 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
284 void selectArch(StringRef ArchFeature) {
285 uint64_t FeatureBits = STI.getFeatureBits();
286 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
287 STI.setFeatureBits(FeatureBits);
288 setAvailableFeatures(
289 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
290 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
293 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
294 if (!(STI.getFeatureBits() & Feature)) {
295 setAvailableFeatures(
296 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
298 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
301 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
302 if (STI.getFeatureBits() & Feature) {
303 setAvailableFeatures(
304 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
306 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
310 enum MipsMatchResultTy {
311 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
312 #define GET_OPERAND_DIAGNOSTIC_TYPES
313 #include "MipsGenAsmMatcher.inc"
314 #undef GET_OPERAND_DIAGNOSTIC_TYPES
318 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
319 const MCInstrInfo &MII, const MCTargetOptions &Options)
320 : MCTargetAsmParser(), STI(sti),
321 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
322 sti.getCPU(), Options)) {
323 MCAsmParserExtension::Initialize(parser);
325 // Initialize the set of available features.
326 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
328 // Remember the initial assembler options. The user can not modify these.
329 AssemblerOptions.push_back(
330 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
332 // Create an assembler options environment for the user to modify.
333 AssemblerOptions.push_back(
334 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
336 getTargetStreamer().updateABIInfo(*this);
338 if (!isABI_O32() && !useOddSPReg() != 0)
339 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
344 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
345 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
347 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
348 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
349 const MipsABIInfo &getABI() const { return ABI; }
350 bool isABI_N32() const { return ABI.IsN32(); }
351 bool isABI_N64() const { return ABI.IsN64(); }
352 bool isABI_O32() const { return ABI.IsO32(); }
353 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
355 bool useOddSPReg() const {
356 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
359 bool inMicroMipsMode() const {
360 return STI.getFeatureBits() & Mips::FeatureMicroMips;
362 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
363 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
364 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
365 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
366 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
367 bool hasMips32() const {
368 return (STI.getFeatureBits() & Mips::FeatureMips32);
370 bool hasMips64() const {
371 return (STI.getFeatureBits() & Mips::FeatureMips64);
373 bool hasMips32r2() const {
374 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
376 bool hasMips64r2() const {
377 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
379 bool hasMips32r6() const {
380 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
382 bool hasMips64r6() const {
383 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
385 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
386 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
387 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
389 bool inMips16Mode() const {
390 return STI.getFeatureBits() & Mips::FeatureMips16;
392 // TODO: see how can we get this info.
393 bool abiUsesSoftFloat() const { return false; }
395 /// Warn if RegNo is the current assembler temporary.
396 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
402 /// MipsOperand - Instances of this class represent a parsed Mips machine
404 class MipsOperand : public MCParsedAsmOperand {
406 /// Broad categories of register classes
407 /// The exact class is finalized by the render method.
409 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
410 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
412 RegKind_FCC = 4, /// FCC
413 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
414 RegKind_MSACtrl = 16, /// MSA control registers
415 RegKind_COP2 = 32, /// COP2
416 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
418 RegKind_CCR = 128, /// CCR
419 RegKind_HWRegs = 256, /// HWRegs
420 RegKind_COP3 = 512, /// COP3
422 /// Potentially any (e.g. $1)
423 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
424 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
425 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
430 k_Immediate, /// An immediate (possibly involving symbol references)
431 k_Memory, /// Base + Offset Memory Address
432 k_PhysRegister, /// A physical register from the Mips namespace
433 k_RegisterIndex, /// A register index in one or more RegKind.
434 k_Token, /// A simple token
435 k_RegList, /// A physical register list
436 k_RegPair /// A pair of physical register
440 MipsOperand(KindTy K, MipsAsmParser &Parser)
441 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
444 /// For diagnostics, and checking the assembler temporary
445 MipsAsmParser &AsmParser;
453 unsigned Num; /// Register Number
457 unsigned Index; /// Index into the register class
458 RegKind Kind; /// Bitfield of the kinds it could possibly be
459 const MCRegisterInfo *RegInfo;
472 SmallVector<unsigned, 10> *List;
477 struct PhysRegOp PhysReg;
478 struct RegIdxOp RegIdx;
481 struct RegListOp RegList;
484 SMLoc StartLoc, EndLoc;
486 /// Internal constructor for register kinds
487 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
488 const MCRegisterInfo *RegInfo,
490 MipsAsmParser &Parser) {
491 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
492 Op->RegIdx.Index = Index;
493 Op->RegIdx.RegInfo = RegInfo;
494 Op->RegIdx.Kind = RegKind;
501 /// Coerce the register to GPR32 and return the real register for the current
503 unsigned getGPR32Reg() const {
504 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
505 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
506 unsigned ClassID = Mips::GPR32RegClassID;
507 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
510 /// Coerce the register to GPR32 and return the real register for the current
512 unsigned getGPRMM16Reg() const {
513 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
514 unsigned ClassID = Mips::GPR32RegClassID;
515 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
518 /// Coerce the register to GPR64 and return the real register for the current
520 unsigned getGPR64Reg() const {
521 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
522 unsigned ClassID = Mips::GPR64RegClassID;
523 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
527 /// Coerce the register to AFGR64 and return the real register for the current
529 unsigned getAFGR64Reg() const {
530 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
531 if (RegIdx.Index % 2 != 0)
532 AsmParser.Warning(StartLoc, "Float register should be even.");
533 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
534 .getRegister(RegIdx.Index / 2);
537 /// Coerce the register to FGR64 and return the real register for the current
539 unsigned getFGR64Reg() const {
540 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
541 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
542 .getRegister(RegIdx.Index);
545 /// Coerce the register to FGR32 and return the real register for the current
547 unsigned getFGR32Reg() const {
548 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
549 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
550 .getRegister(RegIdx.Index);
553 /// Coerce the register to FGRH32 and return the real register for the current
555 unsigned getFGRH32Reg() const {
556 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
557 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
558 .getRegister(RegIdx.Index);
561 /// Coerce the register to FCC and return the real register for the current
563 unsigned getFCCReg() const {
564 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
565 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
566 .getRegister(RegIdx.Index);
569 /// Coerce the register to MSA128 and return the real register for the current
571 unsigned getMSA128Reg() const {
572 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
573 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
575 unsigned ClassID = Mips::MSA128BRegClassID;
576 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
579 /// Coerce the register to MSACtrl and return the real register for the
581 unsigned getMSACtrlReg() const {
582 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
583 unsigned ClassID = Mips::MSACtrlRegClassID;
584 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
587 /// Coerce the register to COP2 and return the real register for the
589 unsigned getCOP2Reg() const {
590 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
591 unsigned ClassID = Mips::COP2RegClassID;
592 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
595 /// Coerce the register to COP3 and return the real register for the
597 unsigned getCOP3Reg() const {
598 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
599 unsigned ClassID = Mips::COP3RegClassID;
600 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
603 /// Coerce the register to ACC64DSP and return the real register for the
605 unsigned getACC64DSPReg() const {
606 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
607 unsigned ClassID = Mips::ACC64DSPRegClassID;
608 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
611 /// Coerce the register to HI32DSP and return the real register for the
613 unsigned getHI32DSPReg() const {
614 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
615 unsigned ClassID = Mips::HI32DSPRegClassID;
616 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
619 /// Coerce the register to LO32DSP and return the real register for the
621 unsigned getLO32DSPReg() const {
622 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
623 unsigned ClassID = Mips::LO32DSPRegClassID;
624 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
627 /// Coerce the register to CCR and return the real register for the
629 unsigned getCCRReg() const {
630 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
631 unsigned ClassID = Mips::CCRRegClassID;
632 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
635 /// Coerce the register to HWRegs and return the real register for the
637 unsigned getHWRegsReg() const {
638 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
639 unsigned ClassID = Mips::HWRegsRegClassID;
640 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
644 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
645 // Add as immediate when possible. Null MCExpr = 0.
647 Inst.addOperand(MCOperand::CreateImm(0));
648 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
649 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
651 Inst.addOperand(MCOperand::CreateExpr(Expr));
654 void addRegOperands(MCInst &Inst, unsigned N) const {
655 llvm_unreachable("Use a custom parser instead");
658 /// Render the operand to an MCInst as a GPR32
659 /// Asserts if the wrong number of operands are requested, or the operand
660 /// is not a k_RegisterIndex compatible with RegKind_GPR
661 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
662 assert(N == 1 && "Invalid number of operands!");
663 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
666 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
667 assert(N == 1 && "Invalid number of operands!");
668 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
671 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
672 assert(N == 1 && "Invalid number of operands!");
673 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
676 /// Render the operand to an MCInst as a GPR64
677 /// Asserts if the wrong number of operands are requested, or the operand
678 /// is not a k_RegisterIndex compatible with RegKind_GPR
679 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
680 assert(N == 1 && "Invalid number of operands!");
681 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
684 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
685 assert(N == 1 && "Invalid number of operands!");
686 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
689 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
690 assert(N == 1 && "Invalid number of operands!");
691 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
694 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
695 assert(N == 1 && "Invalid number of operands!");
696 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
697 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
698 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
699 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
703 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
704 assert(N == 1 && "Invalid number of operands!");
705 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
708 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
709 assert(N == 1 && "Invalid number of operands!");
710 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
713 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
714 assert(N == 1 && "Invalid number of operands!");
715 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
718 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
719 assert(N == 1 && "Invalid number of operands!");
720 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
723 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
724 assert(N == 1 && "Invalid number of operands!");
725 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
728 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
733 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
738 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
743 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
744 assert(N == 1 && "Invalid number of operands!");
745 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
748 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
749 assert(N == 1 && "Invalid number of operands!");
750 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
753 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
754 assert(N == 1 && "Invalid number of operands!");
755 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
758 void addImmOperands(MCInst &Inst, unsigned N) const {
759 assert(N == 1 && "Invalid number of operands!");
760 const MCExpr *Expr = getImm();
764 void addMemOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 2 && "Invalid number of operands!");
767 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
769 const MCExpr *Expr = getMemOff();
773 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 2 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
778 const MCExpr *Expr = getMemOff();
782 void addRegListOperands(MCInst &Inst, unsigned N) const {
783 assert(N == 1 && "Invalid number of operands!");
785 for (auto RegNo : getRegList())
786 Inst.addOperand(MCOperand::CreateReg(RegNo));
789 void addRegPairOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 2 && "Invalid number of operands!");
791 unsigned RegNo = getRegPair();
792 Inst.addOperand(MCOperand::CreateReg(RegNo++));
793 Inst.addOperand(MCOperand::CreateReg(RegNo));
796 bool isReg() const override {
797 // As a special case until we sort out the definition of div/divu, pretend
798 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
799 if (isGPRAsmReg() && RegIdx.Index == 0)
802 return Kind == k_PhysRegister;
804 bool isRegIdx() const { return Kind == k_RegisterIndex; }
805 bool isImm() const override { return Kind == k_Immediate; }
806 bool isConstantImm() const {
807 return isImm() && dyn_cast<MCConstantExpr>(getImm());
809 bool isToken() const override {
810 // Note: It's not possible to pretend that other operand kinds are tokens.
811 // The matcher emitter checks tokens first.
812 return Kind == k_Token;
814 bool isMem() const override { return Kind == k_Memory; }
815 bool isConstantMemOff() const {
816 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
818 template <unsigned Bits> bool isMemWithSimmOffset() const {
819 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
821 bool isMemWithGRPMM16Base() const {
822 return isMem() && getMemBase()->isMM16AsmReg();
824 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
825 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
826 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
828 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
829 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
830 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
831 && (getMemBase()->getGPR32Reg() == Mips::SP);
833 bool isRegList16() const {
837 int Size = RegList.List->size();
838 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
839 RegList.List->back() != Mips::RA)
842 int PrevReg = *RegList.List->begin();
843 for (int i = 1; i < Size - 1; i++) {
844 int Reg = (*(RegList.List))[i];
845 if ( Reg != PrevReg + 1)
852 bool isInvNum() const { return Kind == k_Immediate; }
853 bool isLSAImm() const {
854 if (!isConstantImm())
856 int64_t Val = getConstantImm();
857 return 1 <= Val && Val <= 4;
859 bool isRegList() const { return Kind == k_RegList; }
861 StringRef getToken() const {
862 assert(Kind == k_Token && "Invalid access!");
863 return StringRef(Tok.Data, Tok.Length);
865 bool isRegPair() const { return Kind == k_RegPair; }
867 unsigned getReg() const override {
868 // As a special case until we sort out the definition of div/divu, pretend
869 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
870 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
871 RegIdx.Kind & RegKind_GPR)
872 return getGPR32Reg(); // FIXME: GPR64 too
874 assert(Kind == k_PhysRegister && "Invalid access!");
878 const MCExpr *getImm() const {
879 assert((Kind == k_Immediate) && "Invalid access!");
883 int64_t getConstantImm() const {
884 const MCExpr *Val = getImm();
885 return static_cast<const MCConstantExpr *>(Val)->getValue();
888 MipsOperand *getMemBase() const {
889 assert((Kind == k_Memory) && "Invalid access!");
893 const MCExpr *getMemOff() const {
894 assert((Kind == k_Memory) && "Invalid access!");
898 int64_t getConstantMemOff() const {
899 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
902 const SmallVectorImpl<unsigned> &getRegList() const {
903 assert((Kind == k_RegList) && "Invalid access!");
904 return *(RegList.List);
907 unsigned getRegPair() const {
908 assert((Kind == k_RegPair) && "Invalid access!");
912 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
913 MipsAsmParser &Parser) {
914 auto Op = make_unique<MipsOperand>(k_Token, Parser);
915 Op->Tok.Data = Str.data();
916 Op->Tok.Length = Str.size();
922 /// Create a numeric register (e.g. $1). The exact register remains
923 /// unresolved until an instruction successfully matches
924 static std::unique_ptr<MipsOperand>
925 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
926 SMLoc E, MipsAsmParser &Parser) {
927 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
928 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
931 /// Create a register that is definitely a GPR.
932 /// This is typically only used for named registers such as $gp.
933 static std::unique_ptr<MipsOperand>
934 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
935 MipsAsmParser &Parser) {
936 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
939 /// Create a register that is definitely a FGR.
940 /// This is typically only used for named registers such as $f0.
941 static std::unique_ptr<MipsOperand>
942 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
943 MipsAsmParser &Parser) {
944 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
947 /// Create a register that is definitely a HWReg.
948 /// This is typically only used for named registers such as $hwr_cpunum.
949 static std::unique_ptr<MipsOperand>
950 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
951 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
952 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
955 /// Create a register that is definitely an FCC.
956 /// This is typically only used for named registers such as $fcc0.
957 static std::unique_ptr<MipsOperand>
958 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
959 MipsAsmParser &Parser) {
960 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
963 /// Create a register that is definitely an ACC.
964 /// This is typically only used for named registers such as $ac0.
965 static std::unique_ptr<MipsOperand>
966 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
967 MipsAsmParser &Parser) {
968 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
971 /// Create a register that is definitely an MSA128.
972 /// This is typically only used for named registers such as $w0.
973 static std::unique_ptr<MipsOperand>
974 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
975 SMLoc E, MipsAsmParser &Parser) {
976 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
979 /// Create a register that is definitely an MSACtrl.
980 /// This is typically only used for named registers such as $msaaccess.
981 static std::unique_ptr<MipsOperand>
982 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
983 SMLoc E, MipsAsmParser &Parser) {
984 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
987 static std::unique_ptr<MipsOperand>
988 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
989 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
996 static std::unique_ptr<MipsOperand>
997 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
998 SMLoc E, MipsAsmParser &Parser) {
999 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1000 Op->Mem.Base = Base.release();
1007 static std::unique_ptr<MipsOperand>
1008 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1009 MipsAsmParser &Parser) {
1010 assert (Regs.size() > 0 && "Empty list not allowed");
1012 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1013 Op->RegList.List = new SmallVector<unsigned, 10>();
1014 for (auto Reg : Regs)
1015 Op->RegList.List->push_back(Reg);
1016 Op->StartLoc = StartLoc;
1017 Op->EndLoc = EndLoc;
1021 static std::unique_ptr<MipsOperand>
1022 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1023 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1024 Op->RegIdx.Index = RegNo;
1030 bool isGPRAsmReg() const {
1031 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1033 bool isMM16AsmReg() const {
1034 if (!(isRegIdx() && RegIdx.Kind))
1036 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1037 || RegIdx.Index == 16 || RegIdx.Index == 17);
1039 bool isMM16AsmRegZero() const {
1040 if (!(isRegIdx() && RegIdx.Kind))
1042 return (RegIdx.Index == 0 ||
1043 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1044 RegIdx.Index == 17);
1046 bool isFGRAsmReg() const {
1047 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1048 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1050 bool isHWRegsAsmReg() const {
1051 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1053 bool isCCRAsmReg() const {
1054 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1056 bool isFCCAsmReg() const {
1057 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1059 if (!AsmParser.hasEightFccRegisters())
1060 return RegIdx.Index == 0;
1061 return RegIdx.Index <= 7;
1063 bool isACCAsmReg() const {
1064 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1066 bool isCOP2AsmReg() const {
1067 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1069 bool isCOP3AsmReg() const {
1070 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1072 bool isMSA128AsmReg() const {
1073 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1075 bool isMSACtrlAsmReg() const {
1076 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1079 /// getStartLoc - Get the location of the first token of this operand.
1080 SMLoc getStartLoc() const override { return StartLoc; }
1081 /// getEndLoc - Get the location of the last token of this operand.
1082 SMLoc getEndLoc() const override { return EndLoc; }
1084 virtual ~MipsOperand() {
1092 delete RegList.List;
1093 case k_PhysRegister:
1094 case k_RegisterIndex:
1101 void print(raw_ostream &OS) const override {
1110 Mem.Base->print(OS);
1115 case k_PhysRegister:
1116 OS << "PhysReg<" << PhysReg.Num << ">";
1118 case k_RegisterIndex:
1119 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1126 for (auto Reg : (*RegList.List))
1131 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1135 }; // class MipsOperand
1139 extern const MCInstrDesc MipsInsts[];
1141 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1142 return MipsInsts[Opcode];
1145 static bool hasShortDelaySlot(unsigned Opcode) {
1148 case Mips::JALRS_MM:
1149 case Mips::JALRS16_MM:
1150 case Mips::BGEZALS_MM:
1151 case Mips::BLTZALS_MM:
1158 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1159 SmallVectorImpl<MCInst> &Instructions) {
1160 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1164 if (MCID.isBranch() || MCID.isCall()) {
1165 const unsigned Opcode = Inst.getOpcode();
1175 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1176 Offset = Inst.getOperand(2);
1177 if (!Offset.isImm())
1178 break; // We'll deal with this situation later on when applying fixups.
1179 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1180 return Error(IDLoc, "branch target out of range");
1181 if (OffsetToAlignment(Offset.getImm(),
1182 1LL << (inMicroMipsMode() ? 1 : 2)))
1183 return Error(IDLoc, "branch to misaligned address");
1197 case Mips::BGEZAL_MM:
1198 case Mips::BLTZAL_MM:
1201 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1202 Offset = Inst.getOperand(1);
1203 if (!Offset.isImm())
1204 break; // We'll deal with this situation later on when applying fixups.
1205 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1206 return Error(IDLoc, "branch target out of range");
1207 if (OffsetToAlignment(Offset.getImm(),
1208 1LL << (inMicroMipsMode() ? 1 : 2)))
1209 return Error(IDLoc, "branch to misaligned address");
1211 case Mips::BEQZ16_MM:
1212 case Mips::BNEZ16_MM:
1213 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1214 Offset = Inst.getOperand(1);
1215 if (!Offset.isImm())
1216 break; // We'll deal with this situation later on when applying fixups.
1217 if (!isIntN(8, Offset.getImm()))
1218 return Error(IDLoc, "branch target out of range");
1219 if (OffsetToAlignment(Offset.getImm(), 2LL))
1220 return Error(IDLoc, "branch to misaligned address");
1225 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1226 // We still accept it but it is a normal nop.
1227 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1228 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1229 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1233 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1234 // If this instruction has a delay slot and .set reorder is active,
1235 // emit a NOP after it.
1236 Instructions.push_back(Inst);
1238 if (hasShortDelaySlot(Inst.getOpcode())) {
1239 NopInst.setOpcode(Mips::MOVE16_MM);
1240 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1241 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1243 NopInst.setOpcode(Mips::SLL);
1244 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1245 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1246 NopInst.addOperand(MCOperand::CreateImm(0));
1248 Instructions.push_back(NopInst);
1252 if (MCID.mayLoad() || MCID.mayStore()) {
1253 // Check the offset of memory operand, if it is a symbol
1254 // reference or immediate we may have to expand instructions.
1255 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1256 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1257 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1258 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1259 MCOperand &Op = Inst.getOperand(i);
1261 int MemOffset = Op.getImm();
1262 if (MemOffset < -32768 || MemOffset > 32767) {
1263 // Offset can't exceed 16bit value.
1264 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1267 } else if (Op.isExpr()) {
1268 const MCExpr *Expr = Op.getExpr();
1269 if (Expr->getKind() == MCExpr::SymbolRef) {
1270 const MCSymbolRefExpr *SR =
1271 static_cast<const MCSymbolRefExpr *>(Expr);
1272 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1274 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1277 } else if (!isEvaluated(Expr)) {
1278 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1286 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1287 if (inMicroMipsMode()) {
1291 switch (Inst.getOpcode()) {
1294 case Mips::ADDIUS5_MM:
1295 Opnd = Inst.getOperand(2);
1297 return Error(IDLoc, "expected immediate operand kind");
1298 Imm = Opnd.getImm();
1299 if (Imm < -8 || Imm > 7)
1300 return Error(IDLoc, "immediate operand value out of range");
1302 case Mips::ADDIUSP_MM:
1303 Opnd = Inst.getOperand(0);
1305 return Error(IDLoc, "expected immediate operand kind");
1306 Imm = Opnd.getImm();
1307 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1309 return Error(IDLoc, "immediate operand value out of range");
1311 case Mips::SLL16_MM:
1312 case Mips::SRL16_MM:
1313 Opnd = Inst.getOperand(2);
1315 return Error(IDLoc, "expected immediate operand kind");
1316 Imm = Opnd.getImm();
1317 if (Imm < 1 || Imm > 8)
1318 return Error(IDLoc, "immediate operand value out of range");
1321 Opnd = Inst.getOperand(1);
1323 return Error(IDLoc, "expected immediate operand kind");
1324 Imm = Opnd.getImm();
1325 if (Imm < -1 || Imm > 126)
1326 return Error(IDLoc, "immediate operand value out of range");
1328 case Mips::ADDIUR2_MM:
1329 Opnd = Inst.getOperand(2);
1331 return Error(IDLoc, "expected immediate operand kind");
1332 Imm = Opnd.getImm();
1333 if (!(Imm == 1 || Imm == -1 ||
1334 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1335 return Error(IDLoc, "immediate operand value out of range");
1337 case Mips::ADDIUR1SP_MM:
1338 Opnd = Inst.getOperand(1);
1340 return Error(IDLoc, "expected immediate operand kind");
1341 Imm = Opnd.getImm();
1342 if (OffsetToAlignment(Imm, 4LL))
1343 return Error(IDLoc, "misaligned immediate operand value");
1344 if (Imm < 0 || Imm > 255)
1345 return Error(IDLoc, "immediate operand value out of range");
1347 case Mips::ANDI16_MM:
1348 Opnd = Inst.getOperand(2);
1350 return Error(IDLoc, "expected immediate operand kind");
1351 Imm = Opnd.getImm();
1352 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1353 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1354 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1355 return Error(IDLoc, "immediate operand value out of range");
1357 case Mips::LBU16_MM:
1358 Opnd = Inst.getOperand(2);
1360 return Error(IDLoc, "expected immediate operand kind");
1361 Imm = Opnd.getImm();
1362 if (Imm < -1 || Imm > 14)
1363 return Error(IDLoc, "immediate operand value out of range");
1366 Opnd = Inst.getOperand(2);
1368 return Error(IDLoc, "expected immediate operand kind");
1369 Imm = Opnd.getImm();
1370 if (Imm < 0 || Imm > 15)
1371 return Error(IDLoc, "immediate operand value out of range");
1373 case Mips::LHU16_MM:
1375 Opnd = Inst.getOperand(2);
1377 return Error(IDLoc, "expected immediate operand kind");
1378 Imm = Opnd.getImm();
1379 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1380 return Error(IDLoc, "immediate operand value out of range");
1384 Opnd = Inst.getOperand(2);
1386 return Error(IDLoc, "expected immediate operand kind");
1387 Imm = Opnd.getImm();
1388 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1389 return Error(IDLoc, "immediate operand value out of range");
1393 Opnd = Inst.getOperand(2);
1395 return Error(IDLoc, "expected immediate operand kind");
1396 Imm = Opnd.getImm();
1397 if (!isUInt<5>(Imm))
1398 return Error(IDLoc, "immediate operand value out of range");
1400 case Mips::ADDIUPC_MM:
1401 MCOperand Opnd = Inst.getOperand(1);
1403 return Error(IDLoc, "expected immediate operand kind");
1404 int Imm = Opnd.getImm();
1405 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1406 return Error(IDLoc, "immediate operand value out of range");
1411 if (needsExpansion(Inst))
1412 return expandInstruction(Inst, IDLoc, Instructions);
1414 Instructions.push_back(Inst);
1419 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1421 switch (Inst.getOpcode()) {
1422 case Mips::LoadImm32Reg:
1423 case Mips::LoadAddr32Imm:
1424 case Mips::LoadAddr32Reg:
1425 case Mips::LoadImm64Reg:
1426 case Mips::B_MM_Pseudo:
1433 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1434 SmallVectorImpl<MCInst> &Instructions) {
1435 switch (Inst.getOpcode()) {
1436 default: llvm_unreachable("unimplemented expansion");
1437 case Mips::LoadImm32Reg:
1438 return expandLoadImm(Inst, IDLoc, Instructions);
1439 case Mips::LoadImm64Reg:
1441 Error(IDLoc, "instruction requires a 64-bit architecture");
1444 return expandLoadImm(Inst, IDLoc, Instructions);
1445 case Mips::LoadAddr32Imm:
1446 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1447 case Mips::LoadAddr32Reg:
1448 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1449 case Mips::B_MM_Pseudo:
1450 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1455 template <bool PerformShift>
1456 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1457 SmallVectorImpl<MCInst> &Instructions) {
1460 tmpInst.setOpcode(Mips::DSLL);
1461 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1462 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1463 tmpInst.addOperand(MCOperand::CreateImm(16));
1464 tmpInst.setLoc(IDLoc);
1465 Instructions.push_back(tmpInst);
1468 tmpInst.setOpcode(Mips::ORi);
1469 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1470 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1471 tmpInst.addOperand(Operand);
1472 tmpInst.setLoc(IDLoc);
1473 Instructions.push_back(tmpInst);
1476 template <int Shift, bool PerformShift>
1477 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1478 SmallVectorImpl<MCInst> &Instructions) {
1479 createShiftOr<PerformShift>(
1480 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1481 IDLoc, Instructions);
1485 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1486 SmallVectorImpl<MCInst> &Instructions) {
1488 const MCOperand &ImmOp = Inst.getOperand(1);
1489 assert(ImmOp.isImm() && "expected immediate operand kind");
1490 const MCOperand &RegOp = Inst.getOperand(0);
1491 assert(RegOp.isReg() && "expected register operand kind");
1493 int64_t ImmValue = ImmOp.getImm();
1494 tmpInst.setLoc(IDLoc);
1495 // FIXME: gas has a special case for values that are 000...1111, which
1496 // becomes a li -1 and then a dsrl
1497 if (0 <= ImmValue && ImmValue <= 65535) {
1498 // For 0 <= j <= 65535.
1499 // li d,j => ori d,$zero,j
1500 tmpInst.setOpcode(Mips::ORi);
1501 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1502 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1503 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1504 Instructions.push_back(tmpInst);
1505 } else if (ImmValue < 0 && ImmValue >= -32768) {
1506 // For -32768 <= j < 0.
1507 // li d,j => addiu d,$zero,j
1508 tmpInst.setOpcode(Mips::ADDiu);
1509 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1510 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1511 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1512 Instructions.push_back(tmpInst);
1513 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1514 // For any value of j that is representable as a 32-bit integer, create
1516 // li d,j => lui d,hi16(j)
1518 tmpInst.setOpcode(Mips::LUi);
1519 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1520 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1521 Instructions.push_back(tmpInst);
1522 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1523 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1525 Error(IDLoc, "instruction requires a 64-bit architecture");
1529 // <------- lo32 ------>
1530 // <------- hi32 ------>
1531 // <- hi16 -> <- lo16 ->
1532 // _________________________________
1534 // | 16-bytes | 16-bytes | 16-bytes |
1535 // |__________|__________|__________|
1537 // For any value of j that is representable as a 48-bit integer, create
1539 // li d,j => lui d,hi16(j)
1540 // ori d,d,hi16(lo32(j))
1542 // ori d,d,lo16(lo32(j))
1543 tmpInst.setOpcode(Mips::LUi);
1544 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1546 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1547 Instructions.push_back(tmpInst);
1548 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1549 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1552 Error(IDLoc, "instruction requires a 64-bit architecture");
1556 // <------- hi32 ------> <------- lo32 ------>
1557 // <- hi16 -> <- lo16 ->
1558 // ___________________________________________
1560 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1561 // |__________|__________|__________|__________|
1563 // For any value of j that isn't representable as a 48-bit integer.
1564 // li d,j => lui d,hi16(j)
1565 // ori d,d,lo16(hi32(j))
1567 // ori d,d,hi16(lo32(j))
1569 // ori d,d,lo16(lo32(j))
1570 tmpInst.setOpcode(Mips::LUi);
1571 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1573 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1574 Instructions.push_back(tmpInst);
1575 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1576 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1577 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1583 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1584 SmallVectorImpl<MCInst> &Instructions) {
1586 const MCOperand &ImmOp = Inst.getOperand(2);
1587 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1588 "expected immediate operand kind");
1589 if (!ImmOp.isImm()) {
1590 expandLoadAddressSym(Inst, IDLoc, Instructions);
1593 const MCOperand &SrcRegOp = Inst.getOperand(1);
1594 assert(SrcRegOp.isReg() && "expected register operand kind");
1595 const MCOperand &DstRegOp = Inst.getOperand(0);
1596 assert(DstRegOp.isReg() && "expected register operand kind");
1597 int ImmValue = ImmOp.getImm();
1598 if (-32768 <= ImmValue && ImmValue <= 65535) {
1599 // For -32768 <= j <= 65535.
1600 // la d,j(s) => addiu d,s,j
1601 tmpInst.setOpcode(Mips::ADDiu);
1602 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1603 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1604 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1605 Instructions.push_back(tmpInst);
1607 // For any other value of j that is representable as a 32-bit integer.
1608 // la d,j(s) => lui d,hi16(j)
1611 tmpInst.setOpcode(Mips::LUi);
1612 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1613 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1614 Instructions.push_back(tmpInst);
1616 tmpInst.setOpcode(Mips::ORi);
1617 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1618 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1619 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1620 Instructions.push_back(tmpInst);
1622 tmpInst.setOpcode(Mips::ADDu);
1623 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1624 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1625 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1626 Instructions.push_back(tmpInst);
1632 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1633 SmallVectorImpl<MCInst> &Instructions) {
1635 const MCOperand &ImmOp = Inst.getOperand(1);
1636 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1637 "expected immediate operand kind");
1638 if (!ImmOp.isImm()) {
1639 expandLoadAddressSym(Inst, IDLoc, Instructions);
1642 const MCOperand &RegOp = Inst.getOperand(0);
1643 assert(RegOp.isReg() && "expected register operand kind");
1644 int ImmValue = ImmOp.getImm();
1645 if (-32768 <= ImmValue && ImmValue <= 65535) {
1646 // For -32768 <= j <= 65535.
1647 // la d,j => addiu d,$zero,j
1648 tmpInst.setOpcode(Mips::ADDiu);
1649 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1650 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1651 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1652 Instructions.push_back(tmpInst);
1654 // For any other value of j that is representable as a 32-bit integer.
1655 // la d,j => lui d,hi16(j)
1657 tmpInst.setOpcode(Mips::LUi);
1658 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1659 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1660 Instructions.push_back(tmpInst);
1662 tmpInst.setOpcode(Mips::ORi);
1663 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1664 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1665 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1666 Instructions.push_back(tmpInst);
1672 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1673 SmallVectorImpl<MCInst> &Instructions) {
1674 // FIXME: If we do have a valid at register to use, we should generate a
1675 // slightly shorter sequence here.
1677 int ExprOperandNo = 1;
1678 // Sometimes the assembly parser will get the immediate expression as
1679 // a $zero + an immediate.
1680 if (Inst.getNumOperands() == 3) {
1681 assert(Inst.getOperand(1).getReg() ==
1682 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1685 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1686 assert(SymOp.isExpr() && "expected symbol operand kind");
1687 const MCOperand &RegOp = Inst.getOperand(0);
1688 unsigned RegNo = RegOp.getReg();
1689 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1690 const MCSymbolRefExpr *HiExpr =
1691 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1692 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1693 const MCSymbolRefExpr *LoExpr =
1694 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1695 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1697 // If it's a 64-bit architecture, expand to:
1698 // la d,sym => lui d,highest(sym)
1699 // ori d,d,higher(sym)
1701 // ori d,d,hi16(sym)
1703 // ori d,d,lo16(sym)
1704 const MCSymbolRefExpr *HighestExpr =
1705 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1706 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1707 const MCSymbolRefExpr *HigherExpr =
1708 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1709 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1711 tmpInst.setOpcode(Mips::LUi);
1712 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1713 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1714 Instructions.push_back(tmpInst);
1716 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1718 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1720 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1723 // Otherwise, expand to:
1724 // la d,sym => lui d,hi16(sym)
1725 // ori d,d,lo16(sym)
1726 tmpInst.setOpcode(Mips::LUi);
1727 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1728 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1729 Instructions.push_back(tmpInst);
1731 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1736 bool MipsAsmParser::expandUncondBranchMMPseudo(
1737 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1738 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1739 "unexpected number of operands");
1741 MCOperand Offset = Inst.getOperand(0);
1742 if (Offset.isExpr()) {
1744 Inst.setOpcode(Mips::BEQ_MM);
1745 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1746 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1747 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1749 assert(Offset.isImm() && "expected immediate operand kind");
1750 if (isIntN(11, Offset.getImm())) {
1751 // If offset fits into 11 bits then this instruction becomes microMIPS
1752 // 16-bit unconditional branch instruction.
1753 Inst.setOpcode(Mips::B16_MM);
1755 if (!isIntN(17, Offset.getImm()))
1756 Error(IDLoc, "branch target out of range");
1757 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1758 Error(IDLoc, "branch to misaligned address");
1760 Inst.setOpcode(Mips::BEQ_MM);
1761 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1762 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1763 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1766 Instructions.push_back(Inst);
1768 if (AssemblerOptions.back()->isReorder()) {
1769 // If .set reorder is active, emit a NOP after the branch instruction.
1771 NopInst.setOpcode(Mips::MOVE16_MM);
1772 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1773 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1774 Instructions.push_back(NopInst);
1779 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1780 SmallVectorImpl<MCInst> &Instructions,
1781 bool isLoad, bool isImmOpnd) {
1782 const MCSymbolRefExpr *SR;
1784 unsigned ImmOffset, HiOffset, LoOffset;
1785 const MCExpr *ExprOffset;
1787 // 1st operand is either the source or destination register.
1788 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1789 unsigned RegOpNum = Inst.getOperand(0).getReg();
1790 // 2nd operand is the base register.
1791 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1792 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1793 // 3rd operand is either an immediate or expression.
1795 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1796 ImmOffset = Inst.getOperand(2).getImm();
1797 LoOffset = ImmOffset & 0x0000ffff;
1798 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1799 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1800 if (LoOffset & 0x8000)
1803 ExprOffset = Inst.getOperand(2).getExpr();
1804 // All instructions will have the same location.
1805 TempInst.setLoc(IDLoc);
1806 // These are some of the types of expansions we perform here:
1807 // 1) lw $8, sym => lui $8, %hi(sym)
1808 // lw $8, %lo(sym)($8)
1809 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1811 // lw $8, %lo(offset)($9)
1812 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1814 // lw $8, %lo(offset)($at)
1815 // 4) sw $8, sym => lui $at, %hi(sym)
1816 // sw $8, %lo(sym)($at)
1817 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1819 // sw $8, %lo(offset)($at)
1820 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1821 // ldc1 $f0, %lo(sym)($at)
1823 // For load instructions we can use the destination register as a temporary
1824 // if base and dst are different (examples 1 and 2) and if the base register
1825 // is general purpose otherwise we must use $at (example 6) and error if it's
1826 // not available. For stores we must use $at (examples 4 and 5) because we
1827 // must not clobber the source register setting up the offset.
1828 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1829 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1830 unsigned RegClassIDOp0 =
1831 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1832 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1833 (RegClassIDOp0 == Mips::GPR64RegClassID);
1834 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1835 TmpRegNum = RegOpNum;
1837 int AT = getATReg(IDLoc);
1838 // At this point we need AT to perform the expansions and we exit if it is
1843 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1846 TempInst.setOpcode(Mips::LUi);
1847 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1849 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1851 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1852 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1853 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1854 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1856 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1858 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1859 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1862 // Add the instruction to the list.
1863 Instructions.push_back(TempInst);
1864 // Prepare TempInst for next instruction.
1866 // Add temp register to base.
1867 TempInst.setOpcode(Mips::ADDu);
1868 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1869 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1870 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1871 Instructions.push_back(TempInst);
1873 // And finally, create original instruction with low part
1874 // of offset and new base.
1875 TempInst.setOpcode(Inst.getOpcode());
1876 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1877 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1879 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1881 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1882 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1883 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1885 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1887 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1888 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1891 Instructions.push_back(TempInst);
1895 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1896 // As described by the Mips32r2 spec, the registers Rd and Rs for
1897 // jalr.hb must be different.
1898 unsigned Opcode = Inst.getOpcode();
1900 if (Opcode == Mips::JALR_HB &&
1901 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1902 return Match_RequiresDifferentSrcAndDst;
1904 return Match_Success;
1907 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1908 OperandVector &Operands,
1910 uint64_t &ErrorInfo,
1911 bool MatchingInlineAsm) {
1914 SmallVector<MCInst, 8> Instructions;
1915 unsigned MatchResult =
1916 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1918 switch (MatchResult) {
1919 case Match_Success: {
1920 if (processInstruction(Inst, IDLoc, Instructions))
1922 for (unsigned i = 0; i < Instructions.size(); i++)
1923 Out.EmitInstruction(Instructions[i], STI);
1926 case Match_MissingFeature:
1927 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1929 case Match_InvalidOperand: {
1930 SMLoc ErrorLoc = IDLoc;
1931 if (ErrorInfo != ~0ULL) {
1932 if (ErrorInfo >= Operands.size())
1933 return Error(IDLoc, "too few operands for instruction");
1935 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1936 if (ErrorLoc == SMLoc())
1940 return Error(ErrorLoc, "invalid operand for instruction");
1942 case Match_MnemonicFail:
1943 return Error(IDLoc, "invalid instruction");
1944 case Match_RequiresDifferentSrcAndDst:
1945 return Error(IDLoc, "source and destination must be different");
1948 llvm_unreachable("Implement any new match types added!");
1951 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1952 if ((RegIndex != 0) &&
1953 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1955 Warning(Loc, "used $at without \".set noat\"");
1957 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1958 Twine(RegIndex) + "\"");
1963 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1964 SMRange Range, bool ShowColors) {
1965 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1966 Range, SMFixIt(Range, FixMsg),
1970 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1973 CC = StringSwitch<unsigned>(Name)
2009 if (!(isABI_N32() || isABI_N64()))
2012 if (12 <= CC && CC <= 15) {
2013 // Name is one of t4-t7
2014 AsmToken RegTok = getLexer().peekTok();
2015 SMRange RegRange = RegTok.getLocRange();
2017 StringRef FixedName = StringSwitch<StringRef>(Name)
2023 assert(FixedName != "" && "Register name is not one of t4-t7.");
2025 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2026 "Did you mean $" + FixedName + "?", RegRange);
2029 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2030 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2031 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2032 if (8 <= CC && CC <= 11)
2036 CC = StringSwitch<unsigned>(Name)
2048 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2051 CC = StringSwitch<unsigned>(Name)
2052 .Case("hwr_cpunum", 0)
2053 .Case("hwr_synci_step", 1)
2055 .Case("hwr_ccres", 3)
2056 .Case("hwr_ulr", 29)
2062 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2064 if (Name[0] == 'f') {
2065 StringRef NumString = Name.substr(1);
2067 if (NumString.getAsInteger(10, IntVal))
2068 return -1; // This is not an integer.
2069 if (IntVal > 31) // Maximum index for fpu register.
2076 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2078 if (Name.startswith("fcc")) {
2079 StringRef NumString = Name.substr(3);
2081 if (NumString.getAsInteger(10, IntVal))
2082 return -1; // This is not an integer.
2083 if (IntVal > 7) // There are only 8 fcc registers.
2090 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2092 if (Name.startswith("ac")) {
2093 StringRef NumString = Name.substr(2);
2095 if (NumString.getAsInteger(10, IntVal))
2096 return -1; // This is not an integer.
2097 if (IntVal > 3) // There are only 3 acc registers.
2104 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2107 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2116 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2119 CC = StringSwitch<unsigned>(Name)
2122 .Case("msaaccess", 2)
2124 .Case("msamodify", 4)
2125 .Case("msarequest", 5)
2127 .Case("msaunmap", 7)
2133 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2141 int MipsAsmParser::getATReg(SMLoc Loc) {
2142 int AT = AssemblerOptions.back()->getATRegNum();
2144 reportParseError(Loc,
2145 "pseudo-instruction requires $at, which is not available");
2149 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2150 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2153 unsigned MipsAsmParser::getGPR(int RegNo) {
2154 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2158 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2160 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2163 return getReg(RegClass, RegNum);
2166 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2167 MCAsmParser &Parser = getParser();
2168 DEBUG(dbgs() << "parseOperand\n");
2170 // Check if the current operand has a custom associated parser, if so, try to
2171 // custom parse the operand, or fallback to the general approach.
2172 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2173 if (ResTy == MatchOperand_Success)
2175 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2176 // there was a match, but an error occurred, in which case, just return that
2177 // the operand parsing failed.
2178 if (ResTy == MatchOperand_ParseFail)
2181 DEBUG(dbgs() << ".. Generic Parser\n");
2183 switch (getLexer().getKind()) {
2185 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2187 case AsmToken::Dollar: {
2188 // Parse the register.
2189 SMLoc S = Parser.getTok().getLoc();
2191 // Almost all registers have been parsed by custom parsers. There is only
2192 // one exception to this. $zero (and it's alias $0) will reach this point
2193 // for div, divu, and similar instructions because it is not an operand
2194 // to the instruction definition but an explicit register. Special case
2195 // this situation for now.
2196 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2199 // Maybe it is a symbol reference.
2200 StringRef Identifier;
2201 if (Parser.parseIdentifier(Identifier))
2204 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2205 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2206 // Otherwise create a symbol reference.
2208 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2210 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2213 // Else drop to expression parsing.
2214 case AsmToken::LParen:
2215 case AsmToken::Minus:
2216 case AsmToken::Plus:
2217 case AsmToken::Integer:
2218 case AsmToken::Tilde:
2219 case AsmToken::String: {
2220 DEBUG(dbgs() << ".. generic integer\n");
2221 OperandMatchResultTy ResTy = parseImm(Operands);
2222 return ResTy != MatchOperand_Success;
2224 case AsmToken::Percent: {
2225 // It is a symbol reference or constant expression.
2226 const MCExpr *IdVal;
2227 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2228 if (parseRelocOperand(IdVal))
2231 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2233 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2235 } // case AsmToken::Percent
2236 } // switch(getLexer().getKind())
2240 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2241 StringRef RelocStr) {
2243 // Check the type of the expression.
2244 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2245 // It's a constant, evaluate reloc value.
2247 switch (getVariantKind(RelocStr)) {
2248 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2249 // Get the 1st 16-bits.
2250 Val = MCE->getValue() & 0xffff;
2252 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2253 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2254 // 16 bits being negative.
2255 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2257 case MCSymbolRefExpr::VK_Mips_HIGHER:
2258 // Get the 3rd 16-bits.
2259 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2261 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2262 // Get the 4th 16-bits.
2263 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2266 report_fatal_error("unsupported reloc value");
2268 return MCConstantExpr::Create(Val, getContext());
2271 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2272 // It's a symbol, create a symbolic expression from the symbol.
2273 StringRef Symbol = MSRE->getSymbol().getName();
2274 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2275 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2279 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2280 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2282 // Try to create target expression.
2283 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2284 return MipsMCExpr::Create(VK, Expr, getContext());
2286 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2287 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2288 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2292 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2293 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2294 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2297 // Just return the original expression.
2301 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2303 switch (Expr->getKind()) {
2304 case MCExpr::Constant:
2306 case MCExpr::SymbolRef:
2307 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2308 case MCExpr::Binary:
2309 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2310 if (!isEvaluated(BE->getLHS()))
2312 return isEvaluated(BE->getRHS());
2315 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2316 case MCExpr::Target:
2322 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2323 MCAsmParser &Parser = getParser();
2324 Parser.Lex(); // Eat the % token.
2325 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2326 if (Tok.isNot(AsmToken::Identifier))
2329 std::string Str = Tok.getIdentifier().str();
2331 Parser.Lex(); // Eat the identifier.
2332 // Now make an expression from the rest of the operand.
2333 const MCExpr *IdVal;
2336 if (getLexer().getKind() == AsmToken::LParen) {
2338 Parser.Lex(); // Eat the '(' token.
2339 if (getLexer().getKind() == AsmToken::Percent) {
2340 Parser.Lex(); // Eat the % token.
2341 const AsmToken &nextTok = Parser.getTok();
2342 if (nextTok.isNot(AsmToken::Identifier))
2345 Str += nextTok.getIdentifier();
2346 Parser.Lex(); // Eat the identifier.
2347 if (getLexer().getKind() != AsmToken::LParen)
2352 if (getParser().parseParenExpression(IdVal, EndLoc))
2355 while (getLexer().getKind() == AsmToken::RParen)
2356 Parser.Lex(); // Eat the ')' token.
2359 return true; // Parenthesis must follow the relocation operand.
2361 Res = evaluateRelocExpr(IdVal, Str);
2365 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2367 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2368 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2369 if (ResTy == MatchOperand_Success) {
2370 assert(Operands.size() == 1);
2371 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2372 StartLoc = Operand.getStartLoc();
2373 EndLoc = Operand.getEndLoc();
2375 // AFAIK, we only support numeric registers and named GPR's in CFI
2377 // Don't worry about eating tokens before failing. Using an unrecognised
2378 // register is a parse error.
2379 if (Operand.isGPRAsmReg()) {
2380 // Resolve to GPR32 or GPR64 appropriately.
2381 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2384 return (RegNo == (unsigned)-1);
2387 assert(Operands.size() == 0);
2388 return (RegNo == (unsigned)-1);
2391 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2392 MCAsmParser &Parser = getParser();
2396 while (getLexer().getKind() == AsmToken::LParen)
2399 switch (getLexer().getKind()) {
2402 case AsmToken::Identifier:
2403 case AsmToken::LParen:
2404 case AsmToken::Integer:
2405 case AsmToken::Minus:
2406 case AsmToken::Plus:
2408 Result = getParser().parseParenExpression(Res, S);
2410 Result = (getParser().parseExpression(Res));
2411 while (getLexer().getKind() == AsmToken::RParen)
2414 case AsmToken::Percent:
2415 Result = parseRelocOperand(Res);
2420 MipsAsmParser::OperandMatchResultTy
2421 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2422 MCAsmParser &Parser = getParser();
2423 DEBUG(dbgs() << "parseMemOperand\n");
2424 const MCExpr *IdVal = nullptr;
2426 bool isParenExpr = false;
2427 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2428 // First operand is the offset.
2429 S = Parser.getTok().getLoc();
2431 if (getLexer().getKind() == AsmToken::LParen) {
2436 if (getLexer().getKind() != AsmToken::Dollar) {
2437 if (parseMemOffset(IdVal, isParenExpr))
2438 return MatchOperand_ParseFail;
2440 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2441 if (Tok.isNot(AsmToken::LParen)) {
2442 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2443 if (Mnemonic.getToken() == "la") {
2445 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2446 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2447 return MatchOperand_Success;
2449 if (Tok.is(AsmToken::EndOfStatement)) {
2451 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2453 // Zero register assumed, add a memory operand with ZERO as its base.
2454 // "Base" will be managed by k_Memory.
2455 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2458 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2459 return MatchOperand_Success;
2461 Error(Parser.getTok().getLoc(), "'(' expected");
2462 return MatchOperand_ParseFail;
2465 Parser.Lex(); // Eat the '(' token.
2468 Res = parseAnyRegister(Operands);
2469 if (Res != MatchOperand_Success)
2472 if (Parser.getTok().isNot(AsmToken::RParen)) {
2473 Error(Parser.getTok().getLoc(), "')' expected");
2474 return MatchOperand_ParseFail;
2477 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2479 Parser.Lex(); // Eat the ')' token.
2482 IdVal = MCConstantExpr::Create(0, getContext());
2484 // Replace the register operand with the memory operand.
2485 std::unique_ptr<MipsOperand> op(
2486 static_cast<MipsOperand *>(Operands.back().release()));
2487 // Remove the register from the operands.
2488 // "op" will be managed by k_Memory.
2489 Operands.pop_back();
2490 // Add the memory operand.
2491 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2493 if (IdVal->EvaluateAsAbsolute(Imm))
2494 IdVal = MCConstantExpr::Create(Imm, getContext());
2495 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2496 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2500 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2501 return MatchOperand_Success;
2504 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2505 MCAsmParser &Parser = getParser();
2506 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2508 SMLoc S = Parser.getTok().getLoc();
2510 if (Sym->isVariable())
2511 Expr = Sym->getVariableValue();
2514 if (Expr->getKind() == MCExpr::SymbolRef) {
2515 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2516 StringRef DefSymbol = Ref->getSymbol().getName();
2517 if (DefSymbol.startswith("$")) {
2518 OperandMatchResultTy ResTy =
2519 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2520 if (ResTy == MatchOperand_Success) {
2523 } else if (ResTy == MatchOperand_ParseFail)
2524 llvm_unreachable("Should never ParseFail");
2527 } else if (Expr->getKind() == MCExpr::Constant) {
2529 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2531 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2538 MipsAsmParser::OperandMatchResultTy
2539 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2540 StringRef Identifier,
2542 int Index = matchCPURegisterName(Identifier);
2544 Operands.push_back(MipsOperand::createGPRReg(
2545 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2546 return MatchOperand_Success;
2549 Index = matchHWRegsRegisterName(Identifier);
2551 Operands.push_back(MipsOperand::createHWRegsReg(
2552 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2553 return MatchOperand_Success;
2556 Index = matchFPURegisterName(Identifier);
2558 Operands.push_back(MipsOperand::createFGRReg(
2559 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2560 return MatchOperand_Success;
2563 Index = matchFCCRegisterName(Identifier);
2565 Operands.push_back(MipsOperand::createFCCReg(
2566 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2567 return MatchOperand_Success;
2570 Index = matchACRegisterName(Identifier);
2572 Operands.push_back(MipsOperand::createACCReg(
2573 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2574 return MatchOperand_Success;
2577 Index = matchMSA128RegisterName(Identifier);
2579 Operands.push_back(MipsOperand::createMSA128Reg(
2580 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2581 return MatchOperand_Success;
2584 Index = matchMSA128CtrlRegisterName(Identifier);
2586 Operands.push_back(MipsOperand::createMSACtrlReg(
2587 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2588 return MatchOperand_Success;
2591 return MatchOperand_NoMatch;
2594 MipsAsmParser::OperandMatchResultTy
2595 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2596 MCAsmParser &Parser = getParser();
2597 auto Token = Parser.getLexer().peekTok(false);
2599 if (Token.is(AsmToken::Identifier)) {
2600 DEBUG(dbgs() << ".. identifier\n");
2601 StringRef Identifier = Token.getIdentifier();
2602 OperandMatchResultTy ResTy =
2603 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2605 } else if (Token.is(AsmToken::Integer)) {
2606 DEBUG(dbgs() << ".. integer\n");
2607 Operands.push_back(MipsOperand::createNumericReg(
2608 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2610 return MatchOperand_Success;
2613 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2615 return MatchOperand_NoMatch;
2618 MipsAsmParser::OperandMatchResultTy
2619 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2620 MCAsmParser &Parser = getParser();
2621 DEBUG(dbgs() << "parseAnyRegister\n");
2623 auto Token = Parser.getTok();
2625 SMLoc S = Token.getLoc();
2627 if (Token.isNot(AsmToken::Dollar)) {
2628 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2629 if (Token.is(AsmToken::Identifier)) {
2630 if (searchSymbolAlias(Operands))
2631 return MatchOperand_Success;
2633 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2634 return MatchOperand_NoMatch;
2636 DEBUG(dbgs() << ".. $\n");
2638 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2639 if (ResTy == MatchOperand_Success) {
2641 Parser.Lex(); // identifier
2646 MipsAsmParser::OperandMatchResultTy
2647 MipsAsmParser::parseImm(OperandVector &Operands) {
2648 MCAsmParser &Parser = getParser();
2649 switch (getLexer().getKind()) {
2651 return MatchOperand_NoMatch;
2652 case AsmToken::LParen:
2653 case AsmToken::Minus:
2654 case AsmToken::Plus:
2655 case AsmToken::Integer:
2656 case AsmToken::Tilde:
2657 case AsmToken::String:
2661 const MCExpr *IdVal;
2662 SMLoc S = Parser.getTok().getLoc();
2663 if (getParser().parseExpression(IdVal))
2664 return MatchOperand_ParseFail;
2666 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2667 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2668 return MatchOperand_Success;
2671 MipsAsmParser::OperandMatchResultTy
2672 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2673 MCAsmParser &Parser = getParser();
2674 DEBUG(dbgs() << "parseJumpTarget\n");
2676 SMLoc S = getLexer().getLoc();
2678 // Integers and expressions are acceptable
2679 OperandMatchResultTy ResTy = parseImm(Operands);
2680 if (ResTy != MatchOperand_NoMatch)
2683 // Registers are a valid target and have priority over symbols.
2684 ResTy = parseAnyRegister(Operands);
2685 if (ResTy != MatchOperand_NoMatch)
2688 const MCExpr *Expr = nullptr;
2689 if (Parser.parseExpression(Expr)) {
2690 // We have no way of knowing if a symbol was consumed so we must ParseFail
2691 return MatchOperand_ParseFail;
2694 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2695 return MatchOperand_Success;
2698 MipsAsmParser::OperandMatchResultTy
2699 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2700 MCAsmParser &Parser = getParser();
2701 const MCExpr *IdVal;
2702 // If the first token is '$' we may have register operand.
2703 if (Parser.getTok().is(AsmToken::Dollar))
2704 return MatchOperand_NoMatch;
2705 SMLoc S = Parser.getTok().getLoc();
2706 if (getParser().parseExpression(IdVal))
2707 return MatchOperand_ParseFail;
2708 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2709 assert(MCE && "Unexpected MCExpr type.");
2710 int64_t Val = MCE->getValue();
2711 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2712 Operands.push_back(MipsOperand::CreateImm(
2713 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2714 return MatchOperand_Success;
2717 MipsAsmParser::OperandMatchResultTy
2718 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2719 MCAsmParser &Parser = getParser();
2720 switch (getLexer().getKind()) {
2722 return MatchOperand_NoMatch;
2723 case AsmToken::LParen:
2724 case AsmToken::Plus:
2725 case AsmToken::Minus:
2726 case AsmToken::Integer:
2731 SMLoc S = Parser.getTok().getLoc();
2733 if (getParser().parseExpression(Expr))
2734 return MatchOperand_ParseFail;
2737 if (!Expr->EvaluateAsAbsolute(Val)) {
2738 Error(S, "expected immediate value");
2739 return MatchOperand_ParseFail;
2742 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2743 // and because the CPU always adds one to the immediate field, the allowed
2744 // range becomes 1..4. We'll only check the range here and will deal
2745 // with the addition/subtraction when actually decoding/encoding
2747 if (Val < 1 || Val > 4) {
2748 Error(S, "immediate not in range (1..4)");
2749 return MatchOperand_ParseFail;
2753 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2754 return MatchOperand_Success;
2757 MipsAsmParser::OperandMatchResultTy
2758 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2759 MCAsmParser &Parser = getParser();
2760 SmallVector<unsigned, 10> Regs;
2762 unsigned PrevReg = Mips::NoRegister;
2763 bool RegRange = false;
2764 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2766 if (Parser.getTok().isNot(AsmToken::Dollar))
2767 return MatchOperand_ParseFail;
2769 SMLoc S = Parser.getTok().getLoc();
2770 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2771 SMLoc E = getLexer().getLoc();
2772 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2773 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2775 // Remove last register operand because registers from register range
2776 // should be inserted first.
2777 if (RegNo == Mips::RA) {
2778 Regs.push_back(RegNo);
2780 unsigned TmpReg = PrevReg + 1;
2781 while (TmpReg <= RegNo) {
2782 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2783 Error(E, "invalid register operand");
2784 return MatchOperand_ParseFail;
2788 Regs.push_back(TmpReg++);
2794 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2795 (RegNo != Mips::RA)) {
2796 Error(E, "$16 or $31 expected");
2797 return MatchOperand_ParseFail;
2798 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2799 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2800 Error(E, "invalid register operand");
2801 return MatchOperand_ParseFail;
2802 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2803 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2804 Error(E, "consecutive register numbers expected");
2805 return MatchOperand_ParseFail;
2808 Regs.push_back(RegNo);
2811 if (Parser.getTok().is(AsmToken::Minus))
2814 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2815 !Parser.getTok().isNot(AsmToken::Comma)) {
2816 Error(E, "',' or '-' expected");
2817 return MatchOperand_ParseFail;
2820 Lex(); // Consume comma or minus
2821 if (Parser.getTok().isNot(AsmToken::Dollar))
2827 SMLoc E = Parser.getTok().getLoc();
2828 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2829 parseMemOperand(Operands);
2830 return MatchOperand_Success;
2833 MipsAsmParser::OperandMatchResultTy
2834 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
2835 MCAsmParser &Parser = getParser();
2837 SMLoc S = Parser.getTok().getLoc();
2838 if (parseAnyRegister(Operands) != MatchOperand_Success)
2839 return MatchOperand_ParseFail;
2841 SMLoc E = Parser.getTok().getLoc();
2842 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
2843 unsigned Reg = Op.getGPR32Reg();
2844 Operands.pop_back();
2845 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
2846 return MatchOperand_Success;
2849 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2851 MCSymbolRefExpr::VariantKind VK =
2852 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2853 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2854 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2855 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2856 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2857 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2858 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2859 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2860 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2861 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2862 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2863 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2864 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2865 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2866 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2867 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2868 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2869 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2870 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2871 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2872 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2873 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2874 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2875 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2876 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2877 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2878 .Default(MCSymbolRefExpr::VK_None);
2880 assert(VK != MCSymbolRefExpr::VK_None);
2885 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2887 /// ::= '(', register, ')'
2888 /// handle it before we iterate so we don't get tripped up by the lack of
2890 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2891 MCAsmParser &Parser = getParser();
2892 if (getLexer().is(AsmToken::LParen)) {
2894 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2896 if (parseOperand(Operands, Name)) {
2897 SMLoc Loc = getLexer().getLoc();
2898 Parser.eatToEndOfStatement();
2899 return Error(Loc, "unexpected token in argument list");
2901 if (Parser.getTok().isNot(AsmToken::RParen)) {
2902 SMLoc Loc = getLexer().getLoc();
2903 Parser.eatToEndOfStatement();
2904 return Error(Loc, "unexpected token, expected ')'");
2907 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2913 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2914 /// either one of these.
2915 /// ::= '[', register, ']'
2916 /// ::= '[', integer, ']'
2917 /// handle it before we iterate so we don't get tripped up by the lack of
2919 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2920 OperandVector &Operands) {
2921 MCAsmParser &Parser = getParser();
2922 if (getLexer().is(AsmToken::LBrac)) {
2924 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2926 if (parseOperand(Operands, Name)) {
2927 SMLoc Loc = getLexer().getLoc();
2928 Parser.eatToEndOfStatement();
2929 return Error(Loc, "unexpected token in argument list");
2931 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2932 SMLoc Loc = getLexer().getLoc();
2933 Parser.eatToEndOfStatement();
2934 return Error(Loc, "unexpected token, expected ']'");
2937 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2943 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2944 SMLoc NameLoc, OperandVector &Operands) {
2945 MCAsmParser &Parser = getParser();
2946 DEBUG(dbgs() << "ParseInstruction\n");
2948 // We have reached first instruction, module directive are now forbidden.
2949 getTargetStreamer().forbidModuleDirective();
2951 // Check if we have valid mnemonic
2952 if (!mnemonicIsValid(Name, 0)) {
2953 Parser.eatToEndOfStatement();
2954 return Error(NameLoc, "unknown instruction");
2956 // First operand in MCInst is instruction mnemonic.
2957 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2959 // Read the remaining operands.
2960 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2961 // Read the first operand.
2962 if (parseOperand(Operands, Name)) {
2963 SMLoc Loc = getLexer().getLoc();
2964 Parser.eatToEndOfStatement();
2965 return Error(Loc, "unexpected token in argument list");
2967 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2969 // AFAIK, parenthesis suffixes are never on the first operand
2971 while (getLexer().is(AsmToken::Comma)) {
2972 Parser.Lex(); // Eat the comma.
2973 // Parse and remember the operand.
2974 if (parseOperand(Operands, Name)) {
2975 SMLoc Loc = getLexer().getLoc();
2976 Parser.eatToEndOfStatement();
2977 return Error(Loc, "unexpected token in argument list");
2979 // Parse bracket and parenthesis suffixes before we iterate
2980 if (getLexer().is(AsmToken::LBrac)) {
2981 if (parseBracketSuffix(Name, Operands))
2983 } else if (getLexer().is(AsmToken::LParen) &&
2984 parseParenSuffix(Name, Operands))
2988 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2989 SMLoc Loc = getLexer().getLoc();
2990 Parser.eatToEndOfStatement();
2991 return Error(Loc, "unexpected token in argument list");
2993 Parser.Lex(); // Consume the EndOfStatement.
2997 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2998 MCAsmParser &Parser = getParser();
2999 SMLoc Loc = getLexer().getLoc();
3000 Parser.eatToEndOfStatement();
3001 return Error(Loc, ErrorMsg);
3004 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3005 return Error(Loc, ErrorMsg);
3008 bool MipsAsmParser::parseSetNoAtDirective() {
3009 MCAsmParser &Parser = getParser();
3010 // Line should look like: ".set noat".
3012 AssemblerOptions.back()->setATReg(0);
3015 // If this is not the end of the statement, report an error.
3016 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3017 reportParseError("unexpected token, expected end of statement");
3020 Parser.Lex(); // Consume the EndOfStatement.
3024 bool MipsAsmParser::parseSetAtDirective() {
3025 MCAsmParser &Parser = getParser();
3026 // Line can be .set at - defaults to $1
3030 if (getLexer().is(AsmToken::EndOfStatement)) {
3031 AssemblerOptions.back()->setATReg(1);
3032 Parser.Lex(); // Consume the EndOfStatement.
3034 } else if (getLexer().is(AsmToken::Equal)) {
3035 getParser().Lex(); // Eat the '='.
3036 if (getLexer().isNot(AsmToken::Dollar)) {
3037 reportParseError("unexpected token, expected dollar sign '$'");
3040 Parser.Lex(); // Eat the '$'.
3041 const AsmToken &Reg = Parser.getTok();
3042 if (Reg.is(AsmToken::Identifier)) {
3043 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3044 } else if (Reg.is(AsmToken::Integer)) {
3045 AtRegNo = Reg.getIntVal();
3047 reportParseError("unexpected token, expected identifier or integer");
3051 if (AtRegNo < 0 || AtRegNo > 31) {
3052 reportParseError("unexpected token in statement");
3056 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3057 reportParseError("invalid register");
3060 getParser().Lex(); // Eat the register.
3062 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3063 reportParseError("unexpected token, expected end of statement");
3066 Parser.Lex(); // Consume the EndOfStatement.
3069 reportParseError("unexpected token in statement");
3074 bool MipsAsmParser::parseSetReorderDirective() {
3075 MCAsmParser &Parser = getParser();
3077 // If this is not the end of the statement, report an error.
3078 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3079 reportParseError("unexpected token, expected end of statement");
3082 AssemblerOptions.back()->setReorder();
3083 getTargetStreamer().emitDirectiveSetReorder();
3084 Parser.Lex(); // Consume the EndOfStatement.
3088 bool MipsAsmParser::parseSetNoReorderDirective() {
3089 MCAsmParser &Parser = getParser();
3091 // If this is not the end of the statement, report an error.
3092 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3093 reportParseError("unexpected token, expected end of statement");
3096 AssemblerOptions.back()->setNoReorder();
3097 getTargetStreamer().emitDirectiveSetNoReorder();
3098 Parser.Lex(); // Consume the EndOfStatement.
3102 bool MipsAsmParser::parseSetMacroDirective() {
3103 MCAsmParser &Parser = getParser();
3105 // If this is not the end of the statement, report an error.
3106 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3107 reportParseError("unexpected token, expected end of statement");
3110 AssemblerOptions.back()->setMacro();
3111 Parser.Lex(); // Consume the EndOfStatement.
3115 bool MipsAsmParser::parseSetNoMacroDirective() {
3116 MCAsmParser &Parser = getParser();
3118 // If this is not the end of the statement, report an error.
3119 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3120 reportParseError("unexpected token, expected end of statement");
3123 if (AssemblerOptions.back()->isReorder()) {
3124 reportParseError("`noreorder' must be set before `nomacro'");
3127 AssemblerOptions.back()->setNoMacro();
3128 Parser.Lex(); // Consume the EndOfStatement.
3132 bool MipsAsmParser::parseSetMsaDirective() {
3133 MCAsmParser &Parser = getParser();
3136 // If this is not the end of the statement, report an error.
3137 if (getLexer().isNot(AsmToken::EndOfStatement))
3138 return reportParseError("unexpected token, expected end of statement");
3140 setFeatureBits(Mips::FeatureMSA, "msa");
3141 getTargetStreamer().emitDirectiveSetMsa();
3145 bool MipsAsmParser::parseSetNoMsaDirective() {
3146 MCAsmParser &Parser = getParser();
3149 // If this is not the end of the statement, report an error.
3150 if (getLexer().isNot(AsmToken::EndOfStatement))
3151 return reportParseError("unexpected token, expected end of statement");
3153 clearFeatureBits(Mips::FeatureMSA, "msa");
3154 getTargetStreamer().emitDirectiveSetNoMsa();
3158 bool MipsAsmParser::parseSetNoDspDirective() {
3159 MCAsmParser &Parser = getParser();
3160 Parser.Lex(); // Eat "nodsp".
3162 // If this is not the end of the statement, report an error.
3163 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3164 reportParseError("unexpected token, expected end of statement");
3168 clearFeatureBits(Mips::FeatureDSP, "dsp");
3169 getTargetStreamer().emitDirectiveSetNoDsp();
3173 bool MipsAsmParser::parseSetMips16Directive() {
3174 MCAsmParser &Parser = getParser();
3175 Parser.Lex(); // Eat "mips16".
3177 // If this is not the end of the statement, report an error.
3178 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3179 reportParseError("unexpected token, expected end of statement");
3183 setFeatureBits(Mips::FeatureMips16, "mips16");
3184 getTargetStreamer().emitDirectiveSetMips16();
3185 Parser.Lex(); // Consume the EndOfStatement.
3189 bool MipsAsmParser::parseSetNoMips16Directive() {
3190 MCAsmParser &Parser = getParser();
3191 Parser.Lex(); // Eat "nomips16".
3193 // If this is not the end of the statement, report an error.
3194 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3195 reportParseError("unexpected token, expected end of statement");
3199 clearFeatureBits(Mips::FeatureMips16, "mips16");
3200 getTargetStreamer().emitDirectiveSetNoMips16();
3201 Parser.Lex(); // Consume the EndOfStatement.
3205 bool MipsAsmParser::parseSetFpDirective() {
3206 MCAsmParser &Parser = getParser();
3207 MipsABIFlagsSection::FpABIKind FpAbiVal;
3208 // Line can be: .set fp=32
3211 Parser.Lex(); // Eat fp token
3212 AsmToken Tok = Parser.getTok();
3213 if (Tok.isNot(AsmToken::Equal)) {
3214 reportParseError("unexpected token, expected equals sign '='");
3217 Parser.Lex(); // Eat '=' token.
3218 Tok = Parser.getTok();
3220 if (!parseFpABIValue(FpAbiVal, ".set"))
3223 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3224 reportParseError("unexpected token, expected end of statement");
3227 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3228 Parser.Lex(); // Consume the EndOfStatement.
3232 bool MipsAsmParser::parseSetPopDirective() {
3233 MCAsmParser &Parser = getParser();
3234 SMLoc Loc = getLexer().getLoc();
3237 if (getLexer().isNot(AsmToken::EndOfStatement))
3238 return reportParseError("unexpected token, expected end of statement");
3240 // Always keep an element on the options "stack" to prevent the user
3241 // from changing the initial options. This is how we remember them.
3242 if (AssemblerOptions.size() == 2)
3243 return reportParseError(Loc, ".set pop with no .set push");
3245 AssemblerOptions.pop_back();
3246 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3248 getTargetStreamer().emitDirectiveSetPop();
3252 bool MipsAsmParser::parseSetPushDirective() {
3253 MCAsmParser &Parser = getParser();
3255 if (getLexer().isNot(AsmToken::EndOfStatement))
3256 return reportParseError("unexpected token, expected end of statement");
3258 // Create a copy of the current assembler options environment and push it.
3259 AssemblerOptions.push_back(
3260 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3262 getTargetStreamer().emitDirectiveSetPush();
3266 bool MipsAsmParser::parseSetAssignment() {
3268 const MCExpr *Value;
3269 MCAsmParser &Parser = getParser();
3271 if (Parser.parseIdentifier(Name))
3272 reportParseError("expected identifier after .set");
3274 if (getLexer().isNot(AsmToken::Comma))
3275 return reportParseError("unexpected token, expected comma");
3278 if (Parser.parseExpression(Value))
3279 return reportParseError("expected valid expression after comma");
3281 // Check if the Name already exists as a symbol.
3282 MCSymbol *Sym = getContext().LookupSymbol(Name);
3284 return reportParseError("symbol already defined");
3285 Sym = getContext().GetOrCreateSymbol(Name);
3286 Sym->setVariableValue(Value);
3291 bool MipsAsmParser::parseSetMips0Directive() {
3292 MCAsmParser &Parser = getParser();
3294 if (getLexer().isNot(AsmToken::EndOfStatement))
3295 return reportParseError("unexpected token, expected end of statement");
3297 // Reset assembler options to their initial values.
3298 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3299 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3301 getTargetStreamer().emitDirectiveSetMips0();
3305 bool MipsAsmParser::parseSetArchDirective() {
3306 MCAsmParser &Parser = getParser();
3308 if (getLexer().isNot(AsmToken::Equal))
3309 return reportParseError("unexpected token, expected equals sign");
3313 if (Parser.parseIdentifier(Arch))
3314 return reportParseError("expected arch identifier");
3316 StringRef ArchFeatureName =
3317 StringSwitch<StringRef>(Arch)
3318 .Case("mips1", "mips1")
3319 .Case("mips2", "mips2")
3320 .Case("mips3", "mips3")
3321 .Case("mips4", "mips4")
3322 .Case("mips5", "mips5")
3323 .Case("mips32", "mips32")
3324 .Case("mips32r2", "mips32r2")
3325 .Case("mips32r6", "mips32r6")
3326 .Case("mips64", "mips64")
3327 .Case("mips64r2", "mips64r2")
3328 .Case("mips64r6", "mips64r6")
3329 .Case("cnmips", "cnmips")
3330 .Case("r4000", "mips3") // This is an implementation of Mips3.
3333 if (ArchFeatureName.empty())
3334 return reportParseError("unsupported architecture");
3336 selectArch(ArchFeatureName);
3337 getTargetStreamer().emitDirectiveSetArch(Arch);
3341 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3342 MCAsmParser &Parser = getParser();
3344 if (getLexer().isNot(AsmToken::EndOfStatement))
3345 return reportParseError("unexpected token, expected end of statement");
3349 llvm_unreachable("Unimplemented feature");
3350 case Mips::FeatureDSP:
3351 setFeatureBits(Mips::FeatureDSP, "dsp");
3352 getTargetStreamer().emitDirectiveSetDsp();
3354 case Mips::FeatureMicroMips:
3355 getTargetStreamer().emitDirectiveSetMicroMips();
3357 case Mips::FeatureMips1:
3358 selectArch("mips1");
3359 getTargetStreamer().emitDirectiveSetMips1();
3361 case Mips::FeatureMips2:
3362 selectArch("mips2");
3363 getTargetStreamer().emitDirectiveSetMips2();
3365 case Mips::FeatureMips3:
3366 selectArch("mips3");
3367 getTargetStreamer().emitDirectiveSetMips3();
3369 case Mips::FeatureMips4:
3370 selectArch("mips4");
3371 getTargetStreamer().emitDirectiveSetMips4();
3373 case Mips::FeatureMips5:
3374 selectArch("mips5");
3375 getTargetStreamer().emitDirectiveSetMips5();
3377 case Mips::FeatureMips32:
3378 selectArch("mips32");
3379 getTargetStreamer().emitDirectiveSetMips32();
3381 case Mips::FeatureMips32r2:
3382 selectArch("mips32r2");
3383 getTargetStreamer().emitDirectiveSetMips32R2();
3385 case Mips::FeatureMips32r6:
3386 selectArch("mips32r6");
3387 getTargetStreamer().emitDirectiveSetMips32R6();
3389 case Mips::FeatureMips64:
3390 selectArch("mips64");
3391 getTargetStreamer().emitDirectiveSetMips64();
3393 case Mips::FeatureMips64r2:
3394 selectArch("mips64r2");
3395 getTargetStreamer().emitDirectiveSetMips64R2();
3397 case Mips::FeatureMips64r6:
3398 selectArch("mips64r6");
3399 getTargetStreamer().emitDirectiveSetMips64R6();
3405 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3406 MCAsmParser &Parser = getParser();
3407 if (getLexer().isNot(AsmToken::Comma)) {
3408 SMLoc Loc = getLexer().getLoc();
3409 Parser.eatToEndOfStatement();
3410 return Error(Loc, ErrorStr);
3413 Parser.Lex(); // Eat the comma.
3417 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3418 if (AssemblerOptions.back()->isReorder())
3419 Warning(Loc, ".cpload should be inside a noreorder section");
3421 if (inMips16Mode()) {
3422 reportParseError(".cpload is not supported in Mips16 mode");
3426 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3427 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3428 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3429 reportParseError("expected register containing function address");
3433 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3434 if (!RegOpnd.isGPRAsmReg()) {
3435 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3439 // If this is not the end of the statement, report an error.
3440 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3441 reportParseError("unexpected token, expected end of statement");
3445 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3449 bool MipsAsmParser::parseDirectiveCPSetup() {
3450 MCAsmParser &Parser = getParser();
3453 bool SaveIsReg = true;
3455 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3456 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3457 if (ResTy == MatchOperand_NoMatch) {
3458 reportParseError("expected register containing function address");
3459 Parser.eatToEndOfStatement();
3463 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3464 if (!FuncRegOpnd.isGPRAsmReg()) {
3465 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3466 Parser.eatToEndOfStatement();
3470 FuncReg = FuncRegOpnd.getGPR32Reg();
3473 if (!eatComma("unexpected token, expected comma"))
3476 ResTy = parseAnyRegister(TmpReg);
3477 if (ResTy == MatchOperand_NoMatch) {
3478 const AsmToken &Tok = Parser.getTok();
3479 if (Tok.is(AsmToken::Integer)) {
3480 Save = Tok.getIntVal();
3484 reportParseError("expected save register or stack offset");
3485 Parser.eatToEndOfStatement();
3489 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3490 if (!SaveOpnd.isGPRAsmReg()) {
3491 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3492 Parser.eatToEndOfStatement();
3495 Save = SaveOpnd.getGPR32Reg();
3498 if (!eatComma("unexpected token, expected comma"))
3502 if (Parser.parseIdentifier(Name))
3503 reportParseError("expected identifier");
3504 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3506 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3510 bool MipsAsmParser::parseDirectiveNaN() {
3511 MCAsmParser &Parser = getParser();
3512 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3513 const AsmToken &Tok = Parser.getTok();
3515 if (Tok.getString() == "2008") {
3517 getTargetStreamer().emitDirectiveNaN2008();
3519 } else if (Tok.getString() == "legacy") {
3521 getTargetStreamer().emitDirectiveNaNLegacy();
3525 // If we don't recognize the option passed to the .nan
3526 // directive (e.g. no option or unknown option), emit an error.
3527 reportParseError("invalid option in .nan directive");
3531 bool MipsAsmParser::parseDirectiveSet() {
3532 MCAsmParser &Parser = getParser();
3533 // Get the next token.
3534 const AsmToken &Tok = Parser.getTok();
3536 if (Tok.getString() == "noat") {
3537 return parseSetNoAtDirective();
3538 } else if (Tok.getString() == "at") {
3539 return parseSetAtDirective();
3540 } else if (Tok.getString() == "arch") {
3541 return parseSetArchDirective();
3542 } else if (Tok.getString() == "fp") {
3543 return parseSetFpDirective();
3544 } else if (Tok.getString() == "pop") {
3545 return parseSetPopDirective();
3546 } else if (Tok.getString() == "push") {
3547 return parseSetPushDirective();
3548 } else if (Tok.getString() == "reorder") {
3549 return parseSetReorderDirective();
3550 } else if (Tok.getString() == "noreorder") {
3551 return parseSetNoReorderDirective();
3552 } else if (Tok.getString() == "macro") {
3553 return parseSetMacroDirective();
3554 } else if (Tok.getString() == "nomacro") {
3555 return parseSetNoMacroDirective();
3556 } else if (Tok.getString() == "mips16") {
3557 return parseSetMips16Directive();
3558 } else if (Tok.getString() == "nomips16") {
3559 return parseSetNoMips16Directive();
3560 } else if (Tok.getString() == "nomicromips") {
3561 getTargetStreamer().emitDirectiveSetNoMicroMips();
3562 Parser.eatToEndOfStatement();
3564 } else if (Tok.getString() == "micromips") {
3565 return parseSetFeature(Mips::FeatureMicroMips);
3566 } else if (Tok.getString() == "mips0") {
3567 return parseSetMips0Directive();
3568 } else if (Tok.getString() == "mips1") {
3569 return parseSetFeature(Mips::FeatureMips1);
3570 } else if (Tok.getString() == "mips2") {
3571 return parseSetFeature(Mips::FeatureMips2);
3572 } else if (Tok.getString() == "mips3") {
3573 return parseSetFeature(Mips::FeatureMips3);
3574 } else if (Tok.getString() == "mips4") {
3575 return parseSetFeature(Mips::FeatureMips4);
3576 } else if (Tok.getString() == "mips5") {
3577 return parseSetFeature(Mips::FeatureMips5);
3578 } else if (Tok.getString() == "mips32") {
3579 return parseSetFeature(Mips::FeatureMips32);
3580 } else if (Tok.getString() == "mips32r2") {
3581 return parseSetFeature(Mips::FeatureMips32r2);
3582 } else if (Tok.getString() == "mips32r6") {
3583 return parseSetFeature(Mips::FeatureMips32r6);
3584 } else if (Tok.getString() == "mips64") {
3585 return parseSetFeature(Mips::FeatureMips64);
3586 } else if (Tok.getString() == "mips64r2") {
3587 return parseSetFeature(Mips::FeatureMips64r2);
3588 } else if (Tok.getString() == "mips64r6") {
3589 return parseSetFeature(Mips::FeatureMips64r6);
3590 } else if (Tok.getString() == "dsp") {
3591 return parseSetFeature(Mips::FeatureDSP);
3592 } else if (Tok.getString() == "nodsp") {
3593 return parseSetNoDspDirective();
3594 } else if (Tok.getString() == "msa") {
3595 return parseSetMsaDirective();
3596 } else if (Tok.getString() == "nomsa") {
3597 return parseSetNoMsaDirective();
3599 // It is just an identifier, look for an assignment.
3600 parseSetAssignment();
3607 /// parseDataDirective
3608 /// ::= .word [ expression (, expression)* ]
3609 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3610 MCAsmParser &Parser = getParser();
3611 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3613 const MCExpr *Value;
3614 if (getParser().parseExpression(Value))
3617 getParser().getStreamer().EmitValue(Value, Size);
3619 if (getLexer().is(AsmToken::EndOfStatement))
3622 if (getLexer().isNot(AsmToken::Comma))
3623 return Error(L, "unexpected token, expected comma");
3632 /// parseDirectiveGpWord
3633 /// ::= .gpword local_sym
3634 bool MipsAsmParser::parseDirectiveGpWord() {
3635 MCAsmParser &Parser = getParser();
3636 const MCExpr *Value;
3637 // EmitGPRel32Value requires an expression, so we are using base class
3638 // method to evaluate the expression.
3639 if (getParser().parseExpression(Value))
3641 getParser().getStreamer().EmitGPRel32Value(Value);
3643 if (getLexer().isNot(AsmToken::EndOfStatement))
3644 return Error(getLexer().getLoc(),
3645 "unexpected token, expected end of statement");
3646 Parser.Lex(); // Eat EndOfStatement token.
3650 /// parseDirectiveGpDWord
3651 /// ::= .gpdword local_sym
3652 bool MipsAsmParser::parseDirectiveGpDWord() {
3653 MCAsmParser &Parser = getParser();
3654 const MCExpr *Value;
3655 // EmitGPRel64Value requires an expression, so we are using base class
3656 // method to evaluate the expression.
3657 if (getParser().parseExpression(Value))
3659 getParser().getStreamer().EmitGPRel64Value(Value);
3661 if (getLexer().isNot(AsmToken::EndOfStatement))
3662 return Error(getLexer().getLoc(),
3663 "unexpected token, expected end of statement");
3664 Parser.Lex(); // Eat EndOfStatement token.
3668 bool MipsAsmParser::parseDirectiveOption() {
3669 MCAsmParser &Parser = getParser();
3670 // Get the option token.
3671 AsmToken Tok = Parser.getTok();
3672 // At the moment only identifiers are supported.
3673 if (Tok.isNot(AsmToken::Identifier)) {
3674 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3675 Parser.eatToEndOfStatement();
3679 StringRef Option = Tok.getIdentifier();
3681 if (Option == "pic0") {
3682 getTargetStreamer().emitDirectiveOptionPic0();
3684 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3685 Error(Parser.getTok().getLoc(),
3686 "unexpected token, expected end of statement");
3687 Parser.eatToEndOfStatement();
3692 if (Option == "pic2") {
3693 getTargetStreamer().emitDirectiveOptionPic2();
3695 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3696 Error(Parser.getTok().getLoc(),
3697 "unexpected token, expected end of statement");
3698 Parser.eatToEndOfStatement();
3704 Warning(Parser.getTok().getLoc(),
3705 "unknown option, expected 'pic0' or 'pic2'");
3706 Parser.eatToEndOfStatement();
3710 /// parseDirectiveModule
3711 /// ::= .module oddspreg
3712 /// ::= .module nooddspreg
3713 /// ::= .module fp=value
3714 bool MipsAsmParser::parseDirectiveModule() {
3715 MCAsmParser &Parser = getParser();
3716 MCAsmLexer &Lexer = getLexer();
3717 SMLoc L = Lexer.getLoc();
3719 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3720 // TODO : get a better message.
3721 reportParseError(".module directive must appear before any code");
3726 if (Parser.parseIdentifier(Option)) {
3727 reportParseError("expected .module option identifier");
3731 if (Option == "oddspreg") {
3732 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3733 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3735 // If this is not the end of the statement, report an error.
3736 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3737 reportParseError("unexpected token, expected end of statement");
3741 return false; // parseDirectiveModule has finished successfully.
3742 } else if (Option == "nooddspreg") {
3744 Error(L, "'.module nooddspreg' requires the O32 ABI");
3748 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3749 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3751 // If this is not the end of the statement, report an error.
3752 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3753 reportParseError("unexpected token, expected end of statement");
3757 return false; // parseDirectiveModule has finished successfully.
3758 } else if (Option == "fp") {
3759 return parseDirectiveModuleFP();
3761 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"