1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/TargetRegistry.h"
30 #include "llvm/Support/SourceMgr.h"
35 #define DEBUG_TYPE "mips-asm-parser"
42 class MipsAssemblerOptions {
44 MipsAssemblerOptions(uint64_t Features_) :
45 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
47 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
48 ATReg = Opts->getATRegNum();
49 Reorder = Opts->isReorder();
50 Macro = Opts->isMacro();
51 Features = Opts->getFeatures();
54 unsigned getATRegNum() const { return ATReg; }
55 bool setATReg(unsigned Reg);
57 bool isReorder() const { return Reorder; }
58 void setReorder() { Reorder = true; }
59 void setNoReorder() { Reorder = false; }
61 bool isMacro() const { return Macro; }
62 void setMacro() { Macro = true; }
63 void setNoMacro() { Macro = false; }
65 uint64_t getFeatures() const { return Features; }
66 void setFeatures(uint64_t Features_) { Features = Features_; }
68 // Set of features that are either architecture features or referenced
69 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
70 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
71 // The reason we need this mask is explained in the selectArch function.
72 // FIXME: Ideally we would like TableGen to generate this information.
73 static const uint64_t AllArchRelatedMask =
74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
79 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
80 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
91 class MipsAsmParser : public MCTargetAsmParser {
92 MipsTargetStreamer &getTargetStreamer() {
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
100 // nullptr, which indicates that no function is currently
101 // selected. This usually happens after an '.end func'
104 // Print a warning along with its fix-it message at the given range.
105 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
106 SMRange Range, bool ShowColors = true);
108 #define GET_ASSEMBLER_HEADER
109 #include "MipsGenAsmMatcher.inc"
111 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
113 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
114 OperandVector &Operands, MCStreamer &Out,
116 bool MatchingInlineAsm) override;
118 /// Parse a register as used in CFI directives
119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
121 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
123 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
125 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
126 SMLoc NameLoc, OperandVector &Operands) override;
128 bool ParseDirective(AsmToken DirectiveID) override;
130 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
132 MipsAsmParser::OperandMatchResultTy
133 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
134 StringRef Identifier, SMLoc S);
136 MipsAsmParser::OperandMatchResultTy
137 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
139 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
141 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy
150 parseRegisterList (OperandVector &Operands);
152 bool searchSymbolAlias(OperandVector &Operands);
154 bool parseOperand(OperandVector &, StringRef Mnemonic);
156 bool needsExpansion(MCInst &Inst);
158 // Expands assembly pseudo instructions.
159 // Returns false on success, true otherwise.
160 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
161 SmallVectorImpl<MCInst> &Instructions);
163 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
164 SmallVectorImpl<MCInst> &Instructions);
166 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
169 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
175 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
176 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
178 bool reportParseError(Twine ErrorMsg);
179 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
181 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
182 bool parseRelocOperand(const MCExpr *&Res);
184 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
186 bool isEvaluated(const MCExpr *Expr);
187 bool parseSetMips0Directive();
188 bool parseSetArchDirective();
189 bool parseSetFeature(uint64_t Feature);
190 bool parseDirectiveCpLoad(SMLoc Loc);
191 bool parseDirectiveCPSetup();
192 bool parseDirectiveNaN();
193 bool parseDirectiveSet();
194 bool parseDirectiveOption();
196 bool parseSetAtDirective();
197 bool parseSetNoAtDirective();
198 bool parseSetMacroDirective();
199 bool parseSetNoMacroDirective();
200 bool parseSetMsaDirective();
201 bool parseSetNoMsaDirective();
202 bool parseSetNoDspDirective();
203 bool parseSetReorderDirective();
204 bool parseSetNoReorderDirective();
205 bool parseSetMips16Directive();
206 bool parseSetNoMips16Directive();
207 bool parseSetFpDirective();
208 bool parseSetPopDirective();
209 bool parseSetPushDirective();
211 bool parseSetAssignment();
213 bool parseDataDirective(unsigned Size, SMLoc L);
214 bool parseDirectiveGpWord();
215 bool parseDirectiveGpDWord();
216 bool parseDirectiveModule();
217 bool parseDirectiveModuleFP();
218 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
219 StringRef Directive);
221 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
223 bool eatComma(StringRef ErrorStr);
225 int matchCPURegisterName(StringRef Symbol);
227 int matchHWRegsRegisterName(StringRef Symbol);
229 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
231 int matchFPURegisterName(StringRef Name);
233 int matchFCCRegisterName(StringRef Name);
235 int matchACRegisterName(StringRef Name);
237 int matchMSA128RegisterName(StringRef Name);
239 int matchMSA128CtrlRegisterName(StringRef Name);
241 unsigned getReg(int RC, int RegNo);
243 unsigned getGPR(int RegNo);
245 int getATReg(SMLoc Loc);
247 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
248 SmallVectorImpl<MCInst> &Instructions);
250 // Helper function that checks if the value of a vector index is within the
251 // boundaries of accepted values for each RegisterKind
252 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
253 bool validateMSAIndex(int Val, int RegKind);
255 // Selects a new architecture by updating the FeatureBits with the necessary
256 // info including implied dependencies.
257 // Internally, it clears all the feature bits related to *any* architecture
258 // and selects the new one using the ToggleFeature functionality of the
259 // MCSubtargetInfo object that handles implied dependencies. The reason we
260 // clear all the arch related bits manually is because ToggleFeature only
261 // clears the features that imply the feature being cleared and not the
262 // features implied by the feature being cleared. This is easier to see
264 // --------------------------------------------------
265 // | Feature | Implies |
266 // | -------------------------------------------------|
267 // | FeatureMips1 | None |
268 // | FeatureMips2 | FeatureMips1 |
269 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
270 // | FeatureMips4 | FeatureMips3 |
272 // --------------------------------------------------
274 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
275 // FeatureMipsGP64 | FeatureMips1)
276 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
277 void selectArch(StringRef ArchFeature) {
278 uint64_t FeatureBits = STI.getFeatureBits();
279 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
280 STI.setFeatureBits(FeatureBits);
281 setAvailableFeatures(
282 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
283 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
286 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
287 if (!(STI.getFeatureBits() & Feature)) {
288 setAvailableFeatures(
289 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
291 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
294 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
295 if (STI.getFeatureBits() & Feature) {
296 setAvailableFeatures(
297 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
299 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
303 enum MipsMatchResultTy {
304 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
305 #define GET_OPERAND_DIAGNOSTIC_TYPES
306 #include "MipsGenAsmMatcher.inc"
307 #undef GET_OPERAND_DIAGNOSTIC_TYPES
311 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
312 const MCInstrInfo &MII, const MCTargetOptions &Options)
313 : MCTargetAsmParser(), STI(sti) {
314 MCAsmParserExtension::Initialize(parser);
316 // Initialize the set of available features.
317 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
319 // Remember the initial assembler options. The user can not modify these.
320 AssemblerOptions.push_back(
321 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
323 // Create an assembler options environment for the user to modify.
324 AssemblerOptions.push_back(
325 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
327 getTargetStreamer().updateABIInfo(*this);
329 // Assert exactly one ABI was chosen.
330 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
331 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
332 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
333 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
335 if (!isABI_O32() && !useOddSPReg() != 0)
336 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
341 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
342 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
344 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
345 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
346 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
347 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
348 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
349 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
351 bool useOddSPReg() const {
352 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
355 bool inMicroMipsMode() const {
356 return STI.getFeatureBits() & Mips::FeatureMicroMips;
358 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
359 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
360 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
361 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
362 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
363 bool hasMips32() const {
364 return (STI.getFeatureBits() & Mips::FeatureMips32);
366 bool hasMips64() const {
367 return (STI.getFeatureBits() & Mips::FeatureMips64);
369 bool hasMips32r2() const {
370 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
372 bool hasMips64r2() const {
373 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
375 bool hasMips32r6() const {
376 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
378 bool hasMips64r6() const {
379 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
381 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
382 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
383 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
385 bool inMips16Mode() const {
386 return STI.getFeatureBits() & Mips::FeatureMips16;
388 // TODO: see how can we get this info.
389 bool abiUsesSoftFloat() const { return false; }
391 /// Warn if RegNo is the current assembler temporary.
392 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
398 /// MipsOperand - Instances of this class represent a parsed Mips machine
400 class MipsOperand : public MCParsedAsmOperand {
402 /// Broad categories of register classes
403 /// The exact class is finalized by the render method.
405 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
406 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
408 RegKind_FCC = 4, /// FCC
409 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
410 RegKind_MSACtrl = 16, /// MSA control registers
411 RegKind_COP2 = 32, /// COP2
412 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
414 RegKind_CCR = 128, /// CCR
415 RegKind_HWRegs = 256, /// HWRegs
416 RegKind_COP3 = 512, /// COP3
418 /// Potentially any (e.g. $1)
419 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
420 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
421 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
426 k_Immediate, /// An immediate (possibly involving symbol references)
427 k_Memory, /// Base + Offset Memory Address
428 k_PhysRegister, /// A physical register from the Mips namespace
429 k_RegisterIndex, /// A register index in one or more RegKind.
430 k_Token, /// A simple token
431 k_RegList /// A physical register list
435 MipsOperand(KindTy K, MipsAsmParser &Parser)
436 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
439 /// For diagnostics, and checking the assembler temporary
440 MipsAsmParser &AsmParser;
448 unsigned Num; /// Register Number
452 unsigned Index; /// Index into the register class
453 RegKind Kind; /// Bitfield of the kinds it could possibly be
454 const MCRegisterInfo *RegInfo;
467 SmallVector<unsigned, 10> *List;
472 struct PhysRegOp PhysReg;
473 struct RegIdxOp RegIdx;
476 struct RegListOp RegList;
479 SMLoc StartLoc, EndLoc;
481 /// Internal constructor for register kinds
482 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
483 const MCRegisterInfo *RegInfo,
485 MipsAsmParser &Parser) {
486 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
487 Op->RegIdx.Index = Index;
488 Op->RegIdx.RegInfo = RegInfo;
489 Op->RegIdx.Kind = RegKind;
496 /// Coerce the register to GPR32 and return the real register for the current
498 unsigned getGPR32Reg() const {
499 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
500 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
501 unsigned ClassID = Mips::GPR32RegClassID;
502 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
505 /// Coerce the register to GPR32 and return the real register for the current
507 unsigned getGPRMM16Reg() const {
508 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
509 unsigned ClassID = Mips::GPR32RegClassID;
510 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
513 /// Coerce the register to GPR64 and return the real register for the current
515 unsigned getGPR64Reg() const {
516 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
517 unsigned ClassID = Mips::GPR64RegClassID;
518 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
522 /// Coerce the register to AFGR64 and return the real register for the current
524 unsigned getAFGR64Reg() const {
525 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
526 if (RegIdx.Index % 2 != 0)
527 AsmParser.Warning(StartLoc, "Float register should be even.");
528 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
529 .getRegister(RegIdx.Index / 2);
532 /// Coerce the register to FGR64 and return the real register for the current
534 unsigned getFGR64Reg() const {
535 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
536 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
537 .getRegister(RegIdx.Index);
540 /// Coerce the register to FGR32 and return the real register for the current
542 unsigned getFGR32Reg() const {
543 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
544 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
545 .getRegister(RegIdx.Index);
548 /// Coerce the register to FGRH32 and return the real register for the current
550 unsigned getFGRH32Reg() const {
551 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
552 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
553 .getRegister(RegIdx.Index);
556 /// Coerce the register to FCC and return the real register for the current
558 unsigned getFCCReg() const {
559 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
560 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
561 .getRegister(RegIdx.Index);
564 /// Coerce the register to MSA128 and return the real register for the current
566 unsigned getMSA128Reg() const {
567 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
568 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
570 unsigned ClassID = Mips::MSA128BRegClassID;
571 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
574 /// Coerce the register to MSACtrl and return the real register for the
576 unsigned getMSACtrlReg() const {
577 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
578 unsigned ClassID = Mips::MSACtrlRegClassID;
579 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
582 /// Coerce the register to COP2 and return the real register for the
584 unsigned getCOP2Reg() const {
585 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
586 unsigned ClassID = Mips::COP2RegClassID;
587 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
590 /// Coerce the register to COP3 and return the real register for the
592 unsigned getCOP3Reg() const {
593 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
594 unsigned ClassID = Mips::COP3RegClassID;
595 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
598 /// Coerce the register to ACC64DSP and return the real register for the
600 unsigned getACC64DSPReg() const {
601 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
602 unsigned ClassID = Mips::ACC64DSPRegClassID;
603 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
606 /// Coerce the register to HI32DSP and return the real register for the
608 unsigned getHI32DSPReg() const {
609 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
610 unsigned ClassID = Mips::HI32DSPRegClassID;
611 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
614 /// Coerce the register to LO32DSP and return the real register for the
616 unsigned getLO32DSPReg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
618 unsigned ClassID = Mips::LO32DSPRegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
622 /// Coerce the register to CCR and return the real register for the
624 unsigned getCCRReg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
626 unsigned ClassID = Mips::CCRRegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 /// Coerce the register to HWRegs and return the real register for the
632 unsigned getHWRegsReg() const {
633 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
634 unsigned ClassID = Mips::HWRegsRegClassID;
635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
640 // Add as immediate when possible. Null MCExpr = 0.
642 Inst.addOperand(MCOperand::CreateImm(0));
643 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
644 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
646 Inst.addOperand(MCOperand::CreateExpr(Expr));
649 void addRegOperands(MCInst &Inst, unsigned N) const {
650 llvm_unreachable("Use a custom parser instead");
653 /// Render the operand to an MCInst as a GPR32
654 /// Asserts if the wrong number of operands are requested, or the operand
655 /// is not a k_RegisterIndex compatible with RegKind_GPR
656 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
661 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
662 assert(N == 1 && "Invalid number of operands!");
663 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
666 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
667 assert(N == 1 && "Invalid number of operands!");
668 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
671 /// Render the operand to an MCInst as a GPR64
672 /// Asserts if the wrong number of operands are requested, or the operand
673 /// is not a k_RegisterIndex compatible with RegKind_GPR
674 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
675 assert(N == 1 && "Invalid number of operands!");
676 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
679 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
680 assert(N == 1 && "Invalid number of operands!");
681 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
684 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
685 assert(N == 1 && "Invalid number of operands!");
686 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
689 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
690 assert(N == 1 && "Invalid number of operands!");
691 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
692 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
693 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
694 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
698 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
699 assert(N == 1 && "Invalid number of operands!");
700 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
703 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
704 assert(N == 1 && "Invalid number of operands!");
705 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
708 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
709 assert(N == 1 && "Invalid number of operands!");
710 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
713 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
714 assert(N == 1 && "Invalid number of operands!");
715 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
718 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
719 assert(N == 1 && "Invalid number of operands!");
720 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
723 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
724 assert(N == 1 && "Invalid number of operands!");
725 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
728 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
733 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
738 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
743 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
744 assert(N == 1 && "Invalid number of operands!");
745 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
748 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
749 assert(N == 1 && "Invalid number of operands!");
750 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
753 void addImmOperands(MCInst &Inst, unsigned N) const {
754 assert(N == 1 && "Invalid number of operands!");
755 const MCExpr *Expr = getImm();
759 void addMemOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 2 && "Invalid number of operands!");
762 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
764 const MCExpr *Expr = getMemOff();
768 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
769 assert(N == 2 && "Invalid number of operands!");
771 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
773 const MCExpr *Expr = getMemOff();
777 void addRegListOperands(MCInst &Inst, unsigned N) const {
778 assert(N == 1 && "Invalid number of operands!");
780 for (auto RegNo : getRegList())
781 Inst.addOperand(MCOperand::CreateReg(RegNo));
784 bool isReg() const override {
785 // As a special case until we sort out the definition of div/divu, pretend
786 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
787 if (isGPRAsmReg() && RegIdx.Index == 0)
790 return Kind == k_PhysRegister;
792 bool isRegIdx() const { return Kind == k_RegisterIndex; }
793 bool isImm() const override { return Kind == k_Immediate; }
794 bool isConstantImm() const {
795 return isImm() && dyn_cast<MCConstantExpr>(getImm());
797 bool isToken() const override {
798 // Note: It's not possible to pretend that other operand kinds are tokens.
799 // The matcher emitter checks tokens first.
800 return Kind == k_Token;
802 bool isMem() const override { return Kind == k_Memory; }
803 bool isConstantMemOff() const {
804 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
806 template <unsigned Bits> bool isMemWithSimmOffset() const {
807 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
809 bool isMemWithGRPMM16Base() const {
810 return isMem() && getMemBase()->isMM16AsmReg();
812 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
813 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
814 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
816 bool isRegList16() const {
820 int Size = RegList.List->size();
821 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
822 RegList.List->back() != Mips::RA)
825 int PrevReg = *RegList.List->begin();
826 for (int i = 1; i < Size - 1; i++) {
827 int Reg = (*(RegList.List))[i];
828 if ( Reg != PrevReg + 1)
835 bool isInvNum() const { return Kind == k_Immediate; }
836 bool isLSAImm() const {
837 if (!isConstantImm())
839 int64_t Val = getConstantImm();
840 return 1 <= Val && Val <= 4;
842 bool isRegList() const { return Kind == k_RegList; }
844 StringRef getToken() const {
845 assert(Kind == k_Token && "Invalid access!");
846 return StringRef(Tok.Data, Tok.Length);
849 unsigned getReg() const override {
850 // As a special case until we sort out the definition of div/divu, pretend
851 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
852 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
853 RegIdx.Kind & RegKind_GPR)
854 return getGPR32Reg(); // FIXME: GPR64 too
856 assert(Kind == k_PhysRegister && "Invalid access!");
860 const MCExpr *getImm() const {
861 assert((Kind == k_Immediate) && "Invalid access!");
865 int64_t getConstantImm() const {
866 const MCExpr *Val = getImm();
867 return static_cast<const MCConstantExpr *>(Val)->getValue();
870 MipsOperand *getMemBase() const {
871 assert((Kind == k_Memory) && "Invalid access!");
875 const MCExpr *getMemOff() const {
876 assert((Kind == k_Memory) && "Invalid access!");
880 int64_t getConstantMemOff() const {
881 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
884 const SmallVectorImpl<unsigned> &getRegList() const {
885 assert((Kind == k_RegList) && "Invalid access!");
886 return *(RegList.List);
889 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
890 MipsAsmParser &Parser) {
891 auto Op = make_unique<MipsOperand>(k_Token, Parser);
892 Op->Tok.Data = Str.data();
893 Op->Tok.Length = Str.size();
899 /// Create a numeric register (e.g. $1). The exact register remains
900 /// unresolved until an instruction successfully matches
901 static std::unique_ptr<MipsOperand>
902 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
903 SMLoc E, MipsAsmParser &Parser) {
904 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
905 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
908 /// Create a register that is definitely a GPR.
909 /// This is typically only used for named registers such as $gp.
910 static std::unique_ptr<MipsOperand>
911 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
912 MipsAsmParser &Parser) {
913 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
916 /// Create a register that is definitely a FGR.
917 /// This is typically only used for named registers such as $f0.
918 static std::unique_ptr<MipsOperand>
919 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
920 MipsAsmParser &Parser) {
921 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
924 /// Create a register that is definitely a HWReg.
925 /// This is typically only used for named registers such as $hwr_cpunum.
926 static std::unique_ptr<MipsOperand>
927 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
928 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
929 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
932 /// Create a register that is definitely an FCC.
933 /// This is typically only used for named registers such as $fcc0.
934 static std::unique_ptr<MipsOperand>
935 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
936 MipsAsmParser &Parser) {
937 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
940 /// Create a register that is definitely an ACC.
941 /// This is typically only used for named registers such as $ac0.
942 static std::unique_ptr<MipsOperand>
943 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
944 MipsAsmParser &Parser) {
945 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
948 /// Create a register that is definitely an MSA128.
949 /// This is typically only used for named registers such as $w0.
950 static std::unique_ptr<MipsOperand>
951 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
952 SMLoc E, MipsAsmParser &Parser) {
953 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
956 /// Create a register that is definitely an MSACtrl.
957 /// This is typically only used for named registers such as $msaaccess.
958 static std::unique_ptr<MipsOperand>
959 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
960 SMLoc E, MipsAsmParser &Parser) {
961 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
964 static std::unique_ptr<MipsOperand>
965 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
966 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
973 static std::unique_ptr<MipsOperand>
974 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
975 SMLoc E, MipsAsmParser &Parser) {
976 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
977 Op->Mem.Base = Base.release();
984 static std::unique_ptr<MipsOperand>
985 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
986 MipsAsmParser &Parser) {
987 assert (Regs.size() > 0 && "Empty list not allowed");
989 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
990 Op->RegList.List = new SmallVector<unsigned, 10>();
991 for (auto Reg : Regs)
992 Op->RegList.List->push_back(Reg);
993 Op->StartLoc = StartLoc;
998 bool isGPRAsmReg() const {
999 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1001 bool isMM16AsmReg() const {
1002 if (!(isRegIdx() && RegIdx.Kind))
1004 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1005 || RegIdx.Index == 16 || RegIdx.Index == 17);
1007 bool isMM16AsmRegZero() const {
1008 if (!(isRegIdx() && RegIdx.Kind))
1010 return (RegIdx.Index == 0 ||
1011 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1012 RegIdx.Index == 17);
1014 bool isFGRAsmReg() const {
1015 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1016 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1018 bool isHWRegsAsmReg() const {
1019 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1021 bool isCCRAsmReg() const {
1022 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1024 bool isFCCAsmReg() const {
1025 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1027 if (!AsmParser.hasEightFccRegisters())
1028 return RegIdx.Index == 0;
1029 return RegIdx.Index <= 7;
1031 bool isACCAsmReg() const {
1032 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1034 bool isCOP2AsmReg() const {
1035 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1037 bool isCOP3AsmReg() const {
1038 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1040 bool isMSA128AsmReg() const {
1041 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1043 bool isMSACtrlAsmReg() const {
1044 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1047 /// getStartLoc - Get the location of the first token of this operand.
1048 SMLoc getStartLoc() const override { return StartLoc; }
1049 /// getEndLoc - Get the location of the last token of this operand.
1050 SMLoc getEndLoc() const override { return EndLoc; }
1052 virtual ~MipsOperand() {
1060 delete RegList.List;
1061 case k_PhysRegister:
1062 case k_RegisterIndex:
1068 void print(raw_ostream &OS) const override {
1077 Mem.Base->print(OS);
1082 case k_PhysRegister:
1083 OS << "PhysReg<" << PhysReg.Num << ">";
1085 case k_RegisterIndex:
1086 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1093 for (auto Reg : (*RegList.List))
1099 }; // class MipsOperand
1103 extern const MCInstrDesc MipsInsts[];
1105 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1106 return MipsInsts[Opcode];
1109 static bool hasShortDelaySlot(unsigned Opcode) {
1112 case Mips::JALRS_MM:
1113 case Mips::JALRS16_MM:
1114 case Mips::BGEZALS_MM:
1115 case Mips::BLTZALS_MM:
1122 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1123 SmallVectorImpl<MCInst> &Instructions) {
1124 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1128 if (MCID.isBranch() || MCID.isCall()) {
1129 const unsigned Opcode = Inst.getOpcode();
1139 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1140 Offset = Inst.getOperand(2);
1141 if (!Offset.isImm())
1142 break; // We'll deal with this situation later on when applying fixups.
1143 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1144 return Error(IDLoc, "branch target out of range");
1145 if (OffsetToAlignment(Offset.getImm(),
1146 1LL << (inMicroMipsMode() ? 1 : 2)))
1147 return Error(IDLoc, "branch to misaligned address");
1161 case Mips::BGEZAL_MM:
1162 case Mips::BLTZAL_MM:
1165 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1166 Offset = Inst.getOperand(1);
1167 if (!Offset.isImm())
1168 break; // We'll deal with this situation later on when applying fixups.
1169 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1170 return Error(IDLoc, "branch target out of range");
1171 if (OffsetToAlignment(Offset.getImm(),
1172 1LL << (inMicroMipsMode() ? 1 : 2)))
1173 return Error(IDLoc, "branch to misaligned address");
1178 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1179 // We still accept it but it is a normal nop.
1180 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1181 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1182 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1186 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1187 // If this instruction has a delay slot and .set reorder is active,
1188 // emit a NOP after it.
1189 Instructions.push_back(Inst);
1191 if (hasShortDelaySlot(Inst.getOpcode())) {
1192 NopInst.setOpcode(Mips::MOVE16_MM);
1193 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1194 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1196 NopInst.setOpcode(Mips::SLL);
1197 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1198 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1199 NopInst.addOperand(MCOperand::CreateImm(0));
1201 Instructions.push_back(NopInst);
1205 if (MCID.mayLoad() || MCID.mayStore()) {
1206 // Check the offset of memory operand, if it is a symbol
1207 // reference or immediate we may have to expand instructions.
1208 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1209 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1210 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1211 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1212 MCOperand &Op = Inst.getOperand(i);
1214 int MemOffset = Op.getImm();
1215 if (MemOffset < -32768 || MemOffset > 32767) {
1216 // Offset can't exceed 16bit value.
1217 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1220 } else if (Op.isExpr()) {
1221 const MCExpr *Expr = Op.getExpr();
1222 if (Expr->getKind() == MCExpr::SymbolRef) {
1223 const MCSymbolRefExpr *SR =
1224 static_cast<const MCSymbolRefExpr *>(Expr);
1225 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1227 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1230 } else if (!isEvaluated(Expr)) {
1231 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1239 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1240 if (inMicroMipsMode()) {
1244 switch (Inst.getOpcode()) {
1247 case Mips::ADDIUS5_MM:
1248 Opnd = Inst.getOperand(2);
1250 return Error(IDLoc, "expected immediate operand kind");
1251 Imm = Opnd.getImm();
1252 if (Imm < -8 || Imm > 7)
1253 return Error(IDLoc, "immediate operand value out of range");
1255 case Mips::ADDIUSP_MM:
1256 Opnd = Inst.getOperand(0);
1258 return Error(IDLoc, "expected immediate operand kind");
1259 Imm = Opnd.getImm();
1260 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1262 return Error(IDLoc, "immediate operand value out of range");
1264 case Mips::SLL16_MM:
1265 case Mips::SRL16_MM:
1266 Opnd = Inst.getOperand(2);
1268 return Error(IDLoc, "expected immediate operand kind");
1269 Imm = Opnd.getImm();
1270 if (Imm < 1 || Imm > 8)
1271 return Error(IDLoc, "immediate operand value out of range");
1274 Opnd = Inst.getOperand(1);
1276 return Error(IDLoc, "expected immediate operand kind");
1277 Imm = Opnd.getImm();
1278 if (Imm < -1 || Imm > 126)
1279 return Error(IDLoc, "immediate operand value out of range");
1281 case Mips::ADDIUR2_MM:
1282 Opnd = Inst.getOperand(2);
1284 return Error(IDLoc, "expected immediate operand kind");
1285 Imm = Opnd.getImm();
1286 if (!(Imm == 1 || Imm == -1 ||
1287 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1288 return Error(IDLoc, "immediate operand value out of range");
1290 case Mips::ADDIUR1SP_MM:
1291 Opnd = Inst.getOperand(1);
1293 return Error(IDLoc, "expected immediate operand kind");
1294 Imm = Opnd.getImm();
1295 if (OffsetToAlignment(Imm, 4LL))
1296 return Error(IDLoc, "misaligned immediate operand value");
1297 if (Imm < 0 || Imm > 255)
1298 return Error(IDLoc, "immediate operand value out of range");
1300 case Mips::ANDI16_MM:
1301 Opnd = Inst.getOperand(2);
1303 return Error(IDLoc, "expected immediate operand kind");
1304 Imm = Opnd.getImm();
1305 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1306 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1307 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1308 return Error(IDLoc, "immediate operand value out of range");
1310 case Mips::LBU16_MM:
1311 Opnd = Inst.getOperand(2);
1313 return Error(IDLoc, "expected immediate operand kind");
1314 Imm = Opnd.getImm();
1315 if (Imm < -1 || Imm > 14)
1316 return Error(IDLoc, "immediate operand value out of range");
1319 Opnd = Inst.getOperand(2);
1321 return Error(IDLoc, "expected immediate operand kind");
1322 Imm = Opnd.getImm();
1323 if (Imm < 0 || Imm > 15)
1324 return Error(IDLoc, "immediate operand value out of range");
1326 case Mips::LHU16_MM:
1328 Opnd = Inst.getOperand(2);
1330 return Error(IDLoc, "expected immediate operand kind");
1331 Imm = Opnd.getImm();
1332 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1333 return Error(IDLoc, "immediate operand value out of range");
1337 Opnd = Inst.getOperand(2);
1339 return Error(IDLoc, "expected immediate operand kind");
1340 Imm = Opnd.getImm();
1341 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1342 return Error(IDLoc, "immediate operand value out of range");
1347 if (needsExpansion(Inst))
1348 return expandInstruction(Inst, IDLoc, Instructions);
1350 Instructions.push_back(Inst);
1355 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1357 switch (Inst.getOpcode()) {
1358 case Mips::LoadImm32Reg:
1359 case Mips::LoadAddr32Imm:
1360 case Mips::LoadAddr32Reg:
1361 case Mips::LoadImm64Reg:
1368 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1369 SmallVectorImpl<MCInst> &Instructions) {
1370 switch (Inst.getOpcode()) {
1372 assert(0 && "unimplemented expansion");
1374 case Mips::LoadImm32Reg:
1375 return expandLoadImm(Inst, IDLoc, Instructions);
1376 case Mips::LoadImm64Reg:
1378 Error(IDLoc, "instruction requires a 64-bit architecture");
1381 return expandLoadImm(Inst, IDLoc, Instructions);
1382 case Mips::LoadAddr32Imm:
1383 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1384 case Mips::LoadAddr32Reg:
1385 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1390 template <bool PerformShift>
1391 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1392 SmallVectorImpl<MCInst> &Instructions) {
1395 tmpInst.setOpcode(Mips::DSLL);
1396 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1397 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1398 tmpInst.addOperand(MCOperand::CreateImm(16));
1399 tmpInst.setLoc(IDLoc);
1400 Instructions.push_back(tmpInst);
1403 tmpInst.setOpcode(Mips::ORi);
1404 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1405 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1406 tmpInst.addOperand(Operand);
1407 tmpInst.setLoc(IDLoc);
1408 Instructions.push_back(tmpInst);
1411 template <int Shift, bool PerformShift>
1412 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1413 SmallVectorImpl<MCInst> &Instructions) {
1414 createShiftOr<PerformShift>(
1415 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1416 IDLoc, Instructions);
1420 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1421 SmallVectorImpl<MCInst> &Instructions) {
1423 const MCOperand &ImmOp = Inst.getOperand(1);
1424 assert(ImmOp.isImm() && "expected immediate operand kind");
1425 const MCOperand &RegOp = Inst.getOperand(0);
1426 assert(RegOp.isReg() && "expected register operand kind");
1428 int64_t ImmValue = ImmOp.getImm();
1429 tmpInst.setLoc(IDLoc);
1430 // FIXME: gas has a special case for values that are 000...1111, which
1431 // becomes a li -1 and then a dsrl
1432 if (0 <= ImmValue && ImmValue <= 65535) {
1433 // For 0 <= j <= 65535.
1434 // li d,j => ori d,$zero,j
1435 tmpInst.setOpcode(Mips::ORi);
1436 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1437 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1438 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1439 Instructions.push_back(tmpInst);
1440 } else if (ImmValue < 0 && ImmValue >= -32768) {
1441 // For -32768 <= j < 0.
1442 // li d,j => addiu d,$zero,j
1443 tmpInst.setOpcode(Mips::ADDiu);
1444 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1445 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1446 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1447 Instructions.push_back(tmpInst);
1448 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1449 // For any value of j that is representable as a 32-bit integer, create
1451 // li d,j => lui d,hi16(j)
1453 tmpInst.setOpcode(Mips::LUi);
1454 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1455 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1456 Instructions.push_back(tmpInst);
1457 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1458 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1460 Error(IDLoc, "instruction requires a 64-bit architecture");
1464 // <------- lo32 ------>
1465 // <------- hi32 ------>
1466 // <- hi16 -> <- lo16 ->
1467 // _________________________________
1469 // | 16-bytes | 16-bytes | 16-bytes |
1470 // |__________|__________|__________|
1472 // For any value of j that is representable as a 48-bit integer, create
1474 // li d,j => lui d,hi16(j)
1475 // ori d,d,hi16(lo32(j))
1477 // ori d,d,lo16(lo32(j))
1478 tmpInst.setOpcode(Mips::LUi);
1479 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1481 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1482 Instructions.push_back(tmpInst);
1483 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1484 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1487 Error(IDLoc, "instruction requires a 64-bit architecture");
1491 // <------- hi32 ------> <------- lo32 ------>
1492 // <- hi16 -> <- lo16 ->
1493 // ___________________________________________
1495 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1496 // |__________|__________|__________|__________|
1498 // For any value of j that isn't representable as a 48-bit integer.
1499 // li d,j => lui d,hi16(j)
1500 // ori d,d,lo16(hi32(j))
1502 // ori d,d,hi16(lo32(j))
1504 // ori d,d,lo16(lo32(j))
1505 tmpInst.setOpcode(Mips::LUi);
1506 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1508 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1509 Instructions.push_back(tmpInst);
1510 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1511 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1512 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1518 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1519 SmallVectorImpl<MCInst> &Instructions) {
1521 const MCOperand &ImmOp = Inst.getOperand(2);
1522 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1523 "expected immediate operand kind");
1524 if (!ImmOp.isImm()) {
1525 expandLoadAddressSym(Inst, IDLoc, Instructions);
1528 const MCOperand &SrcRegOp = Inst.getOperand(1);
1529 assert(SrcRegOp.isReg() && "expected register operand kind");
1530 const MCOperand &DstRegOp = Inst.getOperand(0);
1531 assert(DstRegOp.isReg() && "expected register operand kind");
1532 int ImmValue = ImmOp.getImm();
1533 if (-32768 <= ImmValue && ImmValue <= 65535) {
1534 // For -32768 <= j <= 65535.
1535 // la d,j(s) => addiu d,s,j
1536 tmpInst.setOpcode(Mips::ADDiu);
1537 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1538 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1539 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1540 Instructions.push_back(tmpInst);
1542 // For any other value of j that is representable as a 32-bit integer.
1543 // la d,j(s) => lui d,hi16(j)
1546 tmpInst.setOpcode(Mips::LUi);
1547 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1548 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1549 Instructions.push_back(tmpInst);
1551 tmpInst.setOpcode(Mips::ORi);
1552 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1553 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1554 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1555 Instructions.push_back(tmpInst);
1557 tmpInst.setOpcode(Mips::ADDu);
1558 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1559 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1560 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1561 Instructions.push_back(tmpInst);
1567 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1568 SmallVectorImpl<MCInst> &Instructions) {
1570 const MCOperand &ImmOp = Inst.getOperand(1);
1571 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1572 "expected immediate operand kind");
1573 if (!ImmOp.isImm()) {
1574 expandLoadAddressSym(Inst, IDLoc, Instructions);
1577 const MCOperand &RegOp = Inst.getOperand(0);
1578 assert(RegOp.isReg() && "expected register operand kind");
1579 int ImmValue = ImmOp.getImm();
1580 if (-32768 <= ImmValue && ImmValue <= 65535) {
1581 // For -32768 <= j <= 65535.
1582 // la d,j => addiu d,$zero,j
1583 tmpInst.setOpcode(Mips::ADDiu);
1584 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1585 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1586 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1587 Instructions.push_back(tmpInst);
1589 // For any other value of j that is representable as a 32-bit integer.
1590 // la d,j => lui d,hi16(j)
1592 tmpInst.setOpcode(Mips::LUi);
1593 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1594 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1595 Instructions.push_back(tmpInst);
1597 tmpInst.setOpcode(Mips::ORi);
1598 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1599 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1600 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1601 Instructions.push_back(tmpInst);
1607 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1608 SmallVectorImpl<MCInst> &Instructions) {
1609 // FIXME: If we do have a valid at register to use, we should generate a
1610 // slightly shorter sequence here.
1612 int ExprOperandNo = 1;
1613 // Sometimes the assembly parser will get the immediate expression as
1614 // a $zero + an immediate.
1615 if (Inst.getNumOperands() == 3) {
1616 assert(Inst.getOperand(1).getReg() ==
1617 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1620 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1621 assert(SymOp.isExpr() && "expected symbol operand kind");
1622 const MCOperand &RegOp = Inst.getOperand(0);
1623 unsigned RegNo = RegOp.getReg();
1624 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1625 const MCSymbolRefExpr *HiExpr =
1626 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1627 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1628 const MCSymbolRefExpr *LoExpr =
1629 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1630 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1632 // If it's a 64-bit architecture, expand to:
1633 // la d,sym => lui d,highest(sym)
1634 // ori d,d,higher(sym)
1636 // ori d,d,hi16(sym)
1638 // ori d,d,lo16(sym)
1639 const MCSymbolRefExpr *HighestExpr =
1640 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1641 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1642 const MCSymbolRefExpr *HigherExpr =
1643 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1644 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1646 tmpInst.setOpcode(Mips::LUi);
1647 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1648 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1649 Instructions.push_back(tmpInst);
1651 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1653 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1655 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1658 // Otherwise, expand to:
1659 // la d,sym => lui d,hi16(sym)
1660 // ori d,d,lo16(sym)
1661 tmpInst.setOpcode(Mips::LUi);
1662 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1663 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1664 Instructions.push_back(tmpInst);
1666 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1671 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1672 SmallVectorImpl<MCInst> &Instructions,
1673 bool isLoad, bool isImmOpnd) {
1674 const MCSymbolRefExpr *SR;
1676 unsigned ImmOffset, HiOffset, LoOffset;
1677 const MCExpr *ExprOffset;
1679 // 1st operand is either the source or destination register.
1680 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1681 unsigned RegOpNum = Inst.getOperand(0).getReg();
1682 // 2nd operand is the base register.
1683 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1684 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1685 // 3rd operand is either an immediate or expression.
1687 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1688 ImmOffset = Inst.getOperand(2).getImm();
1689 LoOffset = ImmOffset & 0x0000ffff;
1690 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1691 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1692 if (LoOffset & 0x8000)
1695 ExprOffset = Inst.getOperand(2).getExpr();
1696 // All instructions will have the same location.
1697 TempInst.setLoc(IDLoc);
1698 // These are some of the types of expansions we perform here:
1699 // 1) lw $8, sym => lui $8, %hi(sym)
1700 // lw $8, %lo(sym)($8)
1701 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1703 // lw $8, %lo(offset)($9)
1704 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1706 // lw $8, %lo(offset)($at)
1707 // 4) sw $8, sym => lui $at, %hi(sym)
1708 // sw $8, %lo(sym)($at)
1709 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1711 // sw $8, %lo(offset)($at)
1712 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1713 // ldc1 $f0, %lo(sym)($at)
1715 // For load instructions we can use the destination register as a temporary
1716 // if base and dst are different (examples 1 and 2) and if the base register
1717 // is general purpose otherwise we must use $at (example 6) and error if it's
1718 // not available. For stores we must use $at (examples 4 and 5) because we
1719 // must not clobber the source register setting up the offset.
1720 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1721 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1722 unsigned RegClassIDOp0 =
1723 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1724 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1725 (RegClassIDOp0 == Mips::GPR64RegClassID);
1726 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1727 TmpRegNum = RegOpNum;
1729 int AT = getATReg(IDLoc);
1730 // At this point we need AT to perform the expansions and we exit if it is
1735 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1738 TempInst.setOpcode(Mips::LUi);
1739 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1741 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1743 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1744 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1745 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1746 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1748 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1750 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1751 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1754 // Add the instruction to the list.
1755 Instructions.push_back(TempInst);
1756 // Prepare TempInst for next instruction.
1758 // Add temp register to base.
1759 TempInst.setOpcode(Mips::ADDu);
1760 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1761 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1762 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1763 Instructions.push_back(TempInst);
1765 // And finally, create original instruction with low part
1766 // of offset and new base.
1767 TempInst.setOpcode(Inst.getOpcode());
1768 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1769 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1771 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1773 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1774 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1775 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1777 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1779 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1780 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1783 Instructions.push_back(TempInst);
1787 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1788 // As described by the Mips32r2 spec, the registers Rd and Rs for
1789 // jalr.hb must be different.
1790 unsigned Opcode = Inst.getOpcode();
1792 if (Opcode == Mips::JALR_HB &&
1793 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1794 return Match_RequiresDifferentSrcAndDst;
1796 return Match_Success;
1799 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1800 OperandVector &Operands,
1802 uint64_t &ErrorInfo,
1803 bool MatchingInlineAsm) {
1806 SmallVector<MCInst, 8> Instructions;
1807 unsigned MatchResult =
1808 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1810 switch (MatchResult) {
1813 case Match_Success: {
1814 if (processInstruction(Inst, IDLoc, Instructions))
1816 for (unsigned i = 0; i < Instructions.size(); i++)
1817 Out.EmitInstruction(Instructions[i], STI);
1820 case Match_MissingFeature:
1821 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1823 case Match_InvalidOperand: {
1824 SMLoc ErrorLoc = IDLoc;
1825 if (ErrorInfo != ~0ULL) {
1826 if (ErrorInfo >= Operands.size())
1827 return Error(IDLoc, "too few operands for instruction");
1829 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1830 if (ErrorLoc == SMLoc())
1834 return Error(ErrorLoc, "invalid operand for instruction");
1836 case Match_MnemonicFail:
1837 return Error(IDLoc, "invalid instruction");
1838 case Match_RequiresDifferentSrcAndDst:
1839 return Error(IDLoc, "source and destination must be different");
1844 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1845 if ((RegIndex != 0) &&
1846 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1848 Warning(Loc, "used $at without \".set noat\"");
1850 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1851 Twine(RegIndex) + "\"");
1856 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1857 SMRange Range, bool ShowColors) {
1858 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1859 Range, SMFixIt(Range, FixMsg),
1863 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1866 CC = StringSwitch<unsigned>(Name)
1902 if (!(isABI_N32() || isABI_N64()))
1905 if (12 <= CC && CC <= 15) {
1906 // Name is one of t4-t7
1907 AsmToken RegTok = getLexer().peekTok();
1908 SMRange RegRange = RegTok.getLocRange();
1910 StringRef FixedName = StringSwitch<StringRef>(Name)
1916 assert(FixedName != "" && "Register name is not one of t4-t7.");
1918 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1919 "Did you mean $" + FixedName + "?", RegRange);
1922 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1923 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1924 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1925 if (8 <= CC && CC <= 11)
1929 CC = StringSwitch<unsigned>(Name)
1941 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
1944 CC = StringSwitch<unsigned>(Name)
1945 .Case("hwr_cpunum", 0)
1946 .Case("hwr_synci_step", 1)
1948 .Case("hwr_ccres", 3)
1949 .Case("hwr_ulr", 29)
1955 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1957 if (Name[0] == 'f') {
1958 StringRef NumString = Name.substr(1);
1960 if (NumString.getAsInteger(10, IntVal))
1961 return -1; // This is not an integer.
1962 if (IntVal > 31) // Maximum index for fpu register.
1969 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1971 if (Name.startswith("fcc")) {
1972 StringRef NumString = Name.substr(3);
1974 if (NumString.getAsInteger(10, IntVal))
1975 return -1; // This is not an integer.
1976 if (IntVal > 7) // There are only 8 fcc registers.
1983 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1985 if (Name.startswith("ac")) {
1986 StringRef NumString = Name.substr(2);
1988 if (NumString.getAsInteger(10, IntVal))
1989 return -1; // This is not an integer.
1990 if (IntVal > 3) // There are only 3 acc registers.
1997 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2000 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2009 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2012 CC = StringSwitch<unsigned>(Name)
2015 .Case("msaaccess", 2)
2017 .Case("msamodify", 4)
2018 .Case("msarequest", 5)
2020 .Case("msaunmap", 7)
2026 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2034 int MipsAsmParser::getATReg(SMLoc Loc) {
2035 int AT = AssemblerOptions.back()->getATRegNum();
2037 reportParseError(Loc,
2038 "pseudo-instruction requires $at, which is not available");
2042 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2043 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2046 unsigned MipsAsmParser::getGPR(int RegNo) {
2047 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2051 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2053 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2056 return getReg(RegClass, RegNum);
2059 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2060 MCAsmParser &Parser = getParser();
2061 DEBUG(dbgs() << "parseOperand\n");
2063 // Check if the current operand has a custom associated parser, if so, try to
2064 // custom parse the operand, or fallback to the general approach.
2065 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2066 if (ResTy == MatchOperand_Success)
2068 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2069 // there was a match, but an error occurred, in which case, just return that
2070 // the operand parsing failed.
2071 if (ResTy == MatchOperand_ParseFail)
2074 DEBUG(dbgs() << ".. Generic Parser\n");
2076 switch (getLexer().getKind()) {
2078 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2080 case AsmToken::Dollar: {
2081 // Parse the register.
2082 SMLoc S = Parser.getTok().getLoc();
2084 // Almost all registers have been parsed by custom parsers. There is only
2085 // one exception to this. $zero (and it's alias $0) will reach this point
2086 // for div, divu, and similar instructions because it is not an operand
2087 // to the instruction definition but an explicit register. Special case
2088 // this situation for now.
2089 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2092 // Maybe it is a symbol reference.
2093 StringRef Identifier;
2094 if (Parser.parseIdentifier(Identifier))
2097 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2098 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2099 // Otherwise create a symbol reference.
2101 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2103 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2106 // Else drop to expression parsing.
2107 case AsmToken::LParen:
2108 case AsmToken::Minus:
2109 case AsmToken::Plus:
2110 case AsmToken::Integer:
2111 case AsmToken::Tilde:
2112 case AsmToken::String: {
2113 DEBUG(dbgs() << ".. generic integer\n");
2114 OperandMatchResultTy ResTy = parseImm(Operands);
2115 return ResTy != MatchOperand_Success;
2117 case AsmToken::Percent: {
2118 // It is a symbol reference or constant expression.
2119 const MCExpr *IdVal;
2120 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2121 if (parseRelocOperand(IdVal))
2124 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2126 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2128 } // case AsmToken::Percent
2129 } // switch(getLexer().getKind())
2133 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2134 StringRef RelocStr) {
2136 // Check the type of the expression.
2137 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2138 // It's a constant, evaluate reloc value.
2140 switch (getVariantKind(RelocStr)) {
2141 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2142 // Get the 1st 16-bits.
2143 Val = MCE->getValue() & 0xffff;
2145 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2146 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2147 // 16 bits being negative.
2148 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2150 case MCSymbolRefExpr::VK_Mips_HIGHER:
2151 // Get the 3rd 16-bits.
2152 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2154 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2155 // Get the 4th 16-bits.
2156 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2159 report_fatal_error("unsupported reloc value");
2161 return MCConstantExpr::Create(Val, getContext());
2164 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2165 // It's a symbol, create a symbolic expression from the symbol.
2166 StringRef Symbol = MSRE->getSymbol().getName();
2167 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2168 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2172 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2173 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2175 // Try to create target expression.
2176 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2177 return MipsMCExpr::Create(VK, Expr, getContext());
2179 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2180 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2181 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2185 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2186 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2187 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2190 // Just return the original expression.
2194 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2196 switch (Expr->getKind()) {
2197 case MCExpr::Constant:
2199 case MCExpr::SymbolRef:
2200 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2201 case MCExpr::Binary:
2202 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2203 if (!isEvaluated(BE->getLHS()))
2205 return isEvaluated(BE->getRHS());
2208 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2209 case MCExpr::Target:
2215 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2216 MCAsmParser &Parser = getParser();
2217 Parser.Lex(); // Eat the % token.
2218 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2219 if (Tok.isNot(AsmToken::Identifier))
2222 std::string Str = Tok.getIdentifier().str();
2224 Parser.Lex(); // Eat the identifier.
2225 // Now make an expression from the rest of the operand.
2226 const MCExpr *IdVal;
2229 if (getLexer().getKind() == AsmToken::LParen) {
2231 Parser.Lex(); // Eat the '(' token.
2232 if (getLexer().getKind() == AsmToken::Percent) {
2233 Parser.Lex(); // Eat the % token.
2234 const AsmToken &nextTok = Parser.getTok();
2235 if (nextTok.isNot(AsmToken::Identifier))
2238 Str += nextTok.getIdentifier();
2239 Parser.Lex(); // Eat the identifier.
2240 if (getLexer().getKind() != AsmToken::LParen)
2245 if (getParser().parseParenExpression(IdVal, EndLoc))
2248 while (getLexer().getKind() == AsmToken::RParen)
2249 Parser.Lex(); // Eat the ')' token.
2252 return true; // Parenthesis must follow the relocation operand.
2254 Res = evaluateRelocExpr(IdVal, Str);
2258 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2260 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2261 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2262 if (ResTy == MatchOperand_Success) {
2263 assert(Operands.size() == 1);
2264 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2265 StartLoc = Operand.getStartLoc();
2266 EndLoc = Operand.getEndLoc();
2268 // AFAIK, we only support numeric registers and named GPR's in CFI
2270 // Don't worry about eating tokens before failing. Using an unrecognised
2271 // register is a parse error.
2272 if (Operand.isGPRAsmReg()) {
2273 // Resolve to GPR32 or GPR64 appropriately.
2274 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2277 return (RegNo == (unsigned)-1);
2280 assert(Operands.size() == 0);
2281 return (RegNo == (unsigned)-1);
2284 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2285 MCAsmParser &Parser = getParser();
2289 while (getLexer().getKind() == AsmToken::LParen)
2292 switch (getLexer().getKind()) {
2295 case AsmToken::Identifier:
2296 case AsmToken::LParen:
2297 case AsmToken::Integer:
2298 case AsmToken::Minus:
2299 case AsmToken::Plus:
2301 Result = getParser().parseParenExpression(Res, S);
2303 Result = (getParser().parseExpression(Res));
2304 while (getLexer().getKind() == AsmToken::RParen)
2307 case AsmToken::Percent:
2308 Result = parseRelocOperand(Res);
2313 MipsAsmParser::OperandMatchResultTy
2314 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2315 MCAsmParser &Parser = getParser();
2316 DEBUG(dbgs() << "parseMemOperand\n");
2317 const MCExpr *IdVal = nullptr;
2319 bool isParenExpr = false;
2320 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2321 // First operand is the offset.
2322 S = Parser.getTok().getLoc();
2324 if (getLexer().getKind() == AsmToken::LParen) {
2329 if (getLexer().getKind() != AsmToken::Dollar) {
2330 if (parseMemOffset(IdVal, isParenExpr))
2331 return MatchOperand_ParseFail;
2333 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2334 if (Tok.isNot(AsmToken::LParen)) {
2335 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2336 if (Mnemonic.getToken() == "la") {
2338 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2339 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2340 return MatchOperand_Success;
2342 if (Tok.is(AsmToken::EndOfStatement)) {
2344 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2346 // Zero register assumed, add a memory operand with ZERO as its base.
2347 // "Base" will be managed by k_Memory.
2348 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2351 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2352 return MatchOperand_Success;
2354 Error(Parser.getTok().getLoc(), "'(' expected");
2355 return MatchOperand_ParseFail;
2358 Parser.Lex(); // Eat the '(' token.
2361 Res = parseAnyRegister(Operands);
2362 if (Res != MatchOperand_Success)
2365 if (Parser.getTok().isNot(AsmToken::RParen)) {
2366 Error(Parser.getTok().getLoc(), "')' expected");
2367 return MatchOperand_ParseFail;
2370 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2372 Parser.Lex(); // Eat the ')' token.
2375 IdVal = MCConstantExpr::Create(0, getContext());
2377 // Replace the register operand with the memory operand.
2378 std::unique_ptr<MipsOperand> op(
2379 static_cast<MipsOperand *>(Operands.back().release()));
2380 // Remove the register from the operands.
2381 // "op" will be managed by k_Memory.
2382 Operands.pop_back();
2383 // Add the memory operand.
2384 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2386 if (IdVal->EvaluateAsAbsolute(Imm))
2387 IdVal = MCConstantExpr::Create(Imm, getContext());
2388 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2389 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2393 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2394 return MatchOperand_Success;
2397 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2398 MCAsmParser &Parser = getParser();
2399 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2401 SMLoc S = Parser.getTok().getLoc();
2403 if (Sym->isVariable())
2404 Expr = Sym->getVariableValue();
2407 if (Expr->getKind() == MCExpr::SymbolRef) {
2408 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2409 StringRef DefSymbol = Ref->getSymbol().getName();
2410 if (DefSymbol.startswith("$")) {
2411 OperandMatchResultTy ResTy =
2412 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2413 if (ResTy == MatchOperand_Success) {
2416 } else if (ResTy == MatchOperand_ParseFail)
2417 llvm_unreachable("Should never ParseFail");
2420 } else if (Expr->getKind() == MCExpr::Constant) {
2422 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2424 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2431 MipsAsmParser::OperandMatchResultTy
2432 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2433 StringRef Identifier,
2435 int Index = matchCPURegisterName(Identifier);
2437 Operands.push_back(MipsOperand::createGPRReg(
2438 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2439 return MatchOperand_Success;
2442 Index = matchHWRegsRegisterName(Identifier);
2444 Operands.push_back(MipsOperand::createHWRegsReg(
2445 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2446 return MatchOperand_Success;
2449 Index = matchFPURegisterName(Identifier);
2451 Operands.push_back(MipsOperand::createFGRReg(
2452 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2453 return MatchOperand_Success;
2456 Index = matchFCCRegisterName(Identifier);
2458 Operands.push_back(MipsOperand::createFCCReg(
2459 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2460 return MatchOperand_Success;
2463 Index = matchACRegisterName(Identifier);
2465 Operands.push_back(MipsOperand::createACCReg(
2466 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2467 return MatchOperand_Success;
2470 Index = matchMSA128RegisterName(Identifier);
2472 Operands.push_back(MipsOperand::createMSA128Reg(
2473 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2474 return MatchOperand_Success;
2477 Index = matchMSA128CtrlRegisterName(Identifier);
2479 Operands.push_back(MipsOperand::createMSACtrlReg(
2480 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2481 return MatchOperand_Success;
2484 return MatchOperand_NoMatch;
2487 MipsAsmParser::OperandMatchResultTy
2488 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2489 MCAsmParser &Parser = getParser();
2490 auto Token = Parser.getLexer().peekTok(false);
2492 if (Token.is(AsmToken::Identifier)) {
2493 DEBUG(dbgs() << ".. identifier\n");
2494 StringRef Identifier = Token.getIdentifier();
2495 OperandMatchResultTy ResTy =
2496 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2498 } else if (Token.is(AsmToken::Integer)) {
2499 DEBUG(dbgs() << ".. integer\n");
2500 Operands.push_back(MipsOperand::createNumericReg(
2501 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2503 return MatchOperand_Success;
2506 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2508 return MatchOperand_NoMatch;
2511 MipsAsmParser::OperandMatchResultTy
2512 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2513 MCAsmParser &Parser = getParser();
2514 DEBUG(dbgs() << "parseAnyRegister\n");
2516 auto Token = Parser.getTok();
2518 SMLoc S = Token.getLoc();
2520 if (Token.isNot(AsmToken::Dollar)) {
2521 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2522 if (Token.is(AsmToken::Identifier)) {
2523 if (searchSymbolAlias(Operands))
2524 return MatchOperand_Success;
2526 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2527 return MatchOperand_NoMatch;
2529 DEBUG(dbgs() << ".. $\n");
2531 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2532 if (ResTy == MatchOperand_Success) {
2534 Parser.Lex(); // identifier
2539 MipsAsmParser::OperandMatchResultTy
2540 MipsAsmParser::parseImm(OperandVector &Operands) {
2541 MCAsmParser &Parser = getParser();
2542 switch (getLexer().getKind()) {
2544 return MatchOperand_NoMatch;
2545 case AsmToken::LParen:
2546 case AsmToken::Minus:
2547 case AsmToken::Plus:
2548 case AsmToken::Integer:
2549 case AsmToken::Tilde:
2550 case AsmToken::String:
2554 const MCExpr *IdVal;
2555 SMLoc S = Parser.getTok().getLoc();
2556 if (getParser().parseExpression(IdVal))
2557 return MatchOperand_ParseFail;
2559 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2560 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2561 return MatchOperand_Success;
2564 MipsAsmParser::OperandMatchResultTy
2565 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2566 MCAsmParser &Parser = getParser();
2567 DEBUG(dbgs() << "parseJumpTarget\n");
2569 SMLoc S = getLexer().getLoc();
2571 // Integers and expressions are acceptable
2572 OperandMatchResultTy ResTy = parseImm(Operands);
2573 if (ResTy != MatchOperand_NoMatch)
2576 // Registers are a valid target and have priority over symbols.
2577 ResTy = parseAnyRegister(Operands);
2578 if (ResTy != MatchOperand_NoMatch)
2581 const MCExpr *Expr = nullptr;
2582 if (Parser.parseExpression(Expr)) {
2583 // We have no way of knowing if a symbol was consumed so we must ParseFail
2584 return MatchOperand_ParseFail;
2587 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2588 return MatchOperand_Success;
2591 MipsAsmParser::OperandMatchResultTy
2592 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2593 MCAsmParser &Parser = getParser();
2594 const MCExpr *IdVal;
2595 // If the first token is '$' we may have register operand.
2596 if (Parser.getTok().is(AsmToken::Dollar))
2597 return MatchOperand_NoMatch;
2598 SMLoc S = Parser.getTok().getLoc();
2599 if (getParser().parseExpression(IdVal))
2600 return MatchOperand_ParseFail;
2601 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2602 assert(MCE && "Unexpected MCExpr type.");
2603 int64_t Val = MCE->getValue();
2604 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2605 Operands.push_back(MipsOperand::CreateImm(
2606 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2607 return MatchOperand_Success;
2610 MipsAsmParser::OperandMatchResultTy
2611 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2612 MCAsmParser &Parser = getParser();
2613 switch (getLexer().getKind()) {
2615 return MatchOperand_NoMatch;
2616 case AsmToken::LParen:
2617 case AsmToken::Plus:
2618 case AsmToken::Minus:
2619 case AsmToken::Integer:
2624 SMLoc S = Parser.getTok().getLoc();
2626 if (getParser().parseExpression(Expr))
2627 return MatchOperand_ParseFail;
2630 if (!Expr->EvaluateAsAbsolute(Val)) {
2631 Error(S, "expected immediate value");
2632 return MatchOperand_ParseFail;
2635 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2636 // and because the CPU always adds one to the immediate field, the allowed
2637 // range becomes 1..4. We'll only check the range here and will deal
2638 // with the addition/subtraction when actually decoding/encoding
2640 if (Val < 1 || Val > 4) {
2641 Error(S, "immediate not in range (1..4)");
2642 return MatchOperand_ParseFail;
2646 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2647 return MatchOperand_Success;
2650 MipsAsmParser::OperandMatchResultTy
2651 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2652 MCAsmParser &Parser = getParser();
2653 SmallVector<unsigned, 10> Regs;
2655 unsigned PrevReg = Mips::NoRegister;
2656 bool RegRange = false;
2657 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2659 if (Parser.getTok().isNot(AsmToken::Dollar))
2660 return MatchOperand_ParseFail;
2662 SMLoc S = Parser.getTok().getLoc();
2663 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2664 SMLoc E = getLexer().getLoc();
2665 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2666 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2668 // Remove last register operand because registers from register range
2669 // should be inserted first.
2670 if (RegNo == Mips::RA) {
2671 Regs.push_back(RegNo);
2673 unsigned TmpReg = PrevReg + 1;
2674 while (TmpReg <= RegNo) {
2675 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2676 Error(E, "invalid register operand");
2677 return MatchOperand_ParseFail;
2681 Regs.push_back(TmpReg++);
2687 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2688 (RegNo != Mips::RA)) {
2689 Error(E, "$16 or $31 expected");
2690 return MatchOperand_ParseFail;
2691 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2692 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2693 Error(E, "invalid register operand");
2694 return MatchOperand_ParseFail;
2695 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2696 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2697 Error(E, "consecutive register numbers expected");
2698 return MatchOperand_ParseFail;
2701 Regs.push_back(RegNo);
2704 if (Parser.getTok().is(AsmToken::Minus))
2707 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2708 !Parser.getTok().isNot(AsmToken::Comma)) {
2709 Error(E, "',' or '-' expected");
2710 return MatchOperand_ParseFail;
2713 Lex(); // Consume comma or minus
2714 if (Parser.getTok().isNot(AsmToken::Dollar))
2720 SMLoc E = Parser.getTok().getLoc();
2721 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2722 parseMemOperand(Operands);
2723 return MatchOperand_Success;
2726 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2728 MCSymbolRefExpr::VariantKind VK =
2729 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2730 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2731 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2732 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2733 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2734 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2735 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2736 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2737 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2738 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2739 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2740 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2741 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2742 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2743 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2744 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2745 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2746 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2747 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2748 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2749 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2750 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2751 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2752 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2753 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2754 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2755 .Default(MCSymbolRefExpr::VK_None);
2757 assert(VK != MCSymbolRefExpr::VK_None);
2762 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2764 /// ::= '(', register, ')'
2765 /// handle it before we iterate so we don't get tripped up by the lack of
2767 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2768 MCAsmParser &Parser = getParser();
2769 if (getLexer().is(AsmToken::LParen)) {
2771 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2773 if (parseOperand(Operands, Name)) {
2774 SMLoc Loc = getLexer().getLoc();
2775 Parser.eatToEndOfStatement();
2776 return Error(Loc, "unexpected token in argument list");
2778 if (Parser.getTok().isNot(AsmToken::RParen)) {
2779 SMLoc Loc = getLexer().getLoc();
2780 Parser.eatToEndOfStatement();
2781 return Error(Loc, "unexpected token, expected ')'");
2784 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2790 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2791 /// either one of these.
2792 /// ::= '[', register, ']'
2793 /// ::= '[', integer, ']'
2794 /// handle it before we iterate so we don't get tripped up by the lack of
2796 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2797 OperandVector &Operands) {
2798 MCAsmParser &Parser = getParser();
2799 if (getLexer().is(AsmToken::LBrac)) {
2801 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2803 if (parseOperand(Operands, Name)) {
2804 SMLoc Loc = getLexer().getLoc();
2805 Parser.eatToEndOfStatement();
2806 return Error(Loc, "unexpected token in argument list");
2808 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2809 SMLoc Loc = getLexer().getLoc();
2810 Parser.eatToEndOfStatement();
2811 return Error(Loc, "unexpected token, expected ']'");
2814 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2820 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2821 SMLoc NameLoc, OperandVector &Operands) {
2822 MCAsmParser &Parser = getParser();
2823 DEBUG(dbgs() << "ParseInstruction\n");
2825 // We have reached first instruction, module directive are now forbidden.
2826 getTargetStreamer().forbidModuleDirective();
2828 // Check if we have valid mnemonic
2829 if (!mnemonicIsValid(Name, 0)) {
2830 Parser.eatToEndOfStatement();
2831 return Error(NameLoc, "unknown instruction");
2833 // First operand in MCInst is instruction mnemonic.
2834 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2836 // Read the remaining operands.
2837 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2838 // Read the first operand.
2839 if (parseOperand(Operands, Name)) {
2840 SMLoc Loc = getLexer().getLoc();
2841 Parser.eatToEndOfStatement();
2842 return Error(Loc, "unexpected token in argument list");
2844 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2846 // AFAIK, parenthesis suffixes are never on the first operand
2848 while (getLexer().is(AsmToken::Comma)) {
2849 Parser.Lex(); // Eat the comma.
2850 // Parse and remember the operand.
2851 if (parseOperand(Operands, Name)) {
2852 SMLoc Loc = getLexer().getLoc();
2853 Parser.eatToEndOfStatement();
2854 return Error(Loc, "unexpected token in argument list");
2856 // Parse bracket and parenthesis suffixes before we iterate
2857 if (getLexer().is(AsmToken::LBrac)) {
2858 if (parseBracketSuffix(Name, Operands))
2860 } else if (getLexer().is(AsmToken::LParen) &&
2861 parseParenSuffix(Name, Operands))
2865 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2866 SMLoc Loc = getLexer().getLoc();
2867 Parser.eatToEndOfStatement();
2868 return Error(Loc, "unexpected token in argument list");
2870 Parser.Lex(); // Consume the EndOfStatement.
2874 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2875 MCAsmParser &Parser = getParser();
2876 SMLoc Loc = getLexer().getLoc();
2877 Parser.eatToEndOfStatement();
2878 return Error(Loc, ErrorMsg);
2881 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2882 return Error(Loc, ErrorMsg);
2885 bool MipsAsmParser::parseSetNoAtDirective() {
2886 MCAsmParser &Parser = getParser();
2887 // Line should look like: ".set noat".
2889 AssemblerOptions.back()->setATReg(0);
2892 // If this is not the end of the statement, report an error.
2893 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2894 reportParseError("unexpected token, expected end of statement");
2897 Parser.Lex(); // Consume the EndOfStatement.
2901 bool MipsAsmParser::parseSetAtDirective() {
2902 MCAsmParser &Parser = getParser();
2903 // Line can be .set at - defaults to $1
2907 if (getLexer().is(AsmToken::EndOfStatement)) {
2908 AssemblerOptions.back()->setATReg(1);
2909 Parser.Lex(); // Consume the EndOfStatement.
2911 } else if (getLexer().is(AsmToken::Equal)) {
2912 getParser().Lex(); // Eat the '='.
2913 if (getLexer().isNot(AsmToken::Dollar)) {
2914 reportParseError("unexpected token, expected dollar sign '$'");
2917 Parser.Lex(); // Eat the '$'.
2918 const AsmToken &Reg = Parser.getTok();
2919 if (Reg.is(AsmToken::Identifier)) {
2920 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2921 } else if (Reg.is(AsmToken::Integer)) {
2922 AtRegNo = Reg.getIntVal();
2924 reportParseError("unexpected token, expected identifier or integer");
2928 if (AtRegNo < 0 || AtRegNo > 31) {
2929 reportParseError("unexpected token in statement");
2933 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2934 reportParseError("invalid register");
2937 getParser().Lex(); // Eat the register.
2939 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2940 reportParseError("unexpected token, expected end of statement");
2943 Parser.Lex(); // Consume the EndOfStatement.
2946 reportParseError("unexpected token in statement");
2951 bool MipsAsmParser::parseSetReorderDirective() {
2952 MCAsmParser &Parser = getParser();
2954 // If this is not the end of the statement, report an error.
2955 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2956 reportParseError("unexpected token, expected end of statement");
2959 AssemblerOptions.back()->setReorder();
2960 getTargetStreamer().emitDirectiveSetReorder();
2961 Parser.Lex(); // Consume the EndOfStatement.
2965 bool MipsAsmParser::parseSetNoReorderDirective() {
2966 MCAsmParser &Parser = getParser();
2968 // If this is not the end of the statement, report an error.
2969 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2970 reportParseError("unexpected token, expected end of statement");
2973 AssemblerOptions.back()->setNoReorder();
2974 getTargetStreamer().emitDirectiveSetNoReorder();
2975 Parser.Lex(); // Consume the EndOfStatement.
2979 bool MipsAsmParser::parseSetMacroDirective() {
2980 MCAsmParser &Parser = getParser();
2982 // If this is not the end of the statement, report an error.
2983 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2984 reportParseError("unexpected token, expected end of statement");
2987 AssemblerOptions.back()->setMacro();
2988 Parser.Lex(); // Consume the EndOfStatement.
2992 bool MipsAsmParser::parseSetNoMacroDirective() {
2993 MCAsmParser &Parser = getParser();
2995 // If this is not the end of the statement, report an error.
2996 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2997 reportParseError("unexpected token, expected end of statement");
3000 if (AssemblerOptions.back()->isReorder()) {
3001 reportParseError("`noreorder' must be set before `nomacro'");
3004 AssemblerOptions.back()->setNoMacro();
3005 Parser.Lex(); // Consume the EndOfStatement.
3009 bool MipsAsmParser::parseSetMsaDirective() {
3010 MCAsmParser &Parser = getParser();
3013 // If this is not the end of the statement, report an error.
3014 if (getLexer().isNot(AsmToken::EndOfStatement))
3015 return reportParseError("unexpected token, expected end of statement");
3017 setFeatureBits(Mips::FeatureMSA, "msa");
3018 getTargetStreamer().emitDirectiveSetMsa();
3022 bool MipsAsmParser::parseSetNoMsaDirective() {
3023 MCAsmParser &Parser = getParser();
3026 // If this is not the end of the statement, report an error.
3027 if (getLexer().isNot(AsmToken::EndOfStatement))
3028 return reportParseError("unexpected token, expected end of statement");
3030 clearFeatureBits(Mips::FeatureMSA, "msa");
3031 getTargetStreamer().emitDirectiveSetNoMsa();
3035 bool MipsAsmParser::parseSetNoDspDirective() {
3036 MCAsmParser &Parser = getParser();
3037 Parser.Lex(); // Eat "nodsp".
3039 // If this is not the end of the statement, report an error.
3040 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3041 reportParseError("unexpected token, expected end of statement");
3045 clearFeatureBits(Mips::FeatureDSP, "dsp");
3046 getTargetStreamer().emitDirectiveSetNoDsp();
3050 bool MipsAsmParser::parseSetMips16Directive() {
3051 MCAsmParser &Parser = getParser();
3052 Parser.Lex(); // Eat "mips16".
3054 // If this is not the end of the statement, report an error.
3055 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3056 reportParseError("unexpected token, expected end of statement");
3060 setFeatureBits(Mips::FeatureMips16, "mips16");
3061 getTargetStreamer().emitDirectiveSetMips16();
3062 Parser.Lex(); // Consume the EndOfStatement.
3066 bool MipsAsmParser::parseSetNoMips16Directive() {
3067 MCAsmParser &Parser = getParser();
3068 Parser.Lex(); // Eat "nomips16".
3070 // If this is not the end of the statement, report an error.
3071 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3072 reportParseError("unexpected token, expected end of statement");
3076 clearFeatureBits(Mips::FeatureMips16, "mips16");
3077 getTargetStreamer().emitDirectiveSetNoMips16();
3078 Parser.Lex(); // Consume the EndOfStatement.
3082 bool MipsAsmParser::parseSetFpDirective() {
3083 MCAsmParser &Parser = getParser();
3084 MipsABIFlagsSection::FpABIKind FpAbiVal;
3085 // Line can be: .set fp=32
3088 Parser.Lex(); // Eat fp token
3089 AsmToken Tok = Parser.getTok();
3090 if (Tok.isNot(AsmToken::Equal)) {
3091 reportParseError("unexpected token, expected equals sign '='");
3094 Parser.Lex(); // Eat '=' token.
3095 Tok = Parser.getTok();
3097 if (!parseFpABIValue(FpAbiVal, ".set"))
3100 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3101 reportParseError("unexpected token, expected end of statement");
3104 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3105 Parser.Lex(); // Consume the EndOfStatement.
3109 bool MipsAsmParser::parseSetPopDirective() {
3110 MCAsmParser &Parser = getParser();
3111 SMLoc Loc = getLexer().getLoc();
3114 if (getLexer().isNot(AsmToken::EndOfStatement))
3115 return reportParseError("unexpected token, expected end of statement");
3117 // Always keep an element on the options "stack" to prevent the user
3118 // from changing the initial options. This is how we remember them.
3119 if (AssemblerOptions.size() == 2)
3120 return reportParseError(Loc, ".set pop with no .set push");
3122 AssemblerOptions.pop_back();
3123 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3125 getTargetStreamer().emitDirectiveSetPop();
3129 bool MipsAsmParser::parseSetPushDirective() {
3130 MCAsmParser &Parser = getParser();
3132 if (getLexer().isNot(AsmToken::EndOfStatement))
3133 return reportParseError("unexpected token, expected end of statement");
3135 // Create a copy of the current assembler options environment and push it.
3136 AssemblerOptions.push_back(
3137 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3139 getTargetStreamer().emitDirectiveSetPush();
3143 bool MipsAsmParser::parseSetAssignment() {
3145 const MCExpr *Value;
3146 MCAsmParser &Parser = getParser();
3148 if (Parser.parseIdentifier(Name))
3149 reportParseError("expected identifier after .set");
3151 if (getLexer().isNot(AsmToken::Comma))
3152 return reportParseError("unexpected token, expected comma");
3155 if (Parser.parseExpression(Value))
3156 return reportParseError("expected valid expression after comma");
3158 // Check if the Name already exists as a symbol.
3159 MCSymbol *Sym = getContext().LookupSymbol(Name);
3161 return reportParseError("symbol already defined");
3162 Sym = getContext().GetOrCreateSymbol(Name);
3163 Sym->setVariableValue(Value);
3168 bool MipsAsmParser::parseSetMips0Directive() {
3169 MCAsmParser &Parser = getParser();
3171 if (getLexer().isNot(AsmToken::EndOfStatement))
3172 return reportParseError("unexpected token, expected end of statement");
3174 // Reset assembler options to their initial values.
3175 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3176 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3178 getTargetStreamer().emitDirectiveSetMips0();
3182 bool MipsAsmParser::parseSetArchDirective() {
3183 MCAsmParser &Parser = getParser();
3185 if (getLexer().isNot(AsmToken::Equal))
3186 return reportParseError("unexpected token, expected equals sign");
3190 if (Parser.parseIdentifier(Arch))
3191 return reportParseError("expected arch identifier");
3193 StringRef ArchFeatureName =
3194 StringSwitch<StringRef>(Arch)
3195 .Case("mips1", "mips1")
3196 .Case("mips2", "mips2")
3197 .Case("mips3", "mips3")
3198 .Case("mips4", "mips4")
3199 .Case("mips5", "mips5")
3200 .Case("mips32", "mips32")
3201 .Case("mips32r2", "mips32r2")
3202 .Case("mips32r6", "mips32r6")
3203 .Case("mips64", "mips64")
3204 .Case("mips64r2", "mips64r2")
3205 .Case("mips64r6", "mips64r6")
3206 .Case("cnmips", "cnmips")
3207 .Case("r4000", "mips3") // This is an implementation of Mips3.
3210 if (ArchFeatureName.empty())
3211 return reportParseError("unsupported architecture");
3213 selectArch(ArchFeatureName);
3214 getTargetStreamer().emitDirectiveSetArch(Arch);
3218 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3219 MCAsmParser &Parser = getParser();
3221 if (getLexer().isNot(AsmToken::EndOfStatement))
3222 return reportParseError("unexpected token, expected end of statement");
3226 llvm_unreachable("Unimplemented feature");
3227 case Mips::FeatureDSP:
3228 setFeatureBits(Mips::FeatureDSP, "dsp");
3229 getTargetStreamer().emitDirectiveSetDsp();
3231 case Mips::FeatureMicroMips:
3232 getTargetStreamer().emitDirectiveSetMicroMips();
3234 case Mips::FeatureMips1:
3235 selectArch("mips1");
3236 getTargetStreamer().emitDirectiveSetMips1();
3238 case Mips::FeatureMips2:
3239 selectArch("mips2");
3240 getTargetStreamer().emitDirectiveSetMips2();
3242 case Mips::FeatureMips3:
3243 selectArch("mips3");
3244 getTargetStreamer().emitDirectiveSetMips3();
3246 case Mips::FeatureMips4:
3247 selectArch("mips4");
3248 getTargetStreamer().emitDirectiveSetMips4();
3250 case Mips::FeatureMips5:
3251 selectArch("mips5");
3252 getTargetStreamer().emitDirectiveSetMips5();
3254 case Mips::FeatureMips32:
3255 selectArch("mips32");
3256 getTargetStreamer().emitDirectiveSetMips32();
3258 case Mips::FeatureMips32r2:
3259 selectArch("mips32r2");
3260 getTargetStreamer().emitDirectiveSetMips32R2();
3262 case Mips::FeatureMips32r6:
3263 selectArch("mips32r6");
3264 getTargetStreamer().emitDirectiveSetMips32R6();
3266 case Mips::FeatureMips64:
3267 selectArch("mips64");
3268 getTargetStreamer().emitDirectiveSetMips64();
3270 case Mips::FeatureMips64r2:
3271 selectArch("mips64r2");
3272 getTargetStreamer().emitDirectiveSetMips64R2();
3274 case Mips::FeatureMips64r6:
3275 selectArch("mips64r6");
3276 getTargetStreamer().emitDirectiveSetMips64R6();
3282 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3283 MCAsmParser &Parser = getParser();
3284 if (getLexer().isNot(AsmToken::Comma)) {
3285 SMLoc Loc = getLexer().getLoc();
3286 Parser.eatToEndOfStatement();
3287 return Error(Loc, ErrorStr);
3290 Parser.Lex(); // Eat the comma.
3294 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3295 if (AssemblerOptions.back()->isReorder())
3296 Warning(Loc, ".cpload should be inside a noreorder section");
3298 if (inMips16Mode()) {
3299 reportParseError(".cpload is not supported in Mips16 mode");
3303 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3304 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3305 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3306 reportParseError("expected register containing function address");
3310 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3311 if (!RegOpnd.isGPRAsmReg()) {
3312 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3316 // If this is not the end of the statement, report an error.
3317 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3318 reportParseError("unexpected token, expected end of statement");
3322 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3326 bool MipsAsmParser::parseDirectiveCPSetup() {
3327 MCAsmParser &Parser = getParser();
3330 bool SaveIsReg = true;
3332 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3333 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3334 if (ResTy == MatchOperand_NoMatch) {
3335 reportParseError("expected register containing function address");
3336 Parser.eatToEndOfStatement();
3340 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3341 if (!FuncRegOpnd.isGPRAsmReg()) {
3342 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3343 Parser.eatToEndOfStatement();
3347 FuncReg = FuncRegOpnd.getGPR32Reg();
3350 if (!eatComma("unexpected token, expected comma"))
3353 ResTy = parseAnyRegister(TmpReg);
3354 if (ResTy == MatchOperand_NoMatch) {
3355 const AsmToken &Tok = Parser.getTok();
3356 if (Tok.is(AsmToken::Integer)) {
3357 Save = Tok.getIntVal();
3361 reportParseError("expected save register or stack offset");
3362 Parser.eatToEndOfStatement();
3366 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3367 if (!SaveOpnd.isGPRAsmReg()) {
3368 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3369 Parser.eatToEndOfStatement();
3372 Save = SaveOpnd.getGPR32Reg();
3375 if (!eatComma("unexpected token, expected comma"))
3379 if (Parser.parseIdentifier(Name))
3380 reportParseError("expected identifier");
3381 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3383 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3387 bool MipsAsmParser::parseDirectiveNaN() {
3388 MCAsmParser &Parser = getParser();
3389 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3390 const AsmToken &Tok = Parser.getTok();
3392 if (Tok.getString() == "2008") {
3394 getTargetStreamer().emitDirectiveNaN2008();
3396 } else if (Tok.getString() == "legacy") {
3398 getTargetStreamer().emitDirectiveNaNLegacy();
3402 // If we don't recognize the option passed to the .nan
3403 // directive (e.g. no option or unknown option), emit an error.
3404 reportParseError("invalid option in .nan directive");
3408 bool MipsAsmParser::parseDirectiveSet() {
3409 MCAsmParser &Parser = getParser();
3410 // Get the next token.
3411 const AsmToken &Tok = Parser.getTok();
3413 if (Tok.getString() == "noat") {
3414 return parseSetNoAtDirective();
3415 } else if (Tok.getString() == "at") {
3416 return parseSetAtDirective();
3417 } else if (Tok.getString() == "arch") {
3418 return parseSetArchDirective();
3419 } else if (Tok.getString() == "fp") {
3420 return parseSetFpDirective();
3421 } else if (Tok.getString() == "pop") {
3422 return parseSetPopDirective();
3423 } else if (Tok.getString() == "push") {
3424 return parseSetPushDirective();
3425 } else if (Tok.getString() == "reorder") {
3426 return parseSetReorderDirective();
3427 } else if (Tok.getString() == "noreorder") {
3428 return parseSetNoReorderDirective();
3429 } else if (Tok.getString() == "macro") {
3430 return parseSetMacroDirective();
3431 } else if (Tok.getString() == "nomacro") {
3432 return parseSetNoMacroDirective();
3433 } else if (Tok.getString() == "mips16") {
3434 return parseSetMips16Directive();
3435 } else if (Tok.getString() == "nomips16") {
3436 return parseSetNoMips16Directive();
3437 } else if (Tok.getString() == "nomicromips") {
3438 getTargetStreamer().emitDirectiveSetNoMicroMips();
3439 Parser.eatToEndOfStatement();
3441 } else if (Tok.getString() == "micromips") {
3442 return parseSetFeature(Mips::FeatureMicroMips);
3443 } else if (Tok.getString() == "mips0") {
3444 return parseSetMips0Directive();
3445 } else if (Tok.getString() == "mips1") {
3446 return parseSetFeature(Mips::FeatureMips1);
3447 } else if (Tok.getString() == "mips2") {
3448 return parseSetFeature(Mips::FeatureMips2);
3449 } else if (Tok.getString() == "mips3") {
3450 return parseSetFeature(Mips::FeatureMips3);
3451 } else if (Tok.getString() == "mips4") {
3452 return parseSetFeature(Mips::FeatureMips4);
3453 } else if (Tok.getString() == "mips5") {
3454 return parseSetFeature(Mips::FeatureMips5);
3455 } else if (Tok.getString() == "mips32") {
3456 return parseSetFeature(Mips::FeatureMips32);
3457 } else if (Tok.getString() == "mips32r2") {
3458 return parseSetFeature(Mips::FeatureMips32r2);
3459 } else if (Tok.getString() == "mips32r6") {
3460 return parseSetFeature(Mips::FeatureMips32r6);
3461 } else if (Tok.getString() == "mips64") {
3462 return parseSetFeature(Mips::FeatureMips64);
3463 } else if (Tok.getString() == "mips64r2") {
3464 return parseSetFeature(Mips::FeatureMips64r2);
3465 } else if (Tok.getString() == "mips64r6") {
3466 return parseSetFeature(Mips::FeatureMips64r6);
3467 } else if (Tok.getString() == "dsp") {
3468 return parseSetFeature(Mips::FeatureDSP);
3469 } else if (Tok.getString() == "nodsp") {
3470 return parseSetNoDspDirective();
3471 } else if (Tok.getString() == "msa") {
3472 return parseSetMsaDirective();
3473 } else if (Tok.getString() == "nomsa") {
3474 return parseSetNoMsaDirective();
3476 // It is just an identifier, look for an assignment.
3477 parseSetAssignment();
3484 /// parseDataDirective
3485 /// ::= .word [ expression (, expression)* ]
3486 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3487 MCAsmParser &Parser = getParser();
3488 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3490 const MCExpr *Value;
3491 if (getParser().parseExpression(Value))
3494 getParser().getStreamer().EmitValue(Value, Size);
3496 if (getLexer().is(AsmToken::EndOfStatement))
3499 if (getLexer().isNot(AsmToken::Comma))
3500 return Error(L, "unexpected token, expected comma");
3509 /// parseDirectiveGpWord
3510 /// ::= .gpword local_sym
3511 bool MipsAsmParser::parseDirectiveGpWord() {
3512 MCAsmParser &Parser = getParser();
3513 const MCExpr *Value;
3514 // EmitGPRel32Value requires an expression, so we are using base class
3515 // method to evaluate the expression.
3516 if (getParser().parseExpression(Value))
3518 getParser().getStreamer().EmitGPRel32Value(Value);
3520 if (getLexer().isNot(AsmToken::EndOfStatement))
3521 return Error(getLexer().getLoc(),
3522 "unexpected token, expected end of statement");
3523 Parser.Lex(); // Eat EndOfStatement token.
3527 /// parseDirectiveGpDWord
3528 /// ::= .gpdword local_sym
3529 bool MipsAsmParser::parseDirectiveGpDWord() {
3530 MCAsmParser &Parser = getParser();
3531 const MCExpr *Value;
3532 // EmitGPRel64Value requires an expression, so we are using base class
3533 // method to evaluate the expression.
3534 if (getParser().parseExpression(Value))
3536 getParser().getStreamer().EmitGPRel64Value(Value);
3538 if (getLexer().isNot(AsmToken::EndOfStatement))
3539 return Error(getLexer().getLoc(),
3540 "unexpected token, expected end of statement");
3541 Parser.Lex(); // Eat EndOfStatement token.
3545 bool MipsAsmParser::parseDirectiveOption() {
3546 MCAsmParser &Parser = getParser();
3547 // Get the option token.
3548 AsmToken Tok = Parser.getTok();
3549 // At the moment only identifiers are supported.
3550 if (Tok.isNot(AsmToken::Identifier)) {
3551 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3552 Parser.eatToEndOfStatement();
3556 StringRef Option = Tok.getIdentifier();
3558 if (Option == "pic0") {
3559 getTargetStreamer().emitDirectiveOptionPic0();
3561 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3562 Error(Parser.getTok().getLoc(),
3563 "unexpected token, expected end of statement");
3564 Parser.eatToEndOfStatement();
3569 if (Option == "pic2") {
3570 getTargetStreamer().emitDirectiveOptionPic2();
3572 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3573 Error(Parser.getTok().getLoc(),
3574 "unexpected token, expected end of statement");
3575 Parser.eatToEndOfStatement();
3581 Warning(Parser.getTok().getLoc(),
3582 "unknown option, expected 'pic0' or 'pic2'");
3583 Parser.eatToEndOfStatement();
3587 /// parseDirectiveModule
3588 /// ::= .module oddspreg
3589 /// ::= .module nooddspreg
3590 /// ::= .module fp=value
3591 bool MipsAsmParser::parseDirectiveModule() {
3592 MCAsmParser &Parser = getParser();
3593 MCAsmLexer &Lexer = getLexer();
3594 SMLoc L = Lexer.getLoc();
3596 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3597 // TODO : get a better message.
3598 reportParseError(".module directive must appear before any code");
3602 if (Lexer.is(AsmToken::Identifier)) {
3603 StringRef Option = Parser.getTok().getString();
3606 if (Option == "oddspreg") {
3607 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3608 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3610 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3611 reportParseError("unexpected token, expected end of statement");
3616 } else if (Option == "nooddspreg") {
3618 Error(L, "'.module nooddspreg' requires the O32 ABI");
3622 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3623 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3625 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3626 reportParseError("unexpected token, expected end of statement");
3631 } else if (Option == "fp") {
3632 return parseDirectiveModuleFP();
3635 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3641 /// parseDirectiveModuleFP
3645 bool MipsAsmParser::parseDirectiveModuleFP() {
3646 MCAsmParser &Parser = getParser();
3647 MCAsmLexer &Lexer = getLexer();
3649 if (Lexer.isNot(AsmToken::Equal)) {
3650 reportParseError("unexpected token, expected equals sign '='");
3653 Parser.Lex(); // Eat '=' token.
3655 MipsABIFlagsSection::FpABIKind FpABI;
3656 if (!parseFpABIValue(FpABI, ".module"))
3659 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3660 reportParseError("unexpected token, expected end of statement");
3664 // Emit appropriate flags.
3665 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3666 Parser.Lex(); // Consume the EndOfStatement.
3670 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3671 StringRef Directive) {
3672 MCAsmParser &Parser = getParser();
3673 MCAsmLexer &Lexer = getLexer();
3675 if (Lexer.is(AsmToken::Identifier)) {
3676 StringRef Value = Parser.getTok().getString();
3679 if (Value != "xx") {
3680 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3685 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3689 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3693 if (Lexer.is(AsmToken::Integer)) {
3694 unsigned Value = Parser.getTok().getIntVal();
3697 if (Value != 32 && Value != 64) {
3698 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3704 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3708 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3710 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3718 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3719 MCAsmParser &Parser = getParser();
3720 StringRef IDVal = DirectiveID.getString();
3722 if (IDVal == ".cpload")
3723 return parseDirectiveCpLoad(DirectiveID.getLoc());
3724 if (IDVal == ".dword") {
3725 parseDataDirective(8, DirectiveID.getLoc());
3728 if (IDVal == ".ent") {
3729 StringRef SymbolName;
3731 if (Parser.parseIdentifier(SymbolName)) {
3732 reportParseError("expected identifier after .ent");
3736 // There's an undocumented extension that allows an integer to
3737 // follow the name of the procedure which AFAICS is ignored by GAS.
3738 // Example: .ent foo,2
3739 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3740 if (getLexer().isNot(AsmToken::Comma)) {
3741 // Even though we accept this undocumented extension for compatibility
3742 // reasons, the additional integer argument does not actually change
3743 // the behaviour of the '.ent' directive, so we would like to discourage
3744 // its use. We do this by not referring to the extended version in
3745 // error messages which are not directly related to its use.
3746 reportParseError("unexpected token, expected end of statement");
3749 Parser.Lex(); // Eat the comma.
3750 const MCExpr *DummyNumber;
3751 int64_t DummyNumberVal;
3752 // If the user was explicitly trying to use the extended version,
3753 // we still give helpful extension-related error messages.
3754 if (Parser.parseExpression(DummyNumber)) {
3755 reportParseError("expected number after comma");
3758 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3759 reportParseError("expected an absolute expression after comma");
3764 // If this is not the end of the statement, report an error.
3765 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3766 reportParseError("unexpected token, expected end of statement");
3770 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3772 getTargetStreamer().emitDirectiveEnt(*Sym);
3777 if (IDVal == ".end") {
3778 StringRef SymbolName;
3780 if (Parser.parseIdentifier(SymbolName)) {
3781 reportParseError("expected identifier after .end");
3785 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3786 reportParseError("unexpected token, expected end of statement");
3790 if (CurrentFn == nullptr) {
3791 reportParseError(".end used without .ent");
3795 if ((SymbolName != CurrentFn->getName())) {
3796 reportParseError(".end symbol does not match .ent symbol");
3800 getTargetStreamer().emitDirectiveEnd(SymbolName);
3801 CurrentFn = nullptr;
3805 if (IDVal == ".frame") {
3806 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3807 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3808 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3809 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3810 reportParseError("expected stack register");
3814 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3815 if (!StackRegOpnd.isGPRAsmReg()) {
3816 reportParseError(StackRegOpnd.getStartLoc(),
3817 "expected general purpose register");
3820 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3822 if (Parser.getTok().is(AsmToken::Comma))
3825 reportParseError("unexpected token, expected comma");
3829 // Parse the frame size.
3830 const MCExpr *FrameSize;
3831 int64_t FrameSizeVal;
3833 if (Parser.parseExpression(FrameSize)) {
3834 reportParseError("expected frame size value");
3838 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3839 reportParseError("frame size not an absolute expression");
3843 if (Parser.getTok().is(AsmToken::Comma))
3846 reportParseError("unexpected token, expected comma");
3850 // Parse the return register.
3852 ResTy = parseAnyRegister(TmpReg);
3853 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3854 reportParseError("expected return register");
3858 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3859 if (!ReturnRegOpnd.isGPRAsmReg()) {
3860 reportParseError(ReturnRegOpnd.getStartLoc(),
3861 "expected general purpose register");
3865 // If this is not the end of the statement, report an error.
3866 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3867 reportParseError("unexpected token, expected end of statement");
3871 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3872 ReturnRegOpnd.getGPR32Reg());
3876 if (IDVal == ".set") {
3877 return parseDirectiveSet();
3880 if (IDVal == ".mask" || IDVal == ".fmask") {
3881 // .mask bitmask, frame_offset
3882 // bitmask: One bit for each register used.
3883 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3884 // first register is expected to be saved.
3886 // .mask 0x80000000, -4
3887 // .fmask 0x80000000, -4
3890 // Parse the bitmask
3891 const MCExpr *BitMask;
3894 if (Parser.parseExpression(BitMask)) {
3895 reportParseError("expected bitmask value");
3899 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3900 reportParseError("bitmask not an absolute expression");
3904 if (Parser.getTok().is(AsmToken::Comma))
3907 reportParseError("unexpected token, expected comma");
3911 // Parse the frame_offset
3912 const MCExpr *FrameOffset;
3913 int64_t FrameOffsetVal;
3915 if (Parser.parseExpression(FrameOffset)) {
3916 reportParseError("expected frame offset value");
3920 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3921 reportParseError("frame offset not an absolute expression");
3925 // If this is not the end of the statement, report an error.
3926 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3927 reportParseError("unexpected token, expected end of statement");
3931 if (IDVal == ".mask")
3932 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3934 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3938 if (IDVal == ".nan")
3939 return parseDirectiveNaN();
3941 if (IDVal == ".gpword") {
3942 parseDirectiveGpWord();
3946 if (IDVal == ".gpdword") {
3947 parseDirectiveGpDWord();
3951 if (IDVal == ".word") {
3952 parseDataDirective(4, DirectiveID.getLoc());
3956 if (IDVal == ".option")
3957 return parseDirectiveOption();
3959 if (IDVal == ".abicalls") {
3960 getTargetStreamer().emitDirectiveAbiCalls();
3961 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3962 Error(Parser.getTok().getLoc(),
3963 "unexpected token, expected end of statement");
3965 Parser.eatToEndOfStatement();
3970 if (IDVal == ".cpsetup")
3971 return parseDirectiveCPSetup();
3973 if (IDVal == ".module")
3974 return parseDirectiveModule();
3979 extern "C" void LLVMInitializeMipsAsmParser() {
3980 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3981 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3982 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3983 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3986 #define GET_REGISTER_MATCHER
3987 #define GET_MATCHER_IMPLEMENTATION
3988 #include "MipsGenAsmMatcher.inc"