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 bool isInvNum() const { return Kind == k_Immediate; }
813 bool isLSAImm() const {
814 if (!isConstantImm())
816 int64_t Val = getConstantImm();
817 return 1 <= Val && Val <= 4;
819 bool isRegList() const { return Kind == k_RegList; }
821 StringRef getToken() const {
822 assert(Kind == k_Token && "Invalid access!");
823 return StringRef(Tok.Data, Tok.Length);
826 unsigned getReg() const override {
827 // As a special case until we sort out the definition of div/divu, pretend
828 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
829 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
830 RegIdx.Kind & RegKind_GPR)
831 return getGPR32Reg(); // FIXME: GPR64 too
833 assert(Kind == k_PhysRegister && "Invalid access!");
837 const MCExpr *getImm() const {
838 assert((Kind == k_Immediate) && "Invalid access!");
842 int64_t getConstantImm() const {
843 const MCExpr *Val = getImm();
844 return static_cast<const MCConstantExpr *>(Val)->getValue();
847 MipsOperand *getMemBase() const {
848 assert((Kind == k_Memory) && "Invalid access!");
852 const MCExpr *getMemOff() const {
853 assert((Kind == k_Memory) && "Invalid access!");
857 int64_t getConstantMemOff() const {
858 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
861 const SmallVectorImpl<unsigned> &getRegList() const {
862 assert((Kind == k_RegList) && "Invalid access!");
863 return *(RegList.List);
866 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
867 MipsAsmParser &Parser) {
868 auto Op = make_unique<MipsOperand>(k_Token, Parser);
869 Op->Tok.Data = Str.data();
870 Op->Tok.Length = Str.size();
876 /// Create a numeric register (e.g. $1). The exact register remains
877 /// unresolved until an instruction successfully matches
878 static std::unique_ptr<MipsOperand>
879 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
880 SMLoc E, MipsAsmParser &Parser) {
881 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
882 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
885 /// Create a register that is definitely a GPR.
886 /// This is typically only used for named registers such as $gp.
887 static std::unique_ptr<MipsOperand>
888 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
889 MipsAsmParser &Parser) {
890 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
893 /// Create a register that is definitely a FGR.
894 /// This is typically only used for named registers such as $f0.
895 static std::unique_ptr<MipsOperand>
896 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
897 MipsAsmParser &Parser) {
898 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
901 /// Create a register that is definitely a HWReg.
902 /// This is typically only used for named registers such as $hwr_cpunum.
903 static std::unique_ptr<MipsOperand>
904 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
905 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
906 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
909 /// Create a register that is definitely an FCC.
910 /// This is typically only used for named registers such as $fcc0.
911 static std::unique_ptr<MipsOperand>
912 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
913 MipsAsmParser &Parser) {
914 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
917 /// Create a register that is definitely an ACC.
918 /// This is typically only used for named registers such as $ac0.
919 static std::unique_ptr<MipsOperand>
920 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
921 MipsAsmParser &Parser) {
922 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
925 /// Create a register that is definitely an MSA128.
926 /// This is typically only used for named registers such as $w0.
927 static std::unique_ptr<MipsOperand>
928 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
929 SMLoc E, MipsAsmParser &Parser) {
930 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
933 /// Create a register that is definitely an MSACtrl.
934 /// This is typically only used for named registers such as $msaaccess.
935 static std::unique_ptr<MipsOperand>
936 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
937 SMLoc E, MipsAsmParser &Parser) {
938 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
941 static std::unique_ptr<MipsOperand>
942 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
943 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
950 static std::unique_ptr<MipsOperand>
951 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
952 SMLoc E, MipsAsmParser &Parser) {
953 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
954 Op->Mem.Base = Base.release();
961 static std::unique_ptr<MipsOperand>
962 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
963 MipsAsmParser &Parser) {
964 assert (Regs.size() > 0 && "Empty list not allowed");
966 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
967 Op->RegList.List = new SmallVector<unsigned, 10>();
968 for (auto Reg : Regs)
969 Op->RegList.List->push_back(Reg);
970 Op->StartLoc = StartLoc;
975 bool isGPRAsmReg() const {
976 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
978 bool isMM16AsmReg() const {
979 if (!(isRegIdx() && RegIdx.Kind))
981 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
982 || RegIdx.Index == 16 || RegIdx.Index == 17);
984 bool isMM16AsmRegZero() const {
985 if (!(isRegIdx() && RegIdx.Kind))
987 return (RegIdx.Index == 0 ||
988 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
991 bool isFGRAsmReg() const {
992 // AFGR64 is $0-$15 but we handle this in getAFGR64()
993 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
995 bool isHWRegsAsmReg() const {
996 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
998 bool isCCRAsmReg() const {
999 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1001 bool isFCCAsmReg() const {
1002 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1004 if (!AsmParser.hasEightFccRegisters())
1005 return RegIdx.Index == 0;
1006 return RegIdx.Index <= 7;
1008 bool isACCAsmReg() const {
1009 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1011 bool isCOP2AsmReg() const {
1012 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1014 bool isCOP3AsmReg() const {
1015 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1017 bool isMSA128AsmReg() const {
1018 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1020 bool isMSACtrlAsmReg() const {
1021 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1024 /// getStartLoc - Get the location of the first token of this operand.
1025 SMLoc getStartLoc() const override { return StartLoc; }
1026 /// getEndLoc - Get the location of the last token of this operand.
1027 SMLoc getEndLoc() const override { return EndLoc; }
1029 virtual ~MipsOperand() {
1037 delete RegList.List;
1038 case k_PhysRegister:
1039 case k_RegisterIndex:
1045 void print(raw_ostream &OS) const override {
1054 Mem.Base->print(OS);
1059 case k_PhysRegister:
1060 OS << "PhysReg<" << PhysReg.Num << ">";
1062 case k_RegisterIndex:
1063 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1070 for (auto Reg : (*RegList.List))
1076 }; // class MipsOperand
1080 extern const MCInstrDesc MipsInsts[];
1082 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1083 return MipsInsts[Opcode];
1086 static bool hasShortDelaySlot(unsigned Opcode) {
1089 case Mips::JALRS_MM:
1090 case Mips::JALRS16_MM:
1091 case Mips::BGEZALS_MM:
1092 case Mips::BLTZALS_MM:
1099 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1100 SmallVectorImpl<MCInst> &Instructions) {
1101 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1105 if (MCID.isBranch() || MCID.isCall()) {
1106 const unsigned Opcode = Inst.getOpcode();
1116 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1117 Offset = Inst.getOperand(2);
1118 if (!Offset.isImm())
1119 break; // We'll deal with this situation later on when applying fixups.
1120 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1121 return Error(IDLoc, "branch target out of range");
1122 if (OffsetToAlignment(Offset.getImm(),
1123 1LL << (inMicroMipsMode() ? 1 : 2)))
1124 return Error(IDLoc, "branch to misaligned address");
1138 case Mips::BGEZAL_MM:
1139 case Mips::BLTZAL_MM:
1142 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1143 Offset = Inst.getOperand(1);
1144 if (!Offset.isImm())
1145 break; // We'll deal with this situation later on when applying fixups.
1146 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1147 return Error(IDLoc, "branch target out of range");
1148 if (OffsetToAlignment(Offset.getImm(),
1149 1LL << (inMicroMipsMode() ? 1 : 2)))
1150 return Error(IDLoc, "branch to misaligned address");
1155 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1156 // We still accept it but it is a normal nop.
1157 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1158 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1159 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1163 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1164 // If this instruction has a delay slot and .set reorder is active,
1165 // emit a NOP after it.
1166 Instructions.push_back(Inst);
1168 if (hasShortDelaySlot(Inst.getOpcode())) {
1169 NopInst.setOpcode(Mips::MOVE16_MM);
1170 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1171 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1173 NopInst.setOpcode(Mips::SLL);
1174 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1175 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1176 NopInst.addOperand(MCOperand::CreateImm(0));
1178 Instructions.push_back(NopInst);
1182 if (MCID.mayLoad() || MCID.mayStore()) {
1183 // Check the offset of memory operand, if it is a symbol
1184 // reference or immediate we may have to expand instructions.
1185 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1186 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1187 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1188 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1189 MCOperand &Op = Inst.getOperand(i);
1191 int MemOffset = Op.getImm();
1192 if (MemOffset < -32768 || MemOffset > 32767) {
1193 // Offset can't exceed 16bit value.
1194 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1197 } else if (Op.isExpr()) {
1198 const MCExpr *Expr = Op.getExpr();
1199 if (Expr->getKind() == MCExpr::SymbolRef) {
1200 const MCSymbolRefExpr *SR =
1201 static_cast<const MCSymbolRefExpr *>(Expr);
1202 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1204 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1207 } else if (!isEvaluated(Expr)) {
1208 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1216 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1217 if (inMicroMipsMode()) {
1221 switch (Inst.getOpcode()) {
1224 case Mips::ADDIUS5_MM:
1225 Opnd = Inst.getOperand(2);
1227 return Error(IDLoc, "expected immediate operand kind");
1228 Imm = Opnd.getImm();
1229 if (Imm < -8 || Imm > 7)
1230 return Error(IDLoc, "immediate operand value out of range");
1232 case Mips::ADDIUSP_MM:
1233 Opnd = Inst.getOperand(0);
1235 return Error(IDLoc, "expected immediate operand kind");
1236 Imm = Opnd.getImm();
1237 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1239 return Error(IDLoc, "immediate operand value out of range");
1241 case Mips::SLL16_MM:
1242 case Mips::SRL16_MM:
1243 Opnd = Inst.getOperand(2);
1245 return Error(IDLoc, "expected immediate operand kind");
1246 Imm = Opnd.getImm();
1247 if (Imm < 1 || Imm > 8)
1248 return Error(IDLoc, "immediate operand value out of range");
1251 Opnd = Inst.getOperand(1);
1253 return Error(IDLoc, "expected immediate operand kind");
1254 Imm = Opnd.getImm();
1255 if (Imm < -1 || Imm > 126)
1256 return Error(IDLoc, "immediate operand value out of range");
1258 case Mips::ADDIUR2_MM:
1259 Opnd = Inst.getOperand(2);
1261 return Error(IDLoc, "expected immediate operand kind");
1262 Imm = Opnd.getImm();
1263 if (!(Imm == 1 || Imm == -1 ||
1264 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1265 return Error(IDLoc, "immediate operand value out of range");
1267 case Mips::ADDIUR1SP_MM:
1268 Opnd = Inst.getOperand(1);
1270 return Error(IDLoc, "expected immediate operand kind");
1271 Imm = Opnd.getImm();
1272 if (OffsetToAlignment(Imm, 4LL))
1273 return Error(IDLoc, "misaligned immediate operand value");
1274 if (Imm < 0 || Imm > 255)
1275 return Error(IDLoc, "immediate operand value out of range");
1277 case Mips::ANDI16_MM:
1278 Opnd = Inst.getOperand(2);
1280 return Error(IDLoc, "expected immediate operand kind");
1281 Imm = Opnd.getImm();
1282 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1283 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1284 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1285 return Error(IDLoc, "immediate operand value out of range");
1287 case Mips::LBU16_MM:
1288 Opnd = Inst.getOperand(2);
1290 return Error(IDLoc, "expected immediate operand kind");
1291 Imm = Opnd.getImm();
1292 if (Imm < -1 || Imm > 14)
1293 return Error(IDLoc, "immediate operand value out of range");
1296 Opnd = Inst.getOperand(2);
1298 return Error(IDLoc, "expected immediate operand kind");
1299 Imm = Opnd.getImm();
1300 if (Imm < 0 || Imm > 15)
1301 return Error(IDLoc, "immediate operand value out of range");
1303 case Mips::LHU16_MM:
1305 Opnd = Inst.getOperand(2);
1307 return Error(IDLoc, "expected immediate operand kind");
1308 Imm = Opnd.getImm();
1309 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1310 return Error(IDLoc, "immediate operand value out of range");
1314 Opnd = Inst.getOperand(2);
1316 return Error(IDLoc, "expected immediate operand kind");
1317 Imm = Opnd.getImm();
1318 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1319 return Error(IDLoc, "immediate operand value out of range");
1324 if (needsExpansion(Inst))
1325 return expandInstruction(Inst, IDLoc, Instructions);
1327 Instructions.push_back(Inst);
1332 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1334 switch (Inst.getOpcode()) {
1335 case Mips::LoadImm32Reg:
1336 case Mips::LoadAddr32Imm:
1337 case Mips::LoadAddr32Reg:
1338 case Mips::LoadImm64Reg:
1345 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1346 SmallVectorImpl<MCInst> &Instructions) {
1347 switch (Inst.getOpcode()) {
1349 assert(0 && "unimplemented expansion");
1351 case Mips::LoadImm32Reg:
1352 return expandLoadImm(Inst, IDLoc, Instructions);
1353 case Mips::LoadImm64Reg:
1355 Error(IDLoc, "instruction requires a 64-bit architecture");
1358 return expandLoadImm(Inst, IDLoc, Instructions);
1359 case Mips::LoadAddr32Imm:
1360 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1361 case Mips::LoadAddr32Reg:
1362 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1367 template <bool PerformShift>
1368 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1369 SmallVectorImpl<MCInst> &Instructions) {
1372 tmpInst.setOpcode(Mips::DSLL);
1373 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1374 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1375 tmpInst.addOperand(MCOperand::CreateImm(16));
1376 tmpInst.setLoc(IDLoc);
1377 Instructions.push_back(tmpInst);
1380 tmpInst.setOpcode(Mips::ORi);
1381 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1382 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1383 tmpInst.addOperand(Operand);
1384 tmpInst.setLoc(IDLoc);
1385 Instructions.push_back(tmpInst);
1388 template <int Shift, bool PerformShift>
1389 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1390 SmallVectorImpl<MCInst> &Instructions) {
1391 createShiftOr<PerformShift>(
1392 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1393 IDLoc, Instructions);
1397 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1398 SmallVectorImpl<MCInst> &Instructions) {
1400 const MCOperand &ImmOp = Inst.getOperand(1);
1401 assert(ImmOp.isImm() && "expected immediate operand kind");
1402 const MCOperand &RegOp = Inst.getOperand(0);
1403 assert(RegOp.isReg() && "expected register operand kind");
1405 int64_t ImmValue = ImmOp.getImm();
1406 tmpInst.setLoc(IDLoc);
1407 // FIXME: gas has a special case for values that are 000...1111, which
1408 // becomes a li -1 and then a dsrl
1409 if (0 <= ImmValue && ImmValue <= 65535) {
1410 // For 0 <= j <= 65535.
1411 // li d,j => ori d,$zero,j
1412 tmpInst.setOpcode(Mips::ORi);
1413 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1414 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1415 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1416 Instructions.push_back(tmpInst);
1417 } else if (ImmValue < 0 && ImmValue >= -32768) {
1418 // For -32768 <= j < 0.
1419 // li d,j => addiu d,$zero,j
1420 tmpInst.setOpcode(Mips::ADDiu);
1421 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1422 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1423 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1424 Instructions.push_back(tmpInst);
1425 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1426 // For any value of j that is representable as a 32-bit integer, create
1428 // li d,j => lui d,hi16(j)
1430 tmpInst.setOpcode(Mips::LUi);
1431 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1432 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1433 Instructions.push_back(tmpInst);
1434 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1435 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1437 Error(IDLoc, "instruction requires a 64-bit architecture");
1441 // <------- lo32 ------>
1442 // <------- hi32 ------>
1443 // <- hi16 -> <- lo16 ->
1444 // _________________________________
1446 // | 16-bytes | 16-bytes | 16-bytes |
1447 // |__________|__________|__________|
1449 // For any value of j that is representable as a 48-bit integer, create
1451 // li d,j => lui d,hi16(j)
1452 // ori d,d,hi16(lo32(j))
1454 // ori d,d,lo16(lo32(j))
1455 tmpInst.setOpcode(Mips::LUi);
1456 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1458 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1459 Instructions.push_back(tmpInst);
1460 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1461 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1464 Error(IDLoc, "instruction requires a 64-bit architecture");
1468 // <------- hi32 ------> <------- lo32 ------>
1469 // <- hi16 -> <- lo16 ->
1470 // ___________________________________________
1472 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1473 // |__________|__________|__________|__________|
1475 // For any value of j that isn't representable as a 48-bit integer.
1476 // li d,j => lui d,hi16(j)
1477 // ori d,d,lo16(hi32(j))
1479 // ori d,d,hi16(lo32(j))
1481 // ori d,d,lo16(lo32(j))
1482 tmpInst.setOpcode(Mips::LUi);
1483 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1485 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1486 Instructions.push_back(tmpInst);
1487 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1488 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1489 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1495 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1496 SmallVectorImpl<MCInst> &Instructions) {
1498 const MCOperand &ImmOp = Inst.getOperand(2);
1499 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1500 "expected immediate operand kind");
1501 if (!ImmOp.isImm()) {
1502 expandLoadAddressSym(Inst, IDLoc, Instructions);
1505 const MCOperand &SrcRegOp = Inst.getOperand(1);
1506 assert(SrcRegOp.isReg() && "expected register operand kind");
1507 const MCOperand &DstRegOp = Inst.getOperand(0);
1508 assert(DstRegOp.isReg() && "expected register operand kind");
1509 int ImmValue = ImmOp.getImm();
1510 if (-32768 <= ImmValue && ImmValue <= 65535) {
1511 // For -32768 <= j <= 65535.
1512 // la d,j(s) => addiu d,s,j
1513 tmpInst.setOpcode(Mips::ADDiu);
1514 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1515 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1516 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1517 Instructions.push_back(tmpInst);
1519 // For any other value of j that is representable as a 32-bit integer.
1520 // la d,j(s) => lui d,hi16(j)
1523 tmpInst.setOpcode(Mips::LUi);
1524 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1525 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1526 Instructions.push_back(tmpInst);
1528 tmpInst.setOpcode(Mips::ORi);
1529 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1530 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1531 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1532 Instructions.push_back(tmpInst);
1534 tmpInst.setOpcode(Mips::ADDu);
1535 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1536 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1537 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1538 Instructions.push_back(tmpInst);
1544 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1545 SmallVectorImpl<MCInst> &Instructions) {
1547 const MCOperand &ImmOp = Inst.getOperand(1);
1548 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1549 "expected immediate operand kind");
1550 if (!ImmOp.isImm()) {
1551 expandLoadAddressSym(Inst, IDLoc, Instructions);
1554 const MCOperand &RegOp = Inst.getOperand(0);
1555 assert(RegOp.isReg() && "expected register operand kind");
1556 int ImmValue = ImmOp.getImm();
1557 if (-32768 <= ImmValue && ImmValue <= 65535) {
1558 // For -32768 <= j <= 65535.
1559 // la d,j => addiu d,$zero,j
1560 tmpInst.setOpcode(Mips::ADDiu);
1561 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1562 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1563 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1564 Instructions.push_back(tmpInst);
1566 // For any other value of j that is representable as a 32-bit integer.
1567 // la d,j => lui d,hi16(j)
1569 tmpInst.setOpcode(Mips::LUi);
1570 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1571 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1572 Instructions.push_back(tmpInst);
1574 tmpInst.setOpcode(Mips::ORi);
1575 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1576 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1577 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1578 Instructions.push_back(tmpInst);
1584 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1585 SmallVectorImpl<MCInst> &Instructions) {
1586 // FIXME: If we do have a valid at register to use, we should generate a
1587 // slightly shorter sequence here.
1589 int ExprOperandNo = 1;
1590 // Sometimes the assembly parser will get the immediate expression as
1591 // a $zero + an immediate.
1592 if (Inst.getNumOperands() == 3) {
1593 assert(Inst.getOperand(1).getReg() ==
1594 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1597 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1598 assert(SymOp.isExpr() && "expected symbol operand kind");
1599 const MCOperand &RegOp = Inst.getOperand(0);
1600 unsigned RegNo = RegOp.getReg();
1601 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1602 const MCSymbolRefExpr *HiExpr =
1603 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1604 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1605 const MCSymbolRefExpr *LoExpr =
1606 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1607 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1609 // If it's a 64-bit architecture, expand to:
1610 // la d,sym => lui d,highest(sym)
1611 // ori d,d,higher(sym)
1613 // ori d,d,hi16(sym)
1615 // ori d,d,lo16(sym)
1616 const MCSymbolRefExpr *HighestExpr =
1617 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1618 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1619 const MCSymbolRefExpr *HigherExpr =
1620 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1621 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1623 tmpInst.setOpcode(Mips::LUi);
1624 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1625 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1626 Instructions.push_back(tmpInst);
1628 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1630 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1632 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1635 // Otherwise, expand to:
1636 // la d,sym => lui d,hi16(sym)
1637 // ori d,d,lo16(sym)
1638 tmpInst.setOpcode(Mips::LUi);
1639 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1640 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1641 Instructions.push_back(tmpInst);
1643 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1648 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1649 SmallVectorImpl<MCInst> &Instructions,
1650 bool isLoad, bool isImmOpnd) {
1651 const MCSymbolRefExpr *SR;
1653 unsigned ImmOffset, HiOffset, LoOffset;
1654 const MCExpr *ExprOffset;
1656 // 1st operand is either the source or destination register.
1657 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1658 unsigned RegOpNum = Inst.getOperand(0).getReg();
1659 // 2nd operand is the base register.
1660 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1661 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1662 // 3rd operand is either an immediate or expression.
1664 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1665 ImmOffset = Inst.getOperand(2).getImm();
1666 LoOffset = ImmOffset & 0x0000ffff;
1667 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1668 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1669 if (LoOffset & 0x8000)
1672 ExprOffset = Inst.getOperand(2).getExpr();
1673 // All instructions will have the same location.
1674 TempInst.setLoc(IDLoc);
1675 // These are some of the types of expansions we perform here:
1676 // 1) lw $8, sym => lui $8, %hi(sym)
1677 // lw $8, %lo(sym)($8)
1678 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1680 // lw $8, %lo(offset)($9)
1681 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1683 // lw $8, %lo(offset)($at)
1684 // 4) sw $8, sym => lui $at, %hi(sym)
1685 // sw $8, %lo(sym)($at)
1686 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1688 // sw $8, %lo(offset)($at)
1689 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1690 // ldc1 $f0, %lo(sym)($at)
1692 // For load instructions we can use the destination register as a temporary
1693 // if base and dst are different (examples 1 and 2) and if the base register
1694 // is general purpose otherwise we must use $at (example 6) and error if it's
1695 // not available. For stores we must use $at (examples 4 and 5) because we
1696 // must not clobber the source register setting up the offset.
1697 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1698 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1699 unsigned RegClassIDOp0 =
1700 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1701 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1702 (RegClassIDOp0 == Mips::GPR64RegClassID);
1703 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1704 TmpRegNum = RegOpNum;
1706 int AT = getATReg(IDLoc);
1707 // At this point we need AT to perform the expansions and we exit if it is
1712 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1715 TempInst.setOpcode(Mips::LUi);
1716 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1718 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1720 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1721 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1722 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1723 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1725 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1727 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1728 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1731 // Add the instruction to the list.
1732 Instructions.push_back(TempInst);
1733 // Prepare TempInst for next instruction.
1735 // Add temp register to base.
1736 TempInst.setOpcode(Mips::ADDu);
1737 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1738 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1739 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1740 Instructions.push_back(TempInst);
1742 // And finally, create original instruction with low part
1743 // of offset and new base.
1744 TempInst.setOpcode(Inst.getOpcode());
1745 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1746 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1748 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1750 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1751 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1752 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1754 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1756 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1757 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1760 Instructions.push_back(TempInst);
1764 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1765 // As described by the Mips32r2 spec, the registers Rd and Rs for
1766 // jalr.hb must be different.
1767 unsigned Opcode = Inst.getOpcode();
1769 if (Opcode == Mips::JALR_HB &&
1770 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1771 return Match_RequiresDifferentSrcAndDst;
1773 return Match_Success;
1776 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1777 OperandVector &Operands,
1779 uint64_t &ErrorInfo,
1780 bool MatchingInlineAsm) {
1783 SmallVector<MCInst, 8> Instructions;
1784 unsigned MatchResult =
1785 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1787 switch (MatchResult) {
1790 case Match_Success: {
1791 if (processInstruction(Inst, IDLoc, Instructions))
1793 for (unsigned i = 0; i < Instructions.size(); i++)
1794 Out.EmitInstruction(Instructions[i], STI);
1797 case Match_MissingFeature:
1798 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1800 case Match_InvalidOperand: {
1801 SMLoc ErrorLoc = IDLoc;
1802 if (ErrorInfo != ~0ULL) {
1803 if (ErrorInfo >= Operands.size())
1804 return Error(IDLoc, "too few operands for instruction");
1806 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1807 if (ErrorLoc == SMLoc())
1811 return Error(ErrorLoc, "invalid operand for instruction");
1813 case Match_MnemonicFail:
1814 return Error(IDLoc, "invalid instruction");
1815 case Match_RequiresDifferentSrcAndDst:
1816 return Error(IDLoc, "source and destination must be different");
1821 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1822 if ((RegIndex != 0) &&
1823 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1825 Warning(Loc, "used $at without \".set noat\"");
1827 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1828 Twine(RegIndex) + "\"");
1833 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1834 SMRange Range, bool ShowColors) {
1835 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1836 Range, SMFixIt(Range, FixMsg),
1840 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1843 CC = StringSwitch<unsigned>(Name)
1879 if (!(isABI_N32() || isABI_N64()))
1882 if (12 <= CC && CC <= 15) {
1883 // Name is one of t4-t7
1884 AsmToken RegTok = getLexer().peekTok();
1885 SMRange RegRange = RegTok.getLocRange();
1887 StringRef FixedName = StringSwitch<StringRef>(Name)
1893 assert(FixedName != "" && "Register name is not one of t4-t7.");
1895 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1896 "Did you mean $" + FixedName + "?", RegRange);
1899 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1900 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1901 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1902 if (8 <= CC && CC <= 11)
1906 CC = StringSwitch<unsigned>(Name)
1918 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
1921 CC = StringSwitch<unsigned>(Name)
1922 .Case("hwr_cpunum", 0)
1923 .Case("hwr_synci_step", 1)
1925 .Case("hwr_ccres", 3)
1926 .Case("hwr_ulr", 29)
1932 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1934 if (Name[0] == 'f') {
1935 StringRef NumString = Name.substr(1);
1937 if (NumString.getAsInteger(10, IntVal))
1938 return -1; // This is not an integer.
1939 if (IntVal > 31) // Maximum index for fpu register.
1946 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1948 if (Name.startswith("fcc")) {
1949 StringRef NumString = Name.substr(3);
1951 if (NumString.getAsInteger(10, IntVal))
1952 return -1; // This is not an integer.
1953 if (IntVal > 7) // There are only 8 fcc registers.
1960 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1962 if (Name.startswith("ac")) {
1963 StringRef NumString = Name.substr(2);
1965 if (NumString.getAsInteger(10, IntVal))
1966 return -1; // This is not an integer.
1967 if (IntVal > 3) // There are only 3 acc registers.
1974 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1977 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1986 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1989 CC = StringSwitch<unsigned>(Name)
1992 .Case("msaaccess", 2)
1994 .Case("msamodify", 4)
1995 .Case("msarequest", 5)
1997 .Case("msaunmap", 7)
2003 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2011 int MipsAsmParser::getATReg(SMLoc Loc) {
2012 int AT = AssemblerOptions.back()->getATRegNum();
2014 reportParseError(Loc,
2015 "pseudo-instruction requires $at, which is not available");
2019 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2020 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2023 unsigned MipsAsmParser::getGPR(int RegNo) {
2024 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2028 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2030 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2033 return getReg(RegClass, RegNum);
2036 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2037 MCAsmParser &Parser = getParser();
2038 DEBUG(dbgs() << "parseOperand\n");
2040 // Check if the current operand has a custom associated parser, if so, try to
2041 // custom parse the operand, or fallback to the general approach.
2042 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2043 if (ResTy == MatchOperand_Success)
2045 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2046 // there was a match, but an error occurred, in which case, just return that
2047 // the operand parsing failed.
2048 if (ResTy == MatchOperand_ParseFail)
2051 DEBUG(dbgs() << ".. Generic Parser\n");
2053 switch (getLexer().getKind()) {
2055 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2057 case AsmToken::Dollar: {
2058 // Parse the register.
2059 SMLoc S = Parser.getTok().getLoc();
2061 // Almost all registers have been parsed by custom parsers. There is only
2062 // one exception to this. $zero (and it's alias $0) will reach this point
2063 // for div, divu, and similar instructions because it is not an operand
2064 // to the instruction definition but an explicit register. Special case
2065 // this situation for now.
2066 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2069 // Maybe it is a symbol reference.
2070 StringRef Identifier;
2071 if (Parser.parseIdentifier(Identifier))
2074 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2075 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2076 // Otherwise create a symbol reference.
2078 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2080 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2083 // Else drop to expression parsing.
2084 case AsmToken::LParen:
2085 case AsmToken::Minus:
2086 case AsmToken::Plus:
2087 case AsmToken::Integer:
2088 case AsmToken::Tilde:
2089 case AsmToken::String: {
2090 DEBUG(dbgs() << ".. generic integer\n");
2091 OperandMatchResultTy ResTy = parseImm(Operands);
2092 return ResTy != MatchOperand_Success;
2094 case AsmToken::Percent: {
2095 // It is a symbol reference or constant expression.
2096 const MCExpr *IdVal;
2097 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2098 if (parseRelocOperand(IdVal))
2101 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2103 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2105 } // case AsmToken::Percent
2106 } // switch(getLexer().getKind())
2110 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2111 StringRef RelocStr) {
2113 // Check the type of the expression.
2114 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2115 // It's a constant, evaluate reloc value.
2117 switch (getVariantKind(RelocStr)) {
2118 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2119 // Get the 1st 16-bits.
2120 Val = MCE->getValue() & 0xffff;
2122 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2123 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2124 // 16 bits being negative.
2125 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2127 case MCSymbolRefExpr::VK_Mips_HIGHER:
2128 // Get the 3rd 16-bits.
2129 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2131 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2132 // Get the 4th 16-bits.
2133 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2136 report_fatal_error("unsupported reloc value");
2138 return MCConstantExpr::Create(Val, getContext());
2141 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2142 // It's a symbol, create a symbolic expression from the symbol.
2143 StringRef Symbol = MSRE->getSymbol().getName();
2144 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2145 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2149 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2150 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2152 // Try to create target expression.
2153 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2154 return MipsMCExpr::Create(VK, Expr, getContext());
2156 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2157 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2158 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2162 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2163 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2164 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2167 // Just return the original expression.
2171 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2173 switch (Expr->getKind()) {
2174 case MCExpr::Constant:
2176 case MCExpr::SymbolRef:
2177 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2178 case MCExpr::Binary:
2179 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2180 if (!isEvaluated(BE->getLHS()))
2182 return isEvaluated(BE->getRHS());
2185 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2186 case MCExpr::Target:
2192 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2193 MCAsmParser &Parser = getParser();
2194 Parser.Lex(); // Eat the % token.
2195 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2196 if (Tok.isNot(AsmToken::Identifier))
2199 std::string Str = Tok.getIdentifier().str();
2201 Parser.Lex(); // Eat the identifier.
2202 // Now make an expression from the rest of the operand.
2203 const MCExpr *IdVal;
2206 if (getLexer().getKind() == AsmToken::LParen) {
2208 Parser.Lex(); // Eat the '(' token.
2209 if (getLexer().getKind() == AsmToken::Percent) {
2210 Parser.Lex(); // Eat the % token.
2211 const AsmToken &nextTok = Parser.getTok();
2212 if (nextTok.isNot(AsmToken::Identifier))
2215 Str += nextTok.getIdentifier();
2216 Parser.Lex(); // Eat the identifier.
2217 if (getLexer().getKind() != AsmToken::LParen)
2222 if (getParser().parseParenExpression(IdVal, EndLoc))
2225 while (getLexer().getKind() == AsmToken::RParen)
2226 Parser.Lex(); // Eat the ')' token.
2229 return true; // Parenthesis must follow the relocation operand.
2231 Res = evaluateRelocExpr(IdVal, Str);
2235 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2237 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2238 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2239 if (ResTy == MatchOperand_Success) {
2240 assert(Operands.size() == 1);
2241 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2242 StartLoc = Operand.getStartLoc();
2243 EndLoc = Operand.getEndLoc();
2245 // AFAIK, we only support numeric registers and named GPR's in CFI
2247 // Don't worry about eating tokens before failing. Using an unrecognised
2248 // register is a parse error.
2249 if (Operand.isGPRAsmReg()) {
2250 // Resolve to GPR32 or GPR64 appropriately.
2251 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2254 return (RegNo == (unsigned)-1);
2257 assert(Operands.size() == 0);
2258 return (RegNo == (unsigned)-1);
2261 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2262 MCAsmParser &Parser = getParser();
2266 while (getLexer().getKind() == AsmToken::LParen)
2269 switch (getLexer().getKind()) {
2272 case AsmToken::Identifier:
2273 case AsmToken::LParen:
2274 case AsmToken::Integer:
2275 case AsmToken::Minus:
2276 case AsmToken::Plus:
2278 Result = getParser().parseParenExpression(Res, S);
2280 Result = (getParser().parseExpression(Res));
2281 while (getLexer().getKind() == AsmToken::RParen)
2284 case AsmToken::Percent:
2285 Result = parseRelocOperand(Res);
2290 MipsAsmParser::OperandMatchResultTy
2291 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2292 MCAsmParser &Parser = getParser();
2293 DEBUG(dbgs() << "parseMemOperand\n");
2294 const MCExpr *IdVal = nullptr;
2296 bool isParenExpr = false;
2297 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2298 // First operand is the offset.
2299 S = Parser.getTok().getLoc();
2301 if (getLexer().getKind() == AsmToken::LParen) {
2306 if (getLexer().getKind() != AsmToken::Dollar) {
2307 if (parseMemOffset(IdVal, isParenExpr))
2308 return MatchOperand_ParseFail;
2310 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2311 if (Tok.isNot(AsmToken::LParen)) {
2312 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2313 if (Mnemonic.getToken() == "la") {
2315 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2316 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2317 return MatchOperand_Success;
2319 if (Tok.is(AsmToken::EndOfStatement)) {
2321 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2323 // Zero register assumed, add a memory operand with ZERO as its base.
2324 // "Base" will be managed by k_Memory.
2325 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2328 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2329 return MatchOperand_Success;
2331 Error(Parser.getTok().getLoc(), "'(' expected");
2332 return MatchOperand_ParseFail;
2335 Parser.Lex(); // Eat the '(' token.
2338 Res = parseAnyRegister(Operands);
2339 if (Res != MatchOperand_Success)
2342 if (Parser.getTok().isNot(AsmToken::RParen)) {
2343 Error(Parser.getTok().getLoc(), "')' expected");
2344 return MatchOperand_ParseFail;
2347 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2349 Parser.Lex(); // Eat the ')' token.
2352 IdVal = MCConstantExpr::Create(0, getContext());
2354 // Replace the register operand with the memory operand.
2355 std::unique_ptr<MipsOperand> op(
2356 static_cast<MipsOperand *>(Operands.back().release()));
2357 // Remove the register from the operands.
2358 // "op" will be managed by k_Memory.
2359 Operands.pop_back();
2360 // Add the memory operand.
2361 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2363 if (IdVal->EvaluateAsAbsolute(Imm))
2364 IdVal = MCConstantExpr::Create(Imm, getContext());
2365 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2366 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2370 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2371 return MatchOperand_Success;
2374 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2375 MCAsmParser &Parser = getParser();
2376 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2378 SMLoc S = Parser.getTok().getLoc();
2380 if (Sym->isVariable())
2381 Expr = Sym->getVariableValue();
2384 if (Expr->getKind() == MCExpr::SymbolRef) {
2385 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2386 StringRef DefSymbol = Ref->getSymbol().getName();
2387 if (DefSymbol.startswith("$")) {
2388 OperandMatchResultTy ResTy =
2389 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2390 if (ResTy == MatchOperand_Success) {
2393 } else if (ResTy == MatchOperand_ParseFail)
2394 llvm_unreachable("Should never ParseFail");
2397 } else if (Expr->getKind() == MCExpr::Constant) {
2399 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2401 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2408 MipsAsmParser::OperandMatchResultTy
2409 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2410 StringRef Identifier,
2412 int Index = matchCPURegisterName(Identifier);
2414 Operands.push_back(MipsOperand::createGPRReg(
2415 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2416 return MatchOperand_Success;
2419 Index = matchHWRegsRegisterName(Identifier);
2421 Operands.push_back(MipsOperand::createHWRegsReg(
2422 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2423 return MatchOperand_Success;
2426 Index = matchFPURegisterName(Identifier);
2428 Operands.push_back(MipsOperand::createFGRReg(
2429 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2430 return MatchOperand_Success;
2433 Index = matchFCCRegisterName(Identifier);
2435 Operands.push_back(MipsOperand::createFCCReg(
2436 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2437 return MatchOperand_Success;
2440 Index = matchACRegisterName(Identifier);
2442 Operands.push_back(MipsOperand::createACCReg(
2443 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2444 return MatchOperand_Success;
2447 Index = matchMSA128RegisterName(Identifier);
2449 Operands.push_back(MipsOperand::createMSA128Reg(
2450 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2451 return MatchOperand_Success;
2454 Index = matchMSA128CtrlRegisterName(Identifier);
2456 Operands.push_back(MipsOperand::createMSACtrlReg(
2457 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2458 return MatchOperand_Success;
2461 return MatchOperand_NoMatch;
2464 MipsAsmParser::OperandMatchResultTy
2465 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2466 MCAsmParser &Parser = getParser();
2467 auto Token = Parser.getLexer().peekTok(false);
2469 if (Token.is(AsmToken::Identifier)) {
2470 DEBUG(dbgs() << ".. identifier\n");
2471 StringRef Identifier = Token.getIdentifier();
2472 OperandMatchResultTy ResTy =
2473 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2475 } else if (Token.is(AsmToken::Integer)) {
2476 DEBUG(dbgs() << ".. integer\n");
2477 Operands.push_back(MipsOperand::createNumericReg(
2478 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2480 return MatchOperand_Success;
2483 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2485 return MatchOperand_NoMatch;
2488 MipsAsmParser::OperandMatchResultTy
2489 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2490 MCAsmParser &Parser = getParser();
2491 DEBUG(dbgs() << "parseAnyRegister\n");
2493 auto Token = Parser.getTok();
2495 SMLoc S = Token.getLoc();
2497 if (Token.isNot(AsmToken::Dollar)) {
2498 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2499 if (Token.is(AsmToken::Identifier)) {
2500 if (searchSymbolAlias(Operands))
2501 return MatchOperand_Success;
2503 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2504 return MatchOperand_NoMatch;
2506 DEBUG(dbgs() << ".. $\n");
2508 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2509 if (ResTy == MatchOperand_Success) {
2511 Parser.Lex(); // identifier
2516 MipsAsmParser::OperandMatchResultTy
2517 MipsAsmParser::parseImm(OperandVector &Operands) {
2518 MCAsmParser &Parser = getParser();
2519 switch (getLexer().getKind()) {
2521 return MatchOperand_NoMatch;
2522 case AsmToken::LParen:
2523 case AsmToken::Minus:
2524 case AsmToken::Plus:
2525 case AsmToken::Integer:
2526 case AsmToken::Tilde:
2527 case AsmToken::String:
2531 const MCExpr *IdVal;
2532 SMLoc S = Parser.getTok().getLoc();
2533 if (getParser().parseExpression(IdVal))
2534 return MatchOperand_ParseFail;
2536 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2537 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2538 return MatchOperand_Success;
2541 MipsAsmParser::OperandMatchResultTy
2542 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2543 MCAsmParser &Parser = getParser();
2544 DEBUG(dbgs() << "parseJumpTarget\n");
2546 SMLoc S = getLexer().getLoc();
2548 // Integers and expressions are acceptable
2549 OperandMatchResultTy ResTy = parseImm(Operands);
2550 if (ResTy != MatchOperand_NoMatch)
2553 // Registers are a valid target and have priority over symbols.
2554 ResTy = parseAnyRegister(Operands);
2555 if (ResTy != MatchOperand_NoMatch)
2558 const MCExpr *Expr = nullptr;
2559 if (Parser.parseExpression(Expr)) {
2560 // We have no way of knowing if a symbol was consumed so we must ParseFail
2561 return MatchOperand_ParseFail;
2564 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2565 return MatchOperand_Success;
2568 MipsAsmParser::OperandMatchResultTy
2569 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2570 MCAsmParser &Parser = getParser();
2571 const MCExpr *IdVal;
2572 // If the first token is '$' we may have register operand.
2573 if (Parser.getTok().is(AsmToken::Dollar))
2574 return MatchOperand_NoMatch;
2575 SMLoc S = Parser.getTok().getLoc();
2576 if (getParser().parseExpression(IdVal))
2577 return MatchOperand_ParseFail;
2578 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2579 assert(MCE && "Unexpected MCExpr type.");
2580 int64_t Val = MCE->getValue();
2581 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2582 Operands.push_back(MipsOperand::CreateImm(
2583 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2584 return MatchOperand_Success;
2587 MipsAsmParser::OperandMatchResultTy
2588 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2589 MCAsmParser &Parser = getParser();
2590 switch (getLexer().getKind()) {
2592 return MatchOperand_NoMatch;
2593 case AsmToken::LParen:
2594 case AsmToken::Plus:
2595 case AsmToken::Minus:
2596 case AsmToken::Integer:
2601 SMLoc S = Parser.getTok().getLoc();
2603 if (getParser().parseExpression(Expr))
2604 return MatchOperand_ParseFail;
2607 if (!Expr->EvaluateAsAbsolute(Val)) {
2608 Error(S, "expected immediate value");
2609 return MatchOperand_ParseFail;
2612 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2613 // and because the CPU always adds one to the immediate field, the allowed
2614 // range becomes 1..4. We'll only check the range here and will deal
2615 // with the addition/subtraction when actually decoding/encoding
2617 if (Val < 1 || Val > 4) {
2618 Error(S, "immediate not in range (1..4)");
2619 return MatchOperand_ParseFail;
2623 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2624 return MatchOperand_Success;
2627 MipsAsmParser::OperandMatchResultTy
2628 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2629 MCAsmParser &Parser = getParser();
2630 SmallVector<unsigned, 10> Regs;
2632 unsigned PrevReg = Mips::NoRegister;
2633 bool RegRange = false;
2634 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2636 if (Parser.getTok().isNot(AsmToken::Dollar))
2637 return MatchOperand_ParseFail;
2639 SMLoc S = Parser.getTok().getLoc();
2640 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2641 SMLoc E = getLexer().getLoc();
2642 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2643 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2645 // Remove last register operand because registers from register range
2646 // should be inserted first.
2647 if (RegNo == Mips::RA) {
2648 Regs.push_back(RegNo);
2650 unsigned TmpReg = PrevReg + 1;
2651 while (TmpReg <= RegNo) {
2652 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2653 Error(E, "invalid register operand");
2654 return MatchOperand_ParseFail;
2658 Regs.push_back(TmpReg++);
2664 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2665 (RegNo != Mips::RA)) {
2666 Error(E, "$16 or $31 expected");
2667 return MatchOperand_ParseFail;
2668 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2669 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2670 Error(E, "invalid register operand");
2671 return MatchOperand_ParseFail;
2672 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2673 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2674 Error(E, "consecutive register numbers expected");
2675 return MatchOperand_ParseFail;
2678 Regs.push_back(RegNo);
2681 if (Parser.getTok().is(AsmToken::Minus))
2684 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2685 !Parser.getTok().isNot(AsmToken::Comma)) {
2686 Error(E, "',' or '-' expected");
2687 return MatchOperand_ParseFail;
2690 Lex(); // Consume comma or minus
2691 if (Parser.getTok().isNot(AsmToken::Dollar))
2697 SMLoc E = Parser.getTok().getLoc();
2698 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2699 parseMemOperand(Operands);
2700 return MatchOperand_Success;
2703 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2705 MCSymbolRefExpr::VariantKind VK =
2706 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2707 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2708 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2709 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2710 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2711 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2712 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2713 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2714 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2715 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2716 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2717 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2718 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2719 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2720 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2721 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2722 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2723 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2724 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2725 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2726 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2727 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2728 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2729 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2730 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2731 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2732 .Default(MCSymbolRefExpr::VK_None);
2734 assert(VK != MCSymbolRefExpr::VK_None);
2739 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2741 /// ::= '(', register, ')'
2742 /// handle it before we iterate so we don't get tripped up by the lack of
2744 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2745 MCAsmParser &Parser = getParser();
2746 if (getLexer().is(AsmToken::LParen)) {
2748 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2750 if (parseOperand(Operands, Name)) {
2751 SMLoc Loc = getLexer().getLoc();
2752 Parser.eatToEndOfStatement();
2753 return Error(Loc, "unexpected token in argument list");
2755 if (Parser.getTok().isNot(AsmToken::RParen)) {
2756 SMLoc Loc = getLexer().getLoc();
2757 Parser.eatToEndOfStatement();
2758 return Error(Loc, "unexpected token, expected ')'");
2761 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2767 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2768 /// either one of these.
2769 /// ::= '[', register, ']'
2770 /// ::= '[', integer, ']'
2771 /// handle it before we iterate so we don't get tripped up by the lack of
2773 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2774 OperandVector &Operands) {
2775 MCAsmParser &Parser = getParser();
2776 if (getLexer().is(AsmToken::LBrac)) {
2778 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2780 if (parseOperand(Operands, Name)) {
2781 SMLoc Loc = getLexer().getLoc();
2782 Parser.eatToEndOfStatement();
2783 return Error(Loc, "unexpected token in argument list");
2785 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2786 SMLoc Loc = getLexer().getLoc();
2787 Parser.eatToEndOfStatement();
2788 return Error(Loc, "unexpected token, expected ']'");
2791 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2797 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2798 SMLoc NameLoc, OperandVector &Operands) {
2799 MCAsmParser &Parser = getParser();
2800 DEBUG(dbgs() << "ParseInstruction\n");
2802 // We have reached first instruction, module directive are now forbidden.
2803 getTargetStreamer().forbidModuleDirective();
2805 // Check if we have valid mnemonic
2806 if (!mnemonicIsValid(Name, 0)) {
2807 Parser.eatToEndOfStatement();
2808 return Error(NameLoc, "unknown instruction");
2810 // First operand in MCInst is instruction mnemonic.
2811 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2813 // Read the remaining operands.
2814 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2815 // Read the first operand.
2816 if (parseOperand(Operands, Name)) {
2817 SMLoc Loc = getLexer().getLoc();
2818 Parser.eatToEndOfStatement();
2819 return Error(Loc, "unexpected token in argument list");
2821 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2823 // AFAIK, parenthesis suffixes are never on the first operand
2825 while (getLexer().is(AsmToken::Comma)) {
2826 Parser.Lex(); // Eat the comma.
2827 // Parse and remember the operand.
2828 if (parseOperand(Operands, Name)) {
2829 SMLoc Loc = getLexer().getLoc();
2830 Parser.eatToEndOfStatement();
2831 return Error(Loc, "unexpected token in argument list");
2833 // Parse bracket and parenthesis suffixes before we iterate
2834 if (getLexer().is(AsmToken::LBrac)) {
2835 if (parseBracketSuffix(Name, Operands))
2837 } else if (getLexer().is(AsmToken::LParen) &&
2838 parseParenSuffix(Name, Operands))
2842 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2843 SMLoc Loc = getLexer().getLoc();
2844 Parser.eatToEndOfStatement();
2845 return Error(Loc, "unexpected token in argument list");
2847 Parser.Lex(); // Consume the EndOfStatement.
2851 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2852 MCAsmParser &Parser = getParser();
2853 SMLoc Loc = getLexer().getLoc();
2854 Parser.eatToEndOfStatement();
2855 return Error(Loc, ErrorMsg);
2858 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2859 return Error(Loc, ErrorMsg);
2862 bool MipsAsmParser::parseSetNoAtDirective() {
2863 MCAsmParser &Parser = getParser();
2864 // Line should look like: ".set noat".
2866 AssemblerOptions.back()->setATReg(0);
2869 // If this is not the end of the statement, report an error.
2870 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2871 reportParseError("unexpected token, expected end of statement");
2874 Parser.Lex(); // Consume the EndOfStatement.
2878 bool MipsAsmParser::parseSetAtDirective() {
2879 MCAsmParser &Parser = getParser();
2880 // Line can be .set at - defaults to $1
2884 if (getLexer().is(AsmToken::EndOfStatement)) {
2885 AssemblerOptions.back()->setATReg(1);
2886 Parser.Lex(); // Consume the EndOfStatement.
2888 } else if (getLexer().is(AsmToken::Equal)) {
2889 getParser().Lex(); // Eat the '='.
2890 if (getLexer().isNot(AsmToken::Dollar)) {
2891 reportParseError("unexpected token, expected dollar sign '$'");
2894 Parser.Lex(); // Eat the '$'.
2895 const AsmToken &Reg = Parser.getTok();
2896 if (Reg.is(AsmToken::Identifier)) {
2897 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2898 } else if (Reg.is(AsmToken::Integer)) {
2899 AtRegNo = Reg.getIntVal();
2901 reportParseError("unexpected token, expected identifier or integer");
2905 if (AtRegNo < 0 || AtRegNo > 31) {
2906 reportParseError("unexpected token in statement");
2910 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2911 reportParseError("invalid register");
2914 getParser().Lex(); // Eat the register.
2916 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2917 reportParseError("unexpected token, expected end of statement");
2920 Parser.Lex(); // Consume the EndOfStatement.
2923 reportParseError("unexpected token in statement");
2928 bool MipsAsmParser::parseSetReorderDirective() {
2929 MCAsmParser &Parser = getParser();
2931 // If this is not the end of the statement, report an error.
2932 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2933 reportParseError("unexpected token, expected end of statement");
2936 AssemblerOptions.back()->setReorder();
2937 getTargetStreamer().emitDirectiveSetReorder();
2938 Parser.Lex(); // Consume the EndOfStatement.
2942 bool MipsAsmParser::parseSetNoReorderDirective() {
2943 MCAsmParser &Parser = getParser();
2945 // If this is not the end of the statement, report an error.
2946 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2947 reportParseError("unexpected token, expected end of statement");
2950 AssemblerOptions.back()->setNoReorder();
2951 getTargetStreamer().emitDirectiveSetNoReorder();
2952 Parser.Lex(); // Consume the EndOfStatement.
2956 bool MipsAsmParser::parseSetMacroDirective() {
2957 MCAsmParser &Parser = getParser();
2959 // If this is not the end of the statement, report an error.
2960 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2961 reportParseError("unexpected token, expected end of statement");
2964 AssemblerOptions.back()->setMacro();
2965 Parser.Lex(); // Consume the EndOfStatement.
2969 bool MipsAsmParser::parseSetNoMacroDirective() {
2970 MCAsmParser &Parser = getParser();
2972 // If this is not the end of the statement, report an error.
2973 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2974 reportParseError("unexpected token, expected end of statement");
2977 if (AssemblerOptions.back()->isReorder()) {
2978 reportParseError("`noreorder' must be set before `nomacro'");
2981 AssemblerOptions.back()->setNoMacro();
2982 Parser.Lex(); // Consume the EndOfStatement.
2986 bool MipsAsmParser::parseSetMsaDirective() {
2987 MCAsmParser &Parser = getParser();
2990 // If this is not the end of the statement, report an error.
2991 if (getLexer().isNot(AsmToken::EndOfStatement))
2992 return reportParseError("unexpected token, expected end of statement");
2994 setFeatureBits(Mips::FeatureMSA, "msa");
2995 getTargetStreamer().emitDirectiveSetMsa();
2999 bool MipsAsmParser::parseSetNoMsaDirective() {
3000 MCAsmParser &Parser = getParser();
3003 // If this is not the end of the statement, report an error.
3004 if (getLexer().isNot(AsmToken::EndOfStatement))
3005 return reportParseError("unexpected token, expected end of statement");
3007 clearFeatureBits(Mips::FeatureMSA, "msa");
3008 getTargetStreamer().emitDirectiveSetNoMsa();
3012 bool MipsAsmParser::parseSetNoDspDirective() {
3013 MCAsmParser &Parser = getParser();
3014 Parser.Lex(); // Eat "nodsp".
3016 // If this is not the end of the statement, report an error.
3017 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3018 reportParseError("unexpected token, expected end of statement");
3022 clearFeatureBits(Mips::FeatureDSP, "dsp");
3023 getTargetStreamer().emitDirectiveSetNoDsp();
3027 bool MipsAsmParser::parseSetMips16Directive() {
3028 MCAsmParser &Parser = getParser();
3029 Parser.Lex(); // Eat "mips16".
3031 // If this is not the end of the statement, report an error.
3032 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3033 reportParseError("unexpected token, expected end of statement");
3037 setFeatureBits(Mips::FeatureMips16, "mips16");
3038 getTargetStreamer().emitDirectiveSetMips16();
3039 Parser.Lex(); // Consume the EndOfStatement.
3043 bool MipsAsmParser::parseSetNoMips16Directive() {
3044 MCAsmParser &Parser = getParser();
3045 Parser.Lex(); // Eat "nomips16".
3047 // If this is not the end of the statement, report an error.
3048 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3049 reportParseError("unexpected token, expected end of statement");
3053 clearFeatureBits(Mips::FeatureMips16, "mips16");
3054 getTargetStreamer().emitDirectiveSetNoMips16();
3055 Parser.Lex(); // Consume the EndOfStatement.
3059 bool MipsAsmParser::parseSetFpDirective() {
3060 MCAsmParser &Parser = getParser();
3061 MipsABIFlagsSection::FpABIKind FpAbiVal;
3062 // Line can be: .set fp=32
3065 Parser.Lex(); // Eat fp token
3066 AsmToken Tok = Parser.getTok();
3067 if (Tok.isNot(AsmToken::Equal)) {
3068 reportParseError("unexpected token, expected equals sign '='");
3071 Parser.Lex(); // Eat '=' token.
3072 Tok = Parser.getTok();
3074 if (!parseFpABIValue(FpAbiVal, ".set"))
3077 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3078 reportParseError("unexpected token, expected end of statement");
3081 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3082 Parser.Lex(); // Consume the EndOfStatement.
3086 bool MipsAsmParser::parseSetPopDirective() {
3087 MCAsmParser &Parser = getParser();
3088 SMLoc Loc = getLexer().getLoc();
3091 if (getLexer().isNot(AsmToken::EndOfStatement))
3092 return reportParseError("unexpected token, expected end of statement");
3094 // Always keep an element on the options "stack" to prevent the user
3095 // from changing the initial options. This is how we remember them.
3096 if (AssemblerOptions.size() == 2)
3097 return reportParseError(Loc, ".set pop with no .set push");
3099 AssemblerOptions.pop_back();
3100 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3102 getTargetStreamer().emitDirectiveSetPop();
3106 bool MipsAsmParser::parseSetPushDirective() {
3107 MCAsmParser &Parser = getParser();
3109 if (getLexer().isNot(AsmToken::EndOfStatement))
3110 return reportParseError("unexpected token, expected end of statement");
3112 // Create a copy of the current assembler options environment and push it.
3113 AssemblerOptions.push_back(
3114 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3116 getTargetStreamer().emitDirectiveSetPush();
3120 bool MipsAsmParser::parseSetAssignment() {
3122 const MCExpr *Value;
3123 MCAsmParser &Parser = getParser();
3125 if (Parser.parseIdentifier(Name))
3126 reportParseError("expected identifier after .set");
3128 if (getLexer().isNot(AsmToken::Comma))
3129 return reportParseError("unexpected token, expected comma");
3132 if (Parser.parseExpression(Value))
3133 return reportParseError("expected valid expression after comma");
3135 // Check if the Name already exists as a symbol.
3136 MCSymbol *Sym = getContext().LookupSymbol(Name);
3138 return reportParseError("symbol already defined");
3139 Sym = getContext().GetOrCreateSymbol(Name);
3140 Sym->setVariableValue(Value);
3145 bool MipsAsmParser::parseSetMips0Directive() {
3146 MCAsmParser &Parser = getParser();
3148 if (getLexer().isNot(AsmToken::EndOfStatement))
3149 return reportParseError("unexpected token, expected end of statement");
3151 // Reset assembler options to their initial values.
3152 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3153 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3155 getTargetStreamer().emitDirectiveSetMips0();
3159 bool MipsAsmParser::parseSetArchDirective() {
3160 MCAsmParser &Parser = getParser();
3162 if (getLexer().isNot(AsmToken::Equal))
3163 return reportParseError("unexpected token, expected equals sign");
3167 if (Parser.parseIdentifier(Arch))
3168 return reportParseError("expected arch identifier");
3170 StringRef ArchFeatureName =
3171 StringSwitch<StringRef>(Arch)
3172 .Case("mips1", "mips1")
3173 .Case("mips2", "mips2")
3174 .Case("mips3", "mips3")
3175 .Case("mips4", "mips4")
3176 .Case("mips5", "mips5")
3177 .Case("mips32", "mips32")
3178 .Case("mips32r2", "mips32r2")
3179 .Case("mips32r6", "mips32r6")
3180 .Case("mips64", "mips64")
3181 .Case("mips64r2", "mips64r2")
3182 .Case("mips64r6", "mips64r6")
3183 .Case("cnmips", "cnmips")
3184 .Case("r4000", "mips3") // This is an implementation of Mips3.
3187 if (ArchFeatureName.empty())
3188 return reportParseError("unsupported architecture");
3190 selectArch(ArchFeatureName);
3191 getTargetStreamer().emitDirectiveSetArch(Arch);
3195 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3196 MCAsmParser &Parser = getParser();
3198 if (getLexer().isNot(AsmToken::EndOfStatement))
3199 return reportParseError("unexpected token, expected end of statement");
3203 llvm_unreachable("Unimplemented feature");
3204 case Mips::FeatureDSP:
3205 setFeatureBits(Mips::FeatureDSP, "dsp");
3206 getTargetStreamer().emitDirectiveSetDsp();
3208 case Mips::FeatureMicroMips:
3209 getTargetStreamer().emitDirectiveSetMicroMips();
3211 case Mips::FeatureMips1:
3212 selectArch("mips1");
3213 getTargetStreamer().emitDirectiveSetMips1();
3215 case Mips::FeatureMips2:
3216 selectArch("mips2");
3217 getTargetStreamer().emitDirectiveSetMips2();
3219 case Mips::FeatureMips3:
3220 selectArch("mips3");
3221 getTargetStreamer().emitDirectiveSetMips3();
3223 case Mips::FeatureMips4:
3224 selectArch("mips4");
3225 getTargetStreamer().emitDirectiveSetMips4();
3227 case Mips::FeatureMips5:
3228 selectArch("mips5");
3229 getTargetStreamer().emitDirectiveSetMips5();
3231 case Mips::FeatureMips32:
3232 selectArch("mips32");
3233 getTargetStreamer().emitDirectiveSetMips32();
3235 case Mips::FeatureMips32r2:
3236 selectArch("mips32r2");
3237 getTargetStreamer().emitDirectiveSetMips32R2();
3239 case Mips::FeatureMips32r6:
3240 selectArch("mips32r6");
3241 getTargetStreamer().emitDirectiveSetMips32R6();
3243 case Mips::FeatureMips64:
3244 selectArch("mips64");
3245 getTargetStreamer().emitDirectiveSetMips64();
3247 case Mips::FeatureMips64r2:
3248 selectArch("mips64r2");
3249 getTargetStreamer().emitDirectiveSetMips64R2();
3251 case Mips::FeatureMips64r6:
3252 selectArch("mips64r6");
3253 getTargetStreamer().emitDirectiveSetMips64R6();
3259 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3260 MCAsmParser &Parser = getParser();
3261 if (getLexer().isNot(AsmToken::Comma)) {
3262 SMLoc Loc = getLexer().getLoc();
3263 Parser.eatToEndOfStatement();
3264 return Error(Loc, ErrorStr);
3267 Parser.Lex(); // Eat the comma.
3271 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3272 if (AssemblerOptions.back()->isReorder())
3273 Warning(Loc, ".cpload should be inside a noreorder section");
3275 if (inMips16Mode()) {
3276 reportParseError(".cpload is not supported in Mips16 mode");
3280 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3281 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3282 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3283 reportParseError("expected register containing function address");
3287 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3288 if (!RegOpnd.isGPRAsmReg()) {
3289 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3293 // If this is not the end of the statement, report an error.
3294 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3295 reportParseError("unexpected token, expected end of statement");
3299 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3303 bool MipsAsmParser::parseDirectiveCPSetup() {
3304 MCAsmParser &Parser = getParser();
3307 bool SaveIsReg = true;
3309 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3310 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3311 if (ResTy == MatchOperand_NoMatch) {
3312 reportParseError("expected register containing function address");
3313 Parser.eatToEndOfStatement();
3317 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3318 if (!FuncRegOpnd.isGPRAsmReg()) {
3319 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3320 Parser.eatToEndOfStatement();
3324 FuncReg = FuncRegOpnd.getGPR32Reg();
3327 if (!eatComma("unexpected token, expected comma"))
3330 ResTy = parseAnyRegister(TmpReg);
3331 if (ResTy == MatchOperand_NoMatch) {
3332 const AsmToken &Tok = Parser.getTok();
3333 if (Tok.is(AsmToken::Integer)) {
3334 Save = Tok.getIntVal();
3338 reportParseError("expected save register or stack offset");
3339 Parser.eatToEndOfStatement();
3343 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3344 if (!SaveOpnd.isGPRAsmReg()) {
3345 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3346 Parser.eatToEndOfStatement();
3349 Save = SaveOpnd.getGPR32Reg();
3352 if (!eatComma("unexpected token, expected comma"))
3356 if (Parser.parseIdentifier(Name))
3357 reportParseError("expected identifier");
3358 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3360 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3364 bool MipsAsmParser::parseDirectiveNaN() {
3365 MCAsmParser &Parser = getParser();
3366 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3367 const AsmToken &Tok = Parser.getTok();
3369 if (Tok.getString() == "2008") {
3371 getTargetStreamer().emitDirectiveNaN2008();
3373 } else if (Tok.getString() == "legacy") {
3375 getTargetStreamer().emitDirectiveNaNLegacy();
3379 // If we don't recognize the option passed to the .nan
3380 // directive (e.g. no option or unknown option), emit an error.
3381 reportParseError("invalid option in .nan directive");
3385 bool MipsAsmParser::parseDirectiveSet() {
3386 MCAsmParser &Parser = getParser();
3387 // Get the next token.
3388 const AsmToken &Tok = Parser.getTok();
3390 if (Tok.getString() == "noat") {
3391 return parseSetNoAtDirective();
3392 } else if (Tok.getString() == "at") {
3393 return parseSetAtDirective();
3394 } else if (Tok.getString() == "arch") {
3395 return parseSetArchDirective();
3396 } else if (Tok.getString() == "fp") {
3397 return parseSetFpDirective();
3398 } else if (Tok.getString() == "pop") {
3399 return parseSetPopDirective();
3400 } else if (Tok.getString() == "push") {
3401 return parseSetPushDirective();
3402 } else if (Tok.getString() == "reorder") {
3403 return parseSetReorderDirective();
3404 } else if (Tok.getString() == "noreorder") {
3405 return parseSetNoReorderDirective();
3406 } else if (Tok.getString() == "macro") {
3407 return parseSetMacroDirective();
3408 } else if (Tok.getString() == "nomacro") {
3409 return parseSetNoMacroDirective();
3410 } else if (Tok.getString() == "mips16") {
3411 return parseSetMips16Directive();
3412 } else if (Tok.getString() == "nomips16") {
3413 return parseSetNoMips16Directive();
3414 } else if (Tok.getString() == "nomicromips") {
3415 getTargetStreamer().emitDirectiveSetNoMicroMips();
3416 Parser.eatToEndOfStatement();
3418 } else if (Tok.getString() == "micromips") {
3419 return parseSetFeature(Mips::FeatureMicroMips);
3420 } else if (Tok.getString() == "mips0") {
3421 return parseSetMips0Directive();
3422 } else if (Tok.getString() == "mips1") {
3423 return parseSetFeature(Mips::FeatureMips1);
3424 } else if (Tok.getString() == "mips2") {
3425 return parseSetFeature(Mips::FeatureMips2);
3426 } else if (Tok.getString() == "mips3") {
3427 return parseSetFeature(Mips::FeatureMips3);
3428 } else if (Tok.getString() == "mips4") {
3429 return parseSetFeature(Mips::FeatureMips4);
3430 } else if (Tok.getString() == "mips5") {
3431 return parseSetFeature(Mips::FeatureMips5);
3432 } else if (Tok.getString() == "mips32") {
3433 return parseSetFeature(Mips::FeatureMips32);
3434 } else if (Tok.getString() == "mips32r2") {
3435 return parseSetFeature(Mips::FeatureMips32r2);
3436 } else if (Tok.getString() == "mips32r6") {
3437 return parseSetFeature(Mips::FeatureMips32r6);
3438 } else if (Tok.getString() == "mips64") {
3439 return parseSetFeature(Mips::FeatureMips64);
3440 } else if (Tok.getString() == "mips64r2") {
3441 return parseSetFeature(Mips::FeatureMips64r2);
3442 } else if (Tok.getString() == "mips64r6") {
3443 return parseSetFeature(Mips::FeatureMips64r6);
3444 } else if (Tok.getString() == "dsp") {
3445 return parseSetFeature(Mips::FeatureDSP);
3446 } else if (Tok.getString() == "nodsp") {
3447 return parseSetNoDspDirective();
3448 } else if (Tok.getString() == "msa") {
3449 return parseSetMsaDirective();
3450 } else if (Tok.getString() == "nomsa") {
3451 return parseSetNoMsaDirective();
3453 // It is just an identifier, look for an assignment.
3454 parseSetAssignment();
3461 /// parseDataDirective
3462 /// ::= .word [ expression (, expression)* ]
3463 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3464 MCAsmParser &Parser = getParser();
3465 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3467 const MCExpr *Value;
3468 if (getParser().parseExpression(Value))
3471 getParser().getStreamer().EmitValue(Value, Size);
3473 if (getLexer().is(AsmToken::EndOfStatement))
3476 if (getLexer().isNot(AsmToken::Comma))
3477 return Error(L, "unexpected token, expected comma");
3486 /// parseDirectiveGpWord
3487 /// ::= .gpword local_sym
3488 bool MipsAsmParser::parseDirectiveGpWord() {
3489 MCAsmParser &Parser = getParser();
3490 const MCExpr *Value;
3491 // EmitGPRel32Value requires an expression, so we are using base class
3492 // method to evaluate the expression.
3493 if (getParser().parseExpression(Value))
3495 getParser().getStreamer().EmitGPRel32Value(Value);
3497 if (getLexer().isNot(AsmToken::EndOfStatement))
3498 return Error(getLexer().getLoc(),
3499 "unexpected token, expected end of statement");
3500 Parser.Lex(); // Eat EndOfStatement token.
3504 /// parseDirectiveGpDWord
3505 /// ::= .gpdword local_sym
3506 bool MipsAsmParser::parseDirectiveGpDWord() {
3507 MCAsmParser &Parser = getParser();
3508 const MCExpr *Value;
3509 // EmitGPRel64Value requires an expression, so we are using base class
3510 // method to evaluate the expression.
3511 if (getParser().parseExpression(Value))
3513 getParser().getStreamer().EmitGPRel64Value(Value);
3515 if (getLexer().isNot(AsmToken::EndOfStatement))
3516 return Error(getLexer().getLoc(),
3517 "unexpected token, expected end of statement");
3518 Parser.Lex(); // Eat EndOfStatement token.
3522 bool MipsAsmParser::parseDirectiveOption() {
3523 MCAsmParser &Parser = getParser();
3524 // Get the option token.
3525 AsmToken Tok = Parser.getTok();
3526 // At the moment only identifiers are supported.
3527 if (Tok.isNot(AsmToken::Identifier)) {
3528 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3529 Parser.eatToEndOfStatement();
3533 StringRef Option = Tok.getIdentifier();
3535 if (Option == "pic0") {
3536 getTargetStreamer().emitDirectiveOptionPic0();
3538 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3539 Error(Parser.getTok().getLoc(),
3540 "unexpected token, expected end of statement");
3541 Parser.eatToEndOfStatement();
3546 if (Option == "pic2") {
3547 getTargetStreamer().emitDirectiveOptionPic2();
3549 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3550 Error(Parser.getTok().getLoc(),
3551 "unexpected token, expected end of statement");
3552 Parser.eatToEndOfStatement();
3558 Warning(Parser.getTok().getLoc(),
3559 "unknown option, expected 'pic0' or 'pic2'");
3560 Parser.eatToEndOfStatement();
3564 /// parseDirectiveModule
3565 /// ::= .module oddspreg
3566 /// ::= .module nooddspreg
3567 /// ::= .module fp=value
3568 bool MipsAsmParser::parseDirectiveModule() {
3569 MCAsmParser &Parser = getParser();
3570 MCAsmLexer &Lexer = getLexer();
3571 SMLoc L = Lexer.getLoc();
3573 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3574 // TODO : get a better message.
3575 reportParseError(".module directive must appear before any code");
3579 if (Lexer.is(AsmToken::Identifier)) {
3580 StringRef Option = Parser.getTok().getString();
3583 if (Option == "oddspreg") {
3584 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3585 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3587 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3588 reportParseError("unexpected token, expected end of statement");
3593 } else if (Option == "nooddspreg") {
3595 Error(L, "'.module nooddspreg' requires the O32 ABI");
3599 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3600 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3602 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3603 reportParseError("unexpected token, expected end of statement");
3608 } else if (Option == "fp") {
3609 return parseDirectiveModuleFP();
3612 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3618 /// parseDirectiveModuleFP
3622 bool MipsAsmParser::parseDirectiveModuleFP() {
3623 MCAsmParser &Parser = getParser();
3624 MCAsmLexer &Lexer = getLexer();
3626 if (Lexer.isNot(AsmToken::Equal)) {
3627 reportParseError("unexpected token, expected equals sign '='");
3630 Parser.Lex(); // Eat '=' token.
3632 MipsABIFlagsSection::FpABIKind FpABI;
3633 if (!parseFpABIValue(FpABI, ".module"))
3636 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3637 reportParseError("unexpected token, expected end of statement");
3641 // Emit appropriate flags.
3642 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3643 Parser.Lex(); // Consume the EndOfStatement.
3647 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3648 StringRef Directive) {
3649 MCAsmParser &Parser = getParser();
3650 MCAsmLexer &Lexer = getLexer();
3652 if (Lexer.is(AsmToken::Identifier)) {
3653 StringRef Value = Parser.getTok().getString();
3656 if (Value != "xx") {
3657 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3662 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3666 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3670 if (Lexer.is(AsmToken::Integer)) {
3671 unsigned Value = Parser.getTok().getIntVal();
3674 if (Value != 32 && Value != 64) {
3675 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3681 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3685 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3687 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3695 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3696 MCAsmParser &Parser = getParser();
3697 StringRef IDVal = DirectiveID.getString();
3699 if (IDVal == ".cpload")
3700 return parseDirectiveCpLoad(DirectiveID.getLoc());
3701 if (IDVal == ".dword") {
3702 parseDataDirective(8, DirectiveID.getLoc());
3705 if (IDVal == ".ent") {
3706 StringRef SymbolName;
3708 if (Parser.parseIdentifier(SymbolName)) {
3709 reportParseError("expected identifier after .ent");
3713 // There's an undocumented extension that allows an integer to
3714 // follow the name of the procedure which AFAICS is ignored by GAS.
3715 // Example: .ent foo,2
3716 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3717 if (getLexer().isNot(AsmToken::Comma)) {
3718 // Even though we accept this undocumented extension for compatibility
3719 // reasons, the additional integer argument does not actually change
3720 // the behaviour of the '.ent' directive, so we would like to discourage
3721 // its use. We do this by not referring to the extended version in
3722 // error messages which are not directly related to its use.
3723 reportParseError("unexpected token, expected end of statement");
3726 Parser.Lex(); // Eat the comma.
3727 const MCExpr *DummyNumber;
3728 int64_t DummyNumberVal;
3729 // If the user was explicitly trying to use the extended version,
3730 // we still give helpful extension-related error messages.
3731 if (Parser.parseExpression(DummyNumber)) {
3732 reportParseError("expected number after comma");
3735 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3736 reportParseError("expected an absolute expression after comma");
3741 // If this is not the end of the statement, report an error.
3742 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3743 reportParseError("unexpected token, expected end of statement");
3747 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3749 getTargetStreamer().emitDirectiveEnt(*Sym);
3754 if (IDVal == ".end") {
3755 StringRef SymbolName;
3757 if (Parser.parseIdentifier(SymbolName)) {
3758 reportParseError("expected identifier after .end");
3762 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3763 reportParseError("unexpected token, expected end of statement");
3767 if (CurrentFn == nullptr) {
3768 reportParseError(".end used without .ent");
3772 if ((SymbolName != CurrentFn->getName())) {
3773 reportParseError(".end symbol does not match .ent symbol");
3777 getTargetStreamer().emitDirectiveEnd(SymbolName);
3778 CurrentFn = nullptr;
3782 if (IDVal == ".frame") {
3783 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3784 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3785 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3786 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3787 reportParseError("expected stack register");
3791 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3792 if (!StackRegOpnd.isGPRAsmReg()) {
3793 reportParseError(StackRegOpnd.getStartLoc(),
3794 "expected general purpose register");
3797 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3799 if (Parser.getTok().is(AsmToken::Comma))
3802 reportParseError("unexpected token, expected comma");
3806 // Parse the frame size.
3807 const MCExpr *FrameSize;
3808 int64_t FrameSizeVal;
3810 if (Parser.parseExpression(FrameSize)) {
3811 reportParseError("expected frame size value");
3815 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3816 reportParseError("frame size not an absolute expression");
3820 if (Parser.getTok().is(AsmToken::Comma))
3823 reportParseError("unexpected token, expected comma");
3827 // Parse the return register.
3829 ResTy = parseAnyRegister(TmpReg);
3830 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3831 reportParseError("expected return register");
3835 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3836 if (!ReturnRegOpnd.isGPRAsmReg()) {
3837 reportParseError(ReturnRegOpnd.getStartLoc(),
3838 "expected general purpose register");
3842 // If this is not the end of the statement, report an error.
3843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3844 reportParseError("unexpected token, expected end of statement");
3848 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3849 ReturnRegOpnd.getGPR32Reg());
3853 if (IDVal == ".set") {
3854 return parseDirectiveSet();
3857 if (IDVal == ".mask" || IDVal == ".fmask") {
3858 // .mask bitmask, frame_offset
3859 // bitmask: One bit for each register used.
3860 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3861 // first register is expected to be saved.
3863 // .mask 0x80000000, -4
3864 // .fmask 0x80000000, -4
3867 // Parse the bitmask
3868 const MCExpr *BitMask;
3871 if (Parser.parseExpression(BitMask)) {
3872 reportParseError("expected bitmask value");
3876 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3877 reportParseError("bitmask not an absolute expression");
3881 if (Parser.getTok().is(AsmToken::Comma))
3884 reportParseError("unexpected token, expected comma");
3888 // Parse the frame_offset
3889 const MCExpr *FrameOffset;
3890 int64_t FrameOffsetVal;
3892 if (Parser.parseExpression(FrameOffset)) {
3893 reportParseError("expected frame offset value");
3897 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3898 reportParseError("frame offset not an absolute expression");
3902 // If this is not the end of the statement, report an error.
3903 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3904 reportParseError("unexpected token, expected end of statement");
3908 if (IDVal == ".mask")
3909 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3911 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3915 if (IDVal == ".nan")
3916 return parseDirectiveNaN();
3918 if (IDVal == ".gpword") {
3919 parseDirectiveGpWord();
3923 if (IDVal == ".gpdword") {
3924 parseDirectiveGpDWord();
3928 if (IDVal == ".word") {
3929 parseDataDirective(4, DirectiveID.getLoc());
3933 if (IDVal == ".option")
3934 return parseDirectiveOption();
3936 if (IDVal == ".abicalls") {
3937 getTargetStreamer().emitDirectiveAbiCalls();
3938 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3939 Error(Parser.getTok().getLoc(),
3940 "unexpected token, expected end of statement");
3942 Parser.eatToEndOfStatement();
3947 if (IDVal == ".cpsetup")
3948 return parseDirectiveCPSetup();
3950 if (IDVal == ".module")
3951 return parseDirectiveModule();
3956 extern "C" void LLVMInitializeMipsAsmParser() {
3957 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3958 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3959 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3960 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3963 #define GET_REGISTER_MATCHER
3964 #define GET_MATCHER_IMPLEMENTATION
3965 #include "MipsGenAsmMatcher.inc"