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/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstBuilder.h"
20 #include "llvm/MC/MCParser/MCAsmLexer.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCTargetAsmParser.h"
26 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/MathExtras.h"
28 #include "llvm/Support/TargetRegistry.h"
32 #define DEBUG_TYPE "mips-asm-parser"
39 class MipsAssemblerOptions {
41 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
43 unsigned getATRegNum() { return aTReg; }
44 bool setATReg(unsigned Reg);
46 bool isReorder() { return reorder; }
47 void setReorder() { reorder = true; }
48 void setNoreorder() { reorder = false; }
50 bool isMacro() { return macro; }
51 void setMacro() { macro = true; }
52 void setNomacro() { macro = false; }
54 // Set of features that are either architecture features or referenced
55 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
56 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
57 // The reason we need this mask is explained in the selectArch function.
58 // FIXME: Ideally we would like TableGen to generate this information.
59 static const uint64_t AllArchRelatedMask =
60 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
61 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
62 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
63 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
64 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
65 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
66 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
76 class MipsAsmParser : public MCTargetAsmParser {
77 MipsTargetStreamer &getTargetStreamer() {
78 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
79 return static_cast<MipsTargetStreamer &>(TS);
84 MipsAssemblerOptions Options;
85 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
86 // nullptr, which indicates that no function is currently
87 // selected. This usually happens after an '.end func'
90 #define GET_ASSEMBLER_HEADER
91 #include "MipsGenAsmMatcher.inc"
93 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
95 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
96 OperandVector &Operands, MCStreamer &Out,
98 bool MatchingInlineAsm) override;
100 /// Parse a register as used in CFI directives
101 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
103 bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
105 bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
107 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
108 SMLoc NameLoc, OperandVector &Operands) override;
110 bool ParseDirective(AsmToken DirectiveID) override;
112 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
114 MipsAsmParser::OperandMatchResultTy
115 MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
116 StringRef Identifier, SMLoc S);
118 MipsAsmParser::OperandMatchResultTy
119 MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
121 MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
123 MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
125 MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
127 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
129 MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
131 bool searchSymbolAlias(OperandVector &Operands);
133 bool ParseOperand(OperandVector &, StringRef Mnemonic);
135 bool needsExpansion(MCInst &Inst);
137 // Expands assembly pseudo instructions.
138 // Returns false on success, true otherwise.
139 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
140 SmallVectorImpl<MCInst> &Instructions);
142 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
143 SmallVectorImpl<MCInst> &Instructions);
145 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
146 SmallVectorImpl<MCInst> &Instructions);
148 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
149 SmallVectorImpl<MCInst> &Instructions);
151 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
152 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
154 bool reportParseError(Twine ErrorMsg);
155 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
157 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
158 bool parseRelocOperand(const MCExpr *&Res);
160 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
162 bool isEvaluated(const MCExpr *Expr);
163 bool parseSetFeature(uint64_t Feature);
164 bool parseDirectiveCPLoad(SMLoc Loc);
165 bool parseDirectiveCPSetup();
166 bool parseDirectiveNaN();
167 bool parseDirectiveSet();
168 bool parseDirectiveOption();
170 bool parseSetAtDirective();
171 bool parseSetNoAtDirective();
172 bool parseSetMacroDirective();
173 bool parseSetNoMacroDirective();
174 bool parseSetMsaDirective();
175 bool parseSetNoMsaDirective();
176 bool parseSetReorderDirective();
177 bool parseSetNoReorderDirective();
178 bool parseSetNoMips16Directive();
179 bool parseSetFpDirective();
181 bool parseSetAssignment();
183 bool parseDataDirective(unsigned Size, SMLoc L);
184 bool parseDirectiveGpWord();
185 bool parseDirectiveGpDWord();
186 bool parseDirectiveModule();
187 bool parseDirectiveModuleFP();
188 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
189 StringRef Directive);
191 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
193 bool eatComma(StringRef ErrorStr);
195 int matchCPURegisterName(StringRef Symbol);
197 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
199 int matchFPURegisterName(StringRef Name);
201 int matchFCCRegisterName(StringRef Name);
203 int matchACRegisterName(StringRef Name);
205 int matchMSA128RegisterName(StringRef Name);
207 int matchMSA128CtrlRegisterName(StringRef Name);
209 unsigned getReg(int RC, int RegNo);
211 unsigned getGPR(int RegNo);
213 int getATReg(SMLoc Loc);
215 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
216 SmallVectorImpl<MCInst> &Instructions);
218 // Helper function that checks if the value of a vector index is within the
219 // boundaries of accepted values for each RegisterKind
220 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
221 bool validateMSAIndex(int Val, int RegKind);
223 // Selects a new architecture by updating the FeatureBits with the necessary
224 // info including implied dependencies.
225 // Internally, it clears all the feature bits related to *any* architecture
226 // and selects the new one using the ToggleFeature functionality of the
227 // MCSubtargetInfo object that handles implied dependencies. The reason we
228 // clear all the arch related bits manually is because ToggleFeature only
229 // clears the features that imply the feature being cleared and not the
230 // features implied by the feature being cleared. This is easier to see
232 // --------------------------------------------------
233 // | Feature | Implies |
234 // | -------------------------------------------------|
235 // | FeatureMips1 | None |
236 // | FeatureMips2 | FeatureMips1 |
237 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
238 // | FeatureMips4 | FeatureMips3 |
240 // --------------------------------------------------
242 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
243 // FeatureMipsGP64 | FeatureMips1)
244 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
245 void selectArch(StringRef ArchFeature) {
246 uint64_t FeatureBits = STI.getFeatureBits();
247 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
248 STI.setFeatureBits(FeatureBits);
249 setAvailableFeatures(
250 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
253 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
254 if (!(STI.getFeatureBits() & Feature)) {
255 setAvailableFeatures(
256 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
260 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
261 if (STI.getFeatureBits() & Feature) {
262 setAvailableFeatures(
263 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
268 enum MipsMatchResultTy {
269 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
270 #define GET_OPERAND_DIAGNOSTIC_TYPES
271 #include "MipsGenAsmMatcher.inc"
272 #undef GET_OPERAND_DIAGNOSTIC_TYPES
276 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
277 const MCInstrInfo &MII, const MCTargetOptions &Options)
278 : MCTargetAsmParser(), STI(sti), Parser(parser) {
279 // Initialize the set of available features.
280 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
282 getTargetStreamer().updateABIInfo(*this);
284 // Assert exactly one ABI was chosen.
285 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
286 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
287 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
288 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
290 if (!isABI_O32() && !useOddSPReg() != 0)
291 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
296 MCAsmParser &getParser() const { return Parser; }
297 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
299 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
300 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
302 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
303 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
304 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
305 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
306 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
307 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
309 bool useOddSPReg() const {
310 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
313 bool inMicroMipsMode() const {
314 return STI.getFeatureBits() & Mips::FeatureMicroMips;
316 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
317 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
318 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
319 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
320 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
321 bool hasMips32() const {
322 return (STI.getFeatureBits() & Mips::FeatureMips32);
324 bool hasMips64() const {
325 return (STI.getFeatureBits() & Mips::FeatureMips64);
327 bool hasMips32r2() const {
328 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
330 bool hasMips64r2() const {
331 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
333 bool hasMips32r6() const {
334 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
336 bool hasMips64r6() const {
337 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
339 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
340 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
341 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
343 bool inMips16Mode() const {
344 return STI.getFeatureBits() & Mips::FeatureMips16;
346 // TODO: see how can we get this info.
347 bool abiUsesSoftFloat() const { return false; }
349 /// Warn if RegNo is the current assembler temporary.
350 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
356 /// MipsOperand - Instances of this class represent a parsed Mips machine
358 class MipsOperand : public MCParsedAsmOperand {
360 /// Broad categories of register classes
361 /// The exact class is finalized by the render method.
363 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
364 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
366 RegKind_FCC = 4, /// FCC
367 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
368 RegKind_MSACtrl = 16, /// MSA control registers
369 RegKind_COP2 = 32, /// COP2
370 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
372 RegKind_CCR = 128, /// CCR
373 RegKind_HWRegs = 256, /// HWRegs
374 RegKind_COP3 = 512, /// COP3
376 /// Potentially any (e.g. $1)
377 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
378 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
379 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
384 k_Immediate, /// An immediate (possibly involving symbol references)
385 k_Memory, /// Base + Offset Memory Address
386 k_PhysRegister, /// A physical register from the Mips namespace
387 k_RegisterIndex, /// A register index in one or more RegKind.
388 k_Token /// A simple token
392 MipsOperand(KindTy K, MipsAsmParser &Parser)
393 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
396 /// For diagnostics, and checking the assembler temporary
397 MipsAsmParser &AsmParser;
405 unsigned Num; /// Register Number
409 unsigned Index; /// Index into the register class
410 RegKind Kind; /// Bitfield of the kinds it could possibly be
411 const MCRegisterInfo *RegInfo;
425 struct PhysRegOp PhysReg;
426 struct RegIdxOp RegIdx;
431 SMLoc StartLoc, EndLoc;
433 /// Internal constructor for register kinds
434 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
435 const MCRegisterInfo *RegInfo,
437 MipsAsmParser &Parser) {
438 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
439 Op->RegIdx.Index = Index;
440 Op->RegIdx.RegInfo = RegInfo;
441 Op->RegIdx.Kind = RegKind;
448 /// Coerce the register to GPR32 and return the real register for the current
450 unsigned getGPR32Reg() const {
451 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
452 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
453 unsigned ClassID = Mips::GPR32RegClassID;
454 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
457 /// Coerce the register to GPR64 and return the real register for the current
459 unsigned getGPR64Reg() const {
460 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
461 unsigned ClassID = Mips::GPR64RegClassID;
462 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
466 /// Coerce the register to AFGR64 and return the real register for the current
468 unsigned getAFGR64Reg() const {
469 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
470 if (RegIdx.Index % 2 != 0)
471 AsmParser.Warning(StartLoc, "Float register should be even.");
472 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
473 .getRegister(RegIdx.Index / 2);
476 /// Coerce the register to FGR64 and return the real register for the current
478 unsigned getFGR64Reg() const {
479 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
480 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
481 .getRegister(RegIdx.Index);
484 /// Coerce the register to FGR32 and return the real register for the current
486 unsigned getFGR32Reg() const {
487 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
488 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
489 .getRegister(RegIdx.Index);
492 /// Coerce the register to FGRH32 and return the real register for the current
494 unsigned getFGRH32Reg() const {
495 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
496 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
497 .getRegister(RegIdx.Index);
500 /// Coerce the register to FCC and return the real register for the current
502 unsigned getFCCReg() const {
503 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
504 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
505 .getRegister(RegIdx.Index);
508 /// Coerce the register to MSA128 and return the real register for the current
510 unsigned getMSA128Reg() const {
511 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
512 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
514 unsigned ClassID = Mips::MSA128BRegClassID;
515 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
518 /// Coerce the register to MSACtrl and return the real register for the
520 unsigned getMSACtrlReg() const {
521 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
522 unsigned ClassID = Mips::MSACtrlRegClassID;
523 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
526 /// Coerce the register to COP2 and return the real register for the
528 unsigned getCOP2Reg() const {
529 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
530 unsigned ClassID = Mips::COP2RegClassID;
531 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
534 /// Coerce the register to COP3 and return the real register for the
536 unsigned getCOP3Reg() const {
537 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
538 unsigned ClassID = Mips::COP3RegClassID;
539 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
542 /// Coerce the register to ACC64DSP and return the real register for the
544 unsigned getACC64DSPReg() const {
545 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
546 unsigned ClassID = Mips::ACC64DSPRegClassID;
547 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
550 /// Coerce the register to HI32DSP and return the real register for the
552 unsigned getHI32DSPReg() const {
553 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
554 unsigned ClassID = Mips::HI32DSPRegClassID;
555 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
558 /// Coerce the register to LO32DSP and return the real register for the
560 unsigned getLO32DSPReg() const {
561 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
562 unsigned ClassID = Mips::LO32DSPRegClassID;
563 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
566 /// Coerce the register to CCR and return the real register for the
568 unsigned getCCRReg() const {
569 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
570 unsigned ClassID = Mips::CCRRegClassID;
571 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
574 /// Coerce the register to HWRegs and return the real register for the
576 unsigned getHWRegsReg() const {
577 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
578 unsigned ClassID = Mips::HWRegsRegClassID;
579 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
583 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
584 // Add as immediate when possible. Null MCExpr = 0.
586 Inst.addOperand(MCOperand::CreateImm(0));
587 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
588 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
590 Inst.addOperand(MCOperand::CreateExpr(Expr));
593 void addRegOperands(MCInst &Inst, unsigned N) const {
594 llvm_unreachable("Use a custom parser instead");
597 /// Render the operand to an MCInst as a GPR32
598 /// Asserts if the wrong number of operands are requested, or the operand
599 /// is not a k_RegisterIndex compatible with RegKind_GPR
600 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
601 assert(N == 1 && "Invalid number of operands!");
602 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
605 /// Render the operand to an MCInst as a GPR64
606 /// Asserts if the wrong number of operands are requested, or the operand
607 /// is not a k_RegisterIndex compatible with RegKind_GPR
608 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
609 assert(N == 1 && "Invalid number of operands!");
610 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
613 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
614 assert(N == 1 && "Invalid number of operands!");
615 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
618 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
619 assert(N == 1 && "Invalid number of operands!");
620 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
623 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
624 assert(N == 1 && "Invalid number of operands!");
625 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
626 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
627 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
628 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
632 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
633 assert(N == 1 && "Invalid number of operands!");
634 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
637 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
638 assert(N == 1 && "Invalid number of operands!");
639 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
642 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
643 assert(N == 1 && "Invalid number of operands!");
644 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
647 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
648 assert(N == 1 && "Invalid number of operands!");
649 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
652 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
653 assert(N == 1 && "Invalid number of operands!");
654 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
657 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
658 assert(N == 1 && "Invalid number of operands!");
659 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
662 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
663 assert(N == 1 && "Invalid number of operands!");
664 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
667 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
668 assert(N == 1 && "Invalid number of operands!");
669 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
672 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
673 assert(N == 1 && "Invalid number of operands!");
674 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
677 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
678 assert(N == 1 && "Invalid number of operands!");
679 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
682 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
683 assert(N == 1 && "Invalid number of operands!");
684 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
687 void addImmOperands(MCInst &Inst, unsigned N) const {
688 assert(N == 1 && "Invalid number of operands!");
689 const MCExpr *Expr = getImm();
693 void addMemOperands(MCInst &Inst, unsigned N) const {
694 assert(N == 2 && "Invalid number of operands!");
696 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
698 const MCExpr *Expr = getMemOff();
702 bool isReg() const override {
703 // As a special case until we sort out the definition of div/divu, pretend
704 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
705 if (isGPRAsmReg() && RegIdx.Index == 0)
708 return Kind == k_PhysRegister;
710 bool isRegIdx() const { return Kind == k_RegisterIndex; }
711 bool isImm() const override { return Kind == k_Immediate; }
712 bool isConstantImm() const {
713 return isImm() && dyn_cast<MCConstantExpr>(getImm());
715 bool isToken() const override {
716 // Note: It's not possible to pretend that other operand kinds are tokens.
717 // The matcher emitter checks tokens first.
718 return Kind == k_Token;
720 bool isMem() const override { return Kind == k_Memory; }
721 bool isConstantMemOff() const {
722 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
724 template <unsigned Bits> bool isMemWithSimmOffset() const {
725 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
727 bool isInvNum() const { return Kind == k_Immediate; }
728 bool isLSAImm() const {
729 if (!isConstantImm())
731 int64_t Val = getConstantImm();
732 return 1 <= Val && Val <= 4;
735 StringRef getToken() const {
736 assert(Kind == k_Token && "Invalid access!");
737 return StringRef(Tok.Data, Tok.Length);
740 unsigned getReg() const override {
741 // As a special case until we sort out the definition of div/divu, pretend
742 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
743 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
744 RegIdx.Kind & RegKind_GPR)
745 return getGPR32Reg(); // FIXME: GPR64 too
747 assert(Kind == k_PhysRegister && "Invalid access!");
751 const MCExpr *getImm() const {
752 assert((Kind == k_Immediate) && "Invalid access!");
756 int64_t getConstantImm() const {
757 const MCExpr *Val = getImm();
758 return static_cast<const MCConstantExpr *>(Val)->getValue();
761 MipsOperand *getMemBase() const {
762 assert((Kind == k_Memory) && "Invalid access!");
766 const MCExpr *getMemOff() const {
767 assert((Kind == k_Memory) && "Invalid access!");
771 int64_t getConstantMemOff() const {
772 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
775 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
776 MipsAsmParser &Parser) {
777 auto Op = make_unique<MipsOperand>(k_Token, Parser);
778 Op->Tok.Data = Str.data();
779 Op->Tok.Length = Str.size();
785 /// Create a numeric register (e.g. $1). The exact register remains
786 /// unresolved until an instruction successfully matches
787 static std::unique_ptr<MipsOperand>
788 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
789 SMLoc E, MipsAsmParser &Parser) {
790 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
791 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
794 /// Create a register that is definitely a GPR.
795 /// This is typically only used for named registers such as $gp.
796 static std::unique_ptr<MipsOperand>
797 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
798 MipsAsmParser &Parser) {
799 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
802 /// Create a register that is definitely a FGR.
803 /// This is typically only used for named registers such as $f0.
804 static std::unique_ptr<MipsOperand>
805 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
806 MipsAsmParser &Parser) {
807 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
810 /// Create a register that is definitely an FCC.
811 /// This is typically only used for named registers such as $fcc0.
812 static std::unique_ptr<MipsOperand>
813 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
814 MipsAsmParser &Parser) {
815 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
818 /// Create a register that is definitely an ACC.
819 /// This is typically only used for named registers such as $ac0.
820 static std::unique_ptr<MipsOperand>
821 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
822 MipsAsmParser &Parser) {
823 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
826 /// Create a register that is definitely an MSA128.
827 /// This is typically only used for named registers such as $w0.
828 static std::unique_ptr<MipsOperand>
829 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
830 SMLoc E, MipsAsmParser &Parser) {
831 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
834 /// Create a register that is definitely an MSACtrl.
835 /// This is typically only used for named registers such as $msaaccess.
836 static std::unique_ptr<MipsOperand>
837 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
838 SMLoc E, MipsAsmParser &Parser) {
839 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
842 static std::unique_ptr<MipsOperand>
843 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
844 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
851 static std::unique_ptr<MipsOperand>
852 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
853 SMLoc E, MipsAsmParser &Parser) {
854 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
855 Op->Mem.Base = Base.release();
862 bool isGPRAsmReg() const {
863 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
865 bool isFGRAsmReg() const {
866 // AFGR64 is $0-$15 but we handle this in getAFGR64()
867 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
869 bool isHWRegsAsmReg() const {
870 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
872 bool isCCRAsmReg() const {
873 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
875 bool isFCCAsmReg() const {
876 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
878 if (!AsmParser.hasEightFccRegisters())
879 return RegIdx.Index == 0;
880 return RegIdx.Index <= 7;
882 bool isACCAsmReg() const {
883 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
885 bool isCOP2AsmReg() const {
886 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
888 bool isCOP3AsmReg() const {
889 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
891 bool isMSA128AsmReg() const {
892 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
894 bool isMSACtrlAsmReg() const {
895 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
898 /// getStartLoc - Get the location of the first token of this operand.
899 SMLoc getStartLoc() const override { return StartLoc; }
900 /// getEndLoc - Get the location of the last token of this operand.
901 SMLoc getEndLoc() const override { return EndLoc; }
903 virtual ~MipsOperand() {
911 case k_RegisterIndex:
917 void print(raw_ostream &OS) const override {
932 OS << "PhysReg<" << PhysReg.Num << ">";
934 case k_RegisterIndex:
935 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
942 }; // class MipsOperand
946 extern const MCInstrDesc MipsInsts[];
948 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
949 return MipsInsts[Opcode];
952 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
953 SmallVectorImpl<MCInst> &Instructions) {
954 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
958 if (MCID.isBranch() || MCID.isCall()) {
959 const unsigned Opcode = Inst.getOpcode();
969 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
970 Offset = Inst.getOperand(2);
972 break; // We'll deal with this situation later on when applying fixups.
973 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
974 return Error(IDLoc, "branch target out of range");
975 if (OffsetToAlignment(Offset.getImm(),
976 1LL << (inMicroMipsMode() ? 1 : 2)))
977 return Error(IDLoc, "branch to misaligned address");
991 case Mips::BGEZAL_MM:
992 case Mips::BLTZAL_MM:
995 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
996 Offset = Inst.getOperand(1);
998 break; // We'll deal with this situation later on when applying fixups.
999 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1000 return Error(IDLoc, "branch target out of range");
1001 if (OffsetToAlignment(Offset.getImm(),
1002 1LL << (inMicroMipsMode() ? 1 : 2)))
1003 return Error(IDLoc, "branch to misaligned address");
1008 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1009 // We still accept it but it is a normal nop.
1010 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1011 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1012 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1016 if (MCID.hasDelaySlot() && Options.isReorder()) {
1017 // If this instruction has a delay slot and .set reorder is active,
1018 // emit a NOP after it.
1019 Instructions.push_back(Inst);
1021 NopInst.setOpcode(Mips::SLL);
1022 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1023 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1024 NopInst.addOperand(MCOperand::CreateImm(0));
1025 Instructions.push_back(NopInst);
1029 if (MCID.mayLoad() || MCID.mayStore()) {
1030 // Check the offset of memory operand, if it is a symbol
1031 // reference or immediate we may have to expand instructions.
1032 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1033 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1034 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1035 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1036 MCOperand &Op = Inst.getOperand(i);
1038 int MemOffset = Op.getImm();
1039 if (MemOffset < -32768 || MemOffset > 32767) {
1040 // Offset can't exceed 16bit value.
1041 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1044 } else if (Op.isExpr()) {
1045 const MCExpr *Expr = Op.getExpr();
1046 if (Expr->getKind() == MCExpr::SymbolRef) {
1047 const MCSymbolRefExpr *SR =
1048 static_cast<const MCSymbolRefExpr *>(Expr);
1049 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1051 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1054 } else if (!isEvaluated(Expr)) {
1055 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1063 if (needsExpansion(Inst))
1064 return expandInstruction(Inst, IDLoc, Instructions);
1066 Instructions.push_back(Inst);
1071 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1073 switch (Inst.getOpcode()) {
1074 case Mips::LoadImm32Reg:
1075 case Mips::LoadAddr32Imm:
1076 case Mips::LoadAddr32Reg:
1077 case Mips::LoadImm64Reg:
1084 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1085 SmallVectorImpl<MCInst> &Instructions) {
1086 switch (Inst.getOpcode()) {
1088 assert(0 && "unimplemented expansion");
1090 case Mips::LoadImm32Reg:
1091 return expandLoadImm(Inst, IDLoc, Instructions);
1092 case Mips::LoadImm64Reg:
1094 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1097 return expandLoadImm(Inst, IDLoc, Instructions);
1098 case Mips::LoadAddr32Imm:
1099 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1100 case Mips::LoadAddr32Reg:
1101 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1106 template <int Shift, bool PerformShift>
1107 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1108 SmallVectorImpl<MCInst> &Instructions) {
1111 tmpInst.setOpcode(Mips::DSLL);
1112 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1113 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1114 tmpInst.addOperand(MCOperand::CreateImm(16));
1115 tmpInst.setLoc(IDLoc);
1116 Instructions.push_back(tmpInst);
1119 tmpInst.setOpcode(Mips::ORi);
1120 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1121 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1123 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)));
1124 tmpInst.setLoc(IDLoc);
1125 Instructions.push_back(tmpInst);
1129 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1130 SmallVectorImpl<MCInst> &Instructions) {
1132 const MCOperand &ImmOp = Inst.getOperand(1);
1133 assert(ImmOp.isImm() && "expected immediate operand kind");
1134 const MCOperand &RegOp = Inst.getOperand(0);
1135 assert(RegOp.isReg() && "expected register operand kind");
1137 int64_t ImmValue = ImmOp.getImm();
1138 tmpInst.setLoc(IDLoc);
1139 // FIXME: gas has a special case for values that are 000...1111, which
1140 // becomes a li -1 and then a dsrl
1141 if (0 <= ImmValue && ImmValue <= 65535) {
1142 // For 0 <= j <= 65535.
1143 // li d,j => ori d,$zero,j
1144 tmpInst.setOpcode(Mips::ORi);
1145 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1146 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1147 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1148 Instructions.push_back(tmpInst);
1149 } else if (ImmValue < 0 && ImmValue >= -32768) {
1150 // For -32768 <= j < 0.
1151 // li d,j => addiu d,$zero,j
1152 tmpInst.setOpcode(Mips::ADDiu);
1153 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1154 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1155 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1156 Instructions.push_back(tmpInst);
1157 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1158 // For any value of j that is representable as a 32-bit integer, create
1160 // li d,j => lui d,hi16(j)
1162 tmpInst.setOpcode(Mips::LUi);
1163 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1164 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1165 Instructions.push_back(tmpInst);
1166 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1167 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1169 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1173 // <------- lo32 ------>
1174 // <------- hi32 ------>
1175 // <- hi16 -> <- lo16 ->
1176 // _________________________________
1178 // | 16-bytes | 16-bytes | 16-bytes |
1179 // |__________|__________|__________|
1181 // For any value of j that is representable as a 48-bit integer, create
1183 // li d,j => lui d,hi16(j)
1184 // ori d,d,hi16(lo32(j))
1186 // ori d,d,lo16(lo32(j))
1187 tmpInst.setOpcode(Mips::LUi);
1188 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1190 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1191 Instructions.push_back(tmpInst);
1192 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1193 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1196 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1200 // <------- hi32 ------> <------- lo32 ------>
1201 // <- hi16 -> <- lo16 ->
1202 // ___________________________________________
1204 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1205 // |__________|__________|__________|__________|
1207 // For any value of j that isn't representable as a 48-bit integer.
1208 // li d,j => lui d,hi16(j)
1209 // ori d,d,lo16(hi32(j))
1211 // ori d,d,hi16(lo32(j))
1213 // ori d,d,lo16(lo32(j))
1214 tmpInst.setOpcode(Mips::LUi);
1215 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1217 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1218 Instructions.push_back(tmpInst);
1219 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1220 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1221 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1227 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1228 SmallVectorImpl<MCInst> &Instructions) {
1230 const MCOperand &ImmOp = Inst.getOperand(2);
1231 assert(ImmOp.isImm() && "expected immediate operand kind");
1232 const MCOperand &SrcRegOp = Inst.getOperand(1);
1233 assert(SrcRegOp.isReg() && "expected register operand kind");
1234 const MCOperand &DstRegOp = Inst.getOperand(0);
1235 assert(DstRegOp.isReg() && "expected register operand kind");
1236 int ImmValue = ImmOp.getImm();
1237 if (-32768 <= ImmValue && ImmValue <= 65535) {
1238 // For -32768 <= j <= 65535.
1239 // la d,j(s) => addiu d,s,j
1240 tmpInst.setOpcode(Mips::ADDiu);
1241 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1242 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1243 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1244 Instructions.push_back(tmpInst);
1246 // For any other value of j that is representable as a 32-bit integer.
1247 // la d,j(s) => lui d,hi16(j)
1250 tmpInst.setOpcode(Mips::LUi);
1251 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1252 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1253 Instructions.push_back(tmpInst);
1255 tmpInst.setOpcode(Mips::ORi);
1256 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1257 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1258 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1259 Instructions.push_back(tmpInst);
1261 tmpInst.setOpcode(Mips::ADDu);
1262 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1263 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1264 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1265 Instructions.push_back(tmpInst);
1271 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1272 SmallVectorImpl<MCInst> &Instructions) {
1274 const MCOperand &ImmOp = Inst.getOperand(1);
1275 assert(ImmOp.isImm() && "expected immediate operand kind");
1276 const MCOperand &RegOp = Inst.getOperand(0);
1277 assert(RegOp.isReg() && "expected register operand kind");
1278 int ImmValue = ImmOp.getImm();
1279 if (-32768 <= ImmValue && ImmValue <= 65535) {
1280 // For -32768 <= j <= 65535.
1281 // la d,j => addiu d,$zero,j
1282 tmpInst.setOpcode(Mips::ADDiu);
1283 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1284 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1285 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1286 Instructions.push_back(tmpInst);
1288 // For any other value of j that is representable as a 32-bit integer.
1289 // la d,j => lui d,hi16(j)
1291 tmpInst.setOpcode(Mips::LUi);
1292 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1293 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1294 Instructions.push_back(tmpInst);
1296 tmpInst.setOpcode(Mips::ORi);
1297 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1298 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1299 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1300 Instructions.push_back(tmpInst);
1305 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1306 SmallVectorImpl<MCInst> &Instructions,
1307 bool isLoad, bool isImmOpnd) {
1308 const MCSymbolRefExpr *SR;
1310 unsigned ImmOffset, HiOffset, LoOffset;
1311 const MCExpr *ExprOffset;
1313 // 1st operand is either the source or destination register.
1314 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1315 unsigned RegOpNum = Inst.getOperand(0).getReg();
1316 // 2nd operand is the base register.
1317 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1318 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1319 // 3rd operand is either an immediate or expression.
1321 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1322 ImmOffset = Inst.getOperand(2).getImm();
1323 LoOffset = ImmOffset & 0x0000ffff;
1324 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1325 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1326 if (LoOffset & 0x8000)
1329 ExprOffset = Inst.getOperand(2).getExpr();
1330 // All instructions will have the same location.
1331 TempInst.setLoc(IDLoc);
1332 // These are some of the types of expansions we perform here:
1333 // 1) lw $8, sym => lui $8, %hi(sym)
1334 // lw $8, %lo(sym)($8)
1335 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1337 // lw $8, %lo(offset)($9)
1338 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1340 // lw $8, %lo(offset)($at)
1341 // 4) sw $8, sym => lui $at, %hi(sym)
1342 // sw $8, %lo(sym)($at)
1343 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1345 // sw $8, %lo(offset)($at)
1346 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1347 // ldc1 $f0, %lo(sym)($at)
1349 // For load instructions we can use the destination register as a temporary
1350 // if base and dst are different (examples 1 and 2) and if the base register
1351 // is general purpose otherwise we must use $at (example 6) and error if it's
1352 // not available. For stores we must use $at (examples 4 and 5) because we
1353 // must not clobber the source register setting up the offset.
1354 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1355 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1356 unsigned RegClassIDOp0 =
1357 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1358 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1359 (RegClassIDOp0 == Mips::GPR64RegClassID);
1360 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1361 TmpRegNum = RegOpNum;
1363 int AT = getATReg(IDLoc);
1364 // At this point we need AT to perform the expansions and we exit if it is
1369 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1372 TempInst.setOpcode(Mips::LUi);
1373 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1375 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1377 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1378 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1379 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1380 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1382 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1384 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1385 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1388 // Add the instruction to the list.
1389 Instructions.push_back(TempInst);
1390 // Prepare TempInst for next instruction.
1392 // Add temp register to base.
1393 TempInst.setOpcode(Mips::ADDu);
1394 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1395 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1396 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1397 Instructions.push_back(TempInst);
1399 // And finally, create original instruction with low part
1400 // of offset and new base.
1401 TempInst.setOpcode(Inst.getOpcode());
1402 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1403 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1405 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1407 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1408 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1409 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1411 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1413 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1414 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1417 Instructions.push_back(TempInst);
1421 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1422 // As described by the Mips32r2 spec, the registers Rd and Rs for
1423 // jalr.hb must be different.
1424 unsigned Opcode = Inst.getOpcode();
1426 if (Opcode == Mips::JALR_HB &&
1427 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1428 return Match_RequiresDifferentSrcAndDst;
1430 return Match_Success;
1433 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1434 OperandVector &Operands,
1436 unsigned &ErrorInfo,
1437 bool MatchingInlineAsm) {
1440 SmallVector<MCInst, 8> Instructions;
1441 unsigned MatchResult =
1442 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1444 switch (MatchResult) {
1447 case Match_Success: {
1448 if (processInstruction(Inst, IDLoc, Instructions))
1450 for (unsigned i = 0; i < Instructions.size(); i++)
1451 Out.EmitInstruction(Instructions[i], STI);
1454 case Match_MissingFeature:
1455 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1457 case Match_InvalidOperand: {
1458 SMLoc ErrorLoc = IDLoc;
1459 if (ErrorInfo != ~0U) {
1460 if (ErrorInfo >= Operands.size())
1461 return Error(IDLoc, "too few operands for instruction");
1463 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1464 if (ErrorLoc == SMLoc())
1468 return Error(ErrorLoc, "invalid operand for instruction");
1470 case Match_MnemonicFail:
1471 return Error(IDLoc, "invalid instruction");
1472 case Match_RequiresDifferentSrcAndDst:
1473 return Error(IDLoc, "source and destination must be different");
1478 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1479 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1481 Warning(Loc, "Used $at without \".set noat\"");
1483 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1484 Twine(RegIndex) + "\"");
1488 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1491 CC = StringSwitch<unsigned>(Name)
1527 if (isABI_N32() || isABI_N64()) {
1528 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1529 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1530 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1531 if (8 <= CC && CC <= 11)
1535 CC = StringSwitch<unsigned>(Name)
1548 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1550 if (Name[0] == 'f') {
1551 StringRef NumString = Name.substr(1);
1553 if (NumString.getAsInteger(10, IntVal))
1554 return -1; // This is not an integer.
1555 if (IntVal > 31) // Maximum index for fpu register.
1562 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1564 if (Name.startswith("fcc")) {
1565 StringRef NumString = Name.substr(3);
1567 if (NumString.getAsInteger(10, IntVal))
1568 return -1; // This is not an integer.
1569 if (IntVal > 7) // There are only 8 fcc registers.
1576 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1578 if (Name.startswith("ac")) {
1579 StringRef NumString = Name.substr(2);
1581 if (NumString.getAsInteger(10, IntVal))
1582 return -1; // This is not an integer.
1583 if (IntVal > 3) // There are only 3 acc registers.
1590 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1593 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1602 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1605 CC = StringSwitch<unsigned>(Name)
1608 .Case("msaaccess", 2)
1610 .Case("msamodify", 4)
1611 .Case("msarequest", 5)
1613 .Case("msaunmap", 7)
1619 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1627 int MipsAsmParser::getATReg(SMLoc Loc) {
1628 int AT = Options.getATRegNum();
1630 reportParseError(Loc,
1631 "Pseudo instruction requires $at, which is not available");
1635 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1636 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1639 unsigned MipsAsmParser::getGPR(int RegNo) {
1640 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1644 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1646 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1649 return getReg(RegClass, RegNum);
1652 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1653 DEBUG(dbgs() << "ParseOperand\n");
1655 // Check if the current operand has a custom associated parser, if so, try to
1656 // custom parse the operand, or fallback to the general approach.
1657 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1658 if (ResTy == MatchOperand_Success)
1660 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1661 // there was a match, but an error occurred, in which case, just return that
1662 // the operand parsing failed.
1663 if (ResTy == MatchOperand_ParseFail)
1666 DEBUG(dbgs() << ".. Generic Parser\n");
1668 switch (getLexer().getKind()) {
1670 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1672 case AsmToken::Dollar: {
1673 // Parse the register.
1674 SMLoc S = Parser.getTok().getLoc();
1676 // Almost all registers have been parsed by custom parsers. There is only
1677 // one exception to this. $zero (and it's alias $0) will reach this point
1678 // for div, divu, and similar instructions because it is not an operand
1679 // to the instruction definition but an explicit register. Special case
1680 // this situation for now.
1681 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1684 // Maybe it is a symbol reference.
1685 StringRef Identifier;
1686 if (Parser.parseIdentifier(Identifier))
1689 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1690 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1691 // Otherwise create a symbol reference.
1693 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1695 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1698 // Else drop to expression parsing.
1699 case AsmToken::LParen:
1700 case AsmToken::Minus:
1701 case AsmToken::Plus:
1702 case AsmToken::Integer:
1703 case AsmToken::Tilde:
1704 case AsmToken::String: {
1705 DEBUG(dbgs() << ".. generic integer\n");
1706 OperandMatchResultTy ResTy = ParseImm(Operands);
1707 return ResTy != MatchOperand_Success;
1709 case AsmToken::Percent: {
1710 // It is a symbol reference or constant expression.
1711 const MCExpr *IdVal;
1712 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1713 if (parseRelocOperand(IdVal))
1716 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1718 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1720 } // case AsmToken::Percent
1721 } // switch(getLexer().getKind())
1725 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1726 StringRef RelocStr) {
1728 // Check the type of the expression.
1729 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1730 // It's a constant, evaluate reloc value.
1732 switch (getVariantKind(RelocStr)) {
1733 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1734 // Get the 1st 16-bits.
1735 Val = MCE->getValue() & 0xffff;
1737 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1738 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1739 // 16 bits being negative.
1740 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1742 case MCSymbolRefExpr::VK_Mips_HIGHER:
1743 // Get the 3rd 16-bits.
1744 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1746 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1747 // Get the 4th 16-bits.
1748 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1751 report_fatal_error("Unsupported reloc value!");
1753 return MCConstantExpr::Create(Val, getContext());
1756 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1757 // It's a symbol, create a symbolic expression from the symbol.
1758 StringRef Symbol = MSRE->getSymbol().getName();
1759 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1760 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1764 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1765 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1767 // Try to create target expression.
1768 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1769 return MipsMCExpr::Create(VK, Expr, getContext());
1771 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1772 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1773 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1777 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1778 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1779 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1782 // Just return the original expression.
1786 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1788 switch (Expr->getKind()) {
1789 case MCExpr::Constant:
1791 case MCExpr::SymbolRef:
1792 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1793 case MCExpr::Binary:
1794 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1795 if (!isEvaluated(BE->getLHS()))
1797 return isEvaluated(BE->getRHS());
1800 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1801 case MCExpr::Target:
1807 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1808 Parser.Lex(); // Eat the % token.
1809 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1810 if (Tok.isNot(AsmToken::Identifier))
1813 std::string Str = Tok.getIdentifier().str();
1815 Parser.Lex(); // Eat the identifier.
1816 // Now make an expression from the rest of the operand.
1817 const MCExpr *IdVal;
1820 if (getLexer().getKind() == AsmToken::LParen) {
1822 Parser.Lex(); // Eat the '(' token.
1823 if (getLexer().getKind() == AsmToken::Percent) {
1824 Parser.Lex(); // Eat the % token.
1825 const AsmToken &nextTok = Parser.getTok();
1826 if (nextTok.isNot(AsmToken::Identifier))
1829 Str += nextTok.getIdentifier();
1830 Parser.Lex(); // Eat the identifier.
1831 if (getLexer().getKind() != AsmToken::LParen)
1836 if (getParser().parseParenExpression(IdVal, EndLoc))
1839 while (getLexer().getKind() == AsmToken::RParen)
1840 Parser.Lex(); // Eat the ')' token.
1843 return true; // Parenthesis must follow the relocation operand.
1845 Res = evaluateRelocExpr(IdVal, Str);
1849 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1851 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1852 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1853 if (ResTy == MatchOperand_Success) {
1854 assert(Operands.size() == 1);
1855 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1856 StartLoc = Operand.getStartLoc();
1857 EndLoc = Operand.getEndLoc();
1859 // AFAIK, we only support numeric registers and named GPR's in CFI
1861 // Don't worry about eating tokens before failing. Using an unrecognised
1862 // register is a parse error.
1863 if (Operand.isGPRAsmReg()) {
1864 // Resolve to GPR32 or GPR64 appropriately.
1865 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1868 return (RegNo == (unsigned)-1);
1871 assert(Operands.size() == 0);
1872 return (RegNo == (unsigned)-1);
1875 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1879 while (getLexer().getKind() == AsmToken::LParen)
1882 switch (getLexer().getKind()) {
1885 case AsmToken::Identifier:
1886 case AsmToken::LParen:
1887 case AsmToken::Integer:
1888 case AsmToken::Minus:
1889 case AsmToken::Plus:
1891 Result = getParser().parseParenExpression(Res, S);
1893 Result = (getParser().parseExpression(Res));
1894 while (getLexer().getKind() == AsmToken::RParen)
1897 case AsmToken::Percent:
1898 Result = parseRelocOperand(Res);
1903 MipsAsmParser::OperandMatchResultTy
1904 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1905 DEBUG(dbgs() << "parseMemOperand\n");
1906 const MCExpr *IdVal = nullptr;
1908 bool isParenExpr = false;
1909 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1910 // First operand is the offset.
1911 S = Parser.getTok().getLoc();
1913 if (getLexer().getKind() == AsmToken::LParen) {
1918 if (getLexer().getKind() != AsmToken::Dollar) {
1919 if (parseMemOffset(IdVal, isParenExpr))
1920 return MatchOperand_ParseFail;
1922 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1923 if (Tok.isNot(AsmToken::LParen)) {
1924 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
1925 if (Mnemonic.getToken() == "la") {
1927 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1928 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1929 return MatchOperand_Success;
1931 if (Tok.is(AsmToken::EndOfStatement)) {
1933 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1935 // Zero register assumed, add a memory operand with ZERO as its base.
1936 // "Base" will be managed by k_Memory.
1937 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
1940 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
1941 return MatchOperand_Success;
1943 Error(Parser.getTok().getLoc(), "'(' expected");
1944 return MatchOperand_ParseFail;
1947 Parser.Lex(); // Eat the '(' token.
1950 Res = ParseAnyRegister(Operands);
1951 if (Res != MatchOperand_Success)
1954 if (Parser.getTok().isNot(AsmToken::RParen)) {
1955 Error(Parser.getTok().getLoc(), "')' expected");
1956 return MatchOperand_ParseFail;
1959 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1961 Parser.Lex(); // Eat the ')' token.
1964 IdVal = MCConstantExpr::Create(0, getContext());
1966 // Replace the register operand with the memory operand.
1967 std::unique_ptr<MipsOperand> op(
1968 static_cast<MipsOperand *>(Operands.back().release()));
1969 // Remove the register from the operands.
1970 // "op" will be managed by k_Memory.
1971 Operands.pop_back();
1972 // Add the memory operand.
1973 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1975 if (IdVal->EvaluateAsAbsolute(Imm))
1976 IdVal = MCConstantExpr::Create(Imm, getContext());
1977 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1978 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1982 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
1983 return MatchOperand_Success;
1986 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
1988 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1990 SMLoc S = Parser.getTok().getLoc();
1992 if (Sym->isVariable())
1993 Expr = Sym->getVariableValue();
1996 if (Expr->getKind() == MCExpr::SymbolRef) {
1997 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1998 const StringRef DefSymbol = Ref->getSymbol().getName();
1999 if (DefSymbol.startswith("$")) {
2000 OperandMatchResultTy ResTy =
2001 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2002 if (ResTy == MatchOperand_Success) {
2005 } else if (ResTy == MatchOperand_ParseFail)
2006 llvm_unreachable("Should never ParseFail");
2009 } else if (Expr->getKind() == MCExpr::Constant) {
2011 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2013 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2020 MipsAsmParser::OperandMatchResultTy
2021 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2022 StringRef Identifier,
2024 int Index = matchCPURegisterName(Identifier);
2026 Operands.push_back(MipsOperand::CreateGPRReg(
2027 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2028 return MatchOperand_Success;
2031 Index = matchFPURegisterName(Identifier);
2033 Operands.push_back(MipsOperand::CreateFGRReg(
2034 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2035 return MatchOperand_Success;
2038 Index = matchFCCRegisterName(Identifier);
2040 Operands.push_back(MipsOperand::CreateFCCReg(
2041 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2042 return MatchOperand_Success;
2045 Index = matchACRegisterName(Identifier);
2047 Operands.push_back(MipsOperand::CreateACCReg(
2048 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2049 return MatchOperand_Success;
2052 Index = matchMSA128RegisterName(Identifier);
2054 Operands.push_back(MipsOperand::CreateMSA128Reg(
2055 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2056 return MatchOperand_Success;
2059 Index = matchMSA128CtrlRegisterName(Identifier);
2061 Operands.push_back(MipsOperand::CreateMSACtrlReg(
2062 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2063 return MatchOperand_Success;
2066 return MatchOperand_NoMatch;
2069 MipsAsmParser::OperandMatchResultTy
2070 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2071 auto Token = Parser.getLexer().peekTok(false);
2073 if (Token.is(AsmToken::Identifier)) {
2074 DEBUG(dbgs() << ".. identifier\n");
2075 StringRef Identifier = Token.getIdentifier();
2076 OperandMatchResultTy ResTy =
2077 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2079 } else if (Token.is(AsmToken::Integer)) {
2080 DEBUG(dbgs() << ".. integer\n");
2081 Operands.push_back(MipsOperand::CreateNumericReg(
2082 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2084 return MatchOperand_Success;
2087 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2089 return MatchOperand_NoMatch;
2092 MipsAsmParser::OperandMatchResultTy
2093 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
2094 DEBUG(dbgs() << "ParseAnyRegister\n");
2096 auto Token = Parser.getTok();
2098 SMLoc S = Token.getLoc();
2100 if (Token.isNot(AsmToken::Dollar)) {
2101 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2102 if (Token.is(AsmToken::Identifier)) {
2103 if (searchSymbolAlias(Operands))
2104 return MatchOperand_Success;
2106 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2107 return MatchOperand_NoMatch;
2109 DEBUG(dbgs() << ".. $\n");
2111 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
2112 if (ResTy == MatchOperand_Success) {
2114 Parser.Lex(); // identifier
2119 MipsAsmParser::OperandMatchResultTy
2120 MipsAsmParser::ParseImm(OperandVector &Operands) {
2121 switch (getLexer().getKind()) {
2123 return MatchOperand_NoMatch;
2124 case AsmToken::LParen:
2125 case AsmToken::Minus:
2126 case AsmToken::Plus:
2127 case AsmToken::Integer:
2128 case AsmToken::Tilde:
2129 case AsmToken::String:
2133 const MCExpr *IdVal;
2134 SMLoc S = Parser.getTok().getLoc();
2135 if (getParser().parseExpression(IdVal))
2136 return MatchOperand_ParseFail;
2138 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2139 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2140 return MatchOperand_Success;
2143 MipsAsmParser::OperandMatchResultTy
2144 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
2145 DEBUG(dbgs() << "ParseJumpTarget\n");
2147 SMLoc S = getLexer().getLoc();
2149 // Integers and expressions are acceptable
2150 OperandMatchResultTy ResTy = ParseImm(Operands);
2151 if (ResTy != MatchOperand_NoMatch)
2154 // Registers are a valid target and have priority over symbols.
2155 ResTy = ParseAnyRegister(Operands);
2156 if (ResTy != MatchOperand_NoMatch)
2159 const MCExpr *Expr = nullptr;
2160 if (Parser.parseExpression(Expr)) {
2161 // We have no way of knowing if a symbol was consumed so we must ParseFail
2162 return MatchOperand_ParseFail;
2165 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2166 return MatchOperand_Success;
2169 MipsAsmParser::OperandMatchResultTy
2170 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2171 const MCExpr *IdVal;
2172 // If the first token is '$' we may have register operand.
2173 if (Parser.getTok().is(AsmToken::Dollar))
2174 return MatchOperand_NoMatch;
2175 SMLoc S = Parser.getTok().getLoc();
2176 if (getParser().parseExpression(IdVal))
2177 return MatchOperand_ParseFail;
2178 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2179 assert(MCE && "Unexpected MCExpr type.");
2180 int64_t Val = MCE->getValue();
2181 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2182 Operands.push_back(MipsOperand::CreateImm(
2183 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2184 return MatchOperand_Success;
2187 MipsAsmParser::OperandMatchResultTy
2188 MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
2189 switch (getLexer().getKind()) {
2191 return MatchOperand_NoMatch;
2192 case AsmToken::LParen:
2193 case AsmToken::Plus:
2194 case AsmToken::Minus:
2195 case AsmToken::Integer:
2200 SMLoc S = Parser.getTok().getLoc();
2202 if (getParser().parseExpression(Expr))
2203 return MatchOperand_ParseFail;
2206 if (!Expr->EvaluateAsAbsolute(Val)) {
2207 Error(S, "expected immediate value");
2208 return MatchOperand_ParseFail;
2211 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2212 // and because the CPU always adds one to the immediate field, the allowed
2213 // range becomes 1..4. We'll only check the range here and will deal
2214 // with the addition/subtraction when actually decoding/encoding
2216 if (Val < 1 || Val > 4) {
2217 Error(S, "immediate not in range (1..4)");
2218 return MatchOperand_ParseFail;
2222 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2223 return MatchOperand_Success;
2226 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2228 MCSymbolRefExpr::VariantKind VK =
2229 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2230 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2231 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2232 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2233 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2234 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2235 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2236 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2237 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2238 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2239 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2240 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2241 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2242 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2243 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2244 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2245 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2246 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2247 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2248 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2249 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2250 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2251 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2252 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2253 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2254 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2255 .Default(MCSymbolRefExpr::VK_None);
2257 assert(VK != MCSymbolRefExpr::VK_None);
2262 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2264 /// ::= '(', register, ')'
2265 /// handle it before we iterate so we don't get tripped up by the lack of
2267 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2268 if (getLexer().is(AsmToken::LParen)) {
2270 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2272 if (ParseOperand(Operands, Name)) {
2273 SMLoc Loc = getLexer().getLoc();
2274 Parser.eatToEndOfStatement();
2275 return Error(Loc, "unexpected token in argument list");
2277 if (Parser.getTok().isNot(AsmToken::RParen)) {
2278 SMLoc Loc = getLexer().getLoc();
2279 Parser.eatToEndOfStatement();
2280 return Error(Loc, "unexpected token, expected ')'");
2283 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2289 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2290 /// either one of these.
2291 /// ::= '[', register, ']'
2292 /// ::= '[', integer, ']'
2293 /// handle it before we iterate so we don't get tripped up by the lack of
2295 bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2296 OperandVector &Operands) {
2297 if (getLexer().is(AsmToken::LBrac)) {
2299 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2301 if (ParseOperand(Operands, Name)) {
2302 SMLoc Loc = getLexer().getLoc();
2303 Parser.eatToEndOfStatement();
2304 return Error(Loc, "unexpected token in argument list");
2306 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2307 SMLoc Loc = getLexer().getLoc();
2308 Parser.eatToEndOfStatement();
2309 return Error(Loc, "unexpected token, expected ']'");
2312 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2318 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2319 SMLoc NameLoc, OperandVector &Operands) {
2320 DEBUG(dbgs() << "ParseInstruction\n");
2322 // We have reached first instruction, module directive are now forbidden.
2323 getTargetStreamer().forbidModuleDirective();
2325 // Check if we have valid mnemonic
2326 if (!mnemonicIsValid(Name, 0)) {
2327 Parser.eatToEndOfStatement();
2328 return Error(NameLoc, "Unknown instruction");
2330 // First operand in MCInst is instruction mnemonic.
2331 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2333 // Read the remaining operands.
2334 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2335 // Read the first operand.
2336 if (ParseOperand(Operands, Name)) {
2337 SMLoc Loc = getLexer().getLoc();
2338 Parser.eatToEndOfStatement();
2339 return Error(Loc, "unexpected token in argument list");
2341 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2343 // AFAIK, parenthesis suffixes are never on the first operand
2345 while (getLexer().is(AsmToken::Comma)) {
2346 Parser.Lex(); // Eat the comma.
2347 // Parse and remember the operand.
2348 if (ParseOperand(Operands, Name)) {
2349 SMLoc Loc = getLexer().getLoc();
2350 Parser.eatToEndOfStatement();
2351 return Error(Loc, "unexpected token in argument list");
2353 // Parse bracket and parenthesis suffixes before we iterate
2354 if (getLexer().is(AsmToken::LBrac)) {
2355 if (ParseBracketSuffix(Name, Operands))
2357 } else if (getLexer().is(AsmToken::LParen) &&
2358 ParseParenSuffix(Name, Operands))
2362 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2363 SMLoc Loc = getLexer().getLoc();
2364 Parser.eatToEndOfStatement();
2365 return Error(Loc, "unexpected token in argument list");
2367 Parser.Lex(); // Consume the EndOfStatement.
2371 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2372 SMLoc Loc = getLexer().getLoc();
2373 Parser.eatToEndOfStatement();
2374 return Error(Loc, ErrorMsg);
2377 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2378 return Error(Loc, ErrorMsg);
2381 bool MipsAsmParser::parseSetNoAtDirective() {
2382 // Line should look like: ".set noat".
2384 Options.setATReg(0);
2387 // If this is not the end of the statement, report an error.
2388 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2389 reportParseError("unexpected token in statement");
2392 Parser.Lex(); // Consume the EndOfStatement.
2396 bool MipsAsmParser::parseSetAtDirective() {
2397 // Line can be .set at - defaults to $1
2401 if (getLexer().is(AsmToken::EndOfStatement)) {
2402 Options.setATReg(1);
2403 Parser.Lex(); // Consume the EndOfStatement.
2405 } else if (getLexer().is(AsmToken::Equal)) {
2406 getParser().Lex(); // Eat the '='.
2407 if (getLexer().isNot(AsmToken::Dollar)) {
2408 reportParseError("unexpected token in statement");
2411 Parser.Lex(); // Eat the '$'.
2412 const AsmToken &Reg = Parser.getTok();
2413 if (Reg.is(AsmToken::Identifier)) {
2414 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2415 } else if (Reg.is(AsmToken::Integer)) {
2416 AtRegNo = Reg.getIntVal();
2418 reportParseError("unexpected token in statement");
2422 if (AtRegNo < 0 || AtRegNo > 31) {
2423 reportParseError("unexpected token in statement");
2427 if (!Options.setATReg(AtRegNo)) {
2428 reportParseError("unexpected token in statement");
2431 getParser().Lex(); // Eat the register.
2433 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2434 reportParseError("unexpected token in statement");
2437 Parser.Lex(); // Consume the EndOfStatement.
2440 reportParseError("unexpected token in statement");
2445 bool MipsAsmParser::parseSetReorderDirective() {
2447 // If this is not the end of the statement, report an error.
2448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2449 reportParseError("unexpected token in statement");
2452 Options.setReorder();
2453 getTargetStreamer().emitDirectiveSetReorder();
2454 Parser.Lex(); // Consume the EndOfStatement.
2458 bool MipsAsmParser::parseSetNoReorderDirective() {
2460 // If this is not the end of the statement, report an error.
2461 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2462 reportParseError("unexpected token in statement");
2465 Options.setNoreorder();
2466 getTargetStreamer().emitDirectiveSetNoReorder();
2467 Parser.Lex(); // Consume the EndOfStatement.
2471 bool MipsAsmParser::parseSetMacroDirective() {
2473 // If this is not the end of the statement, report an error.
2474 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2475 reportParseError("unexpected token in statement");
2479 Parser.Lex(); // Consume the EndOfStatement.
2483 bool MipsAsmParser::parseSetNoMacroDirective() {
2485 // If this is not the end of the statement, report an error.
2486 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2487 reportParseError("`noreorder' must be set before `nomacro'");
2490 if (Options.isReorder()) {
2491 reportParseError("`noreorder' must be set before `nomacro'");
2494 Options.setNomacro();
2495 Parser.Lex(); // Consume the EndOfStatement.
2499 bool MipsAsmParser::parseSetMsaDirective() {
2502 // If this is not the end of the statement, report an error.
2503 if (getLexer().isNot(AsmToken::EndOfStatement))
2504 return reportParseError("unexpected token in statement");
2506 setFeatureBits(Mips::FeatureMSA, "msa");
2507 getTargetStreamer().emitDirectiveSetMsa();
2511 bool MipsAsmParser::parseSetNoMsaDirective() {
2514 // If this is not the end of the statement, report an error.
2515 if (getLexer().isNot(AsmToken::EndOfStatement))
2516 return reportParseError("unexpected token in statement");
2518 clearFeatureBits(Mips::FeatureMSA, "msa");
2519 getTargetStreamer().emitDirectiveSetNoMsa();
2523 bool MipsAsmParser::parseSetNoMips16Directive() {
2525 // If this is not the end of the statement, report an error.
2526 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2527 reportParseError("unexpected token in statement");
2530 // For now do nothing.
2531 Parser.Lex(); // Consume the EndOfStatement.
2535 bool MipsAsmParser::parseSetFpDirective() {
2536 MipsABIFlagsSection::FpABIKind FpAbiVal;
2537 // Line can be: .set fp=32
2540 Parser.Lex(); // Eat fp token
2541 AsmToken Tok = Parser.getTok();
2542 if (Tok.isNot(AsmToken::Equal)) {
2543 reportParseError("unexpected token in statement");
2546 Parser.Lex(); // Eat '=' token.
2547 Tok = Parser.getTok();
2549 if (!parseFpABIValue(FpAbiVal, ".set"))
2552 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2553 reportParseError("unexpected token in statement");
2556 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2557 Parser.Lex(); // Consume the EndOfStatement.
2561 bool MipsAsmParser::parseSetAssignment() {
2563 const MCExpr *Value;
2565 if (Parser.parseIdentifier(Name))
2566 reportParseError("expected identifier after .set");
2568 if (getLexer().isNot(AsmToken::Comma))
2569 return reportParseError("unexpected token in .set directive");
2572 if (Parser.parseExpression(Value))
2573 return reportParseError("expected valid expression after comma");
2575 // Check if the Name already exists as a symbol.
2576 MCSymbol *Sym = getContext().LookupSymbol(Name);
2578 return reportParseError("symbol already defined");
2579 Sym = getContext().GetOrCreateSymbol(Name);
2580 Sym->setVariableValue(Value);
2585 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2587 if (getLexer().isNot(AsmToken::EndOfStatement))
2588 return reportParseError("unexpected token in .set directive");
2592 llvm_unreachable("Unimplemented feature");
2593 case Mips::FeatureDSP:
2594 setFeatureBits(Mips::FeatureDSP, "dsp");
2595 getTargetStreamer().emitDirectiveSetDsp();
2597 case Mips::FeatureMicroMips:
2598 getTargetStreamer().emitDirectiveSetMicroMips();
2600 case Mips::FeatureMips16:
2601 getTargetStreamer().emitDirectiveSetMips16();
2603 case Mips::FeatureMips1:
2604 selectArch("mips1");
2605 getTargetStreamer().emitDirectiveSetMips1();
2607 case Mips::FeatureMips2:
2608 selectArch("mips2");
2609 getTargetStreamer().emitDirectiveSetMips2();
2611 case Mips::FeatureMips3:
2612 selectArch("mips3");
2613 getTargetStreamer().emitDirectiveSetMips3();
2615 case Mips::FeatureMips4:
2616 selectArch("mips4");
2617 getTargetStreamer().emitDirectiveSetMips4();
2619 case Mips::FeatureMips5:
2620 selectArch("mips5");
2621 getTargetStreamer().emitDirectiveSetMips5();
2623 case Mips::FeatureMips32:
2624 selectArch("mips32");
2625 getTargetStreamer().emitDirectiveSetMips32();
2627 case Mips::FeatureMips32r2:
2628 selectArch("mips32r2");
2629 getTargetStreamer().emitDirectiveSetMips32R2();
2631 case Mips::FeatureMips32r6:
2632 selectArch("mips32r6");
2633 getTargetStreamer().emitDirectiveSetMips32R6();
2635 case Mips::FeatureMips64:
2636 selectArch("mips64");
2637 getTargetStreamer().emitDirectiveSetMips64();
2639 case Mips::FeatureMips64r2:
2640 selectArch("mips64r2");
2641 getTargetStreamer().emitDirectiveSetMips64R2();
2643 case Mips::FeatureMips64r6:
2644 selectArch("mips64r6");
2645 getTargetStreamer().emitDirectiveSetMips64R6();
2651 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2652 if (getLexer().isNot(AsmToken::Comma)) {
2653 SMLoc Loc = getLexer().getLoc();
2654 Parser.eatToEndOfStatement();
2655 return Error(Loc, ErrorStr);
2658 Parser.Lex(); // Eat the comma.
2662 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2663 if (Options.isReorder())
2664 Warning(Loc, ".cpload in reorder section");
2666 // FIXME: Warn if cpload is used in Mips16 mode.
2668 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2669 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2670 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2671 reportParseError("expected register containing function address");
2675 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2676 if (!RegOpnd.isGPRAsmReg()) {
2677 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2681 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2685 bool MipsAsmParser::parseDirectiveCPSetup() {
2688 bool SaveIsReg = true;
2690 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2691 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2692 if (ResTy == MatchOperand_NoMatch) {
2693 reportParseError("expected register containing function address");
2694 Parser.eatToEndOfStatement();
2698 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2699 if (!FuncRegOpnd.isGPRAsmReg()) {
2700 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2701 Parser.eatToEndOfStatement();
2705 FuncReg = FuncRegOpnd.getGPR32Reg();
2708 if (!eatComma("expected comma parsing directive"))
2711 ResTy = ParseAnyRegister(TmpReg);
2712 if (ResTy == MatchOperand_NoMatch) {
2713 const AsmToken &Tok = Parser.getTok();
2714 if (Tok.is(AsmToken::Integer)) {
2715 Save = Tok.getIntVal();
2719 reportParseError("expected save register or stack offset");
2720 Parser.eatToEndOfStatement();
2724 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2725 if (!SaveOpnd.isGPRAsmReg()) {
2726 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2727 Parser.eatToEndOfStatement();
2730 Save = SaveOpnd.getGPR32Reg();
2733 if (!eatComma("expected comma parsing directive"))
2737 if (Parser.parseIdentifier(Name))
2738 reportParseError("expected identifier");
2739 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2741 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2745 bool MipsAsmParser::parseDirectiveNaN() {
2746 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2747 const AsmToken &Tok = Parser.getTok();
2749 if (Tok.getString() == "2008") {
2751 getTargetStreamer().emitDirectiveNaN2008();
2753 } else if (Tok.getString() == "legacy") {
2755 getTargetStreamer().emitDirectiveNaNLegacy();
2759 // If we don't recognize the option passed to the .nan
2760 // directive (e.g. no option or unknown option), emit an error.
2761 reportParseError("invalid option in .nan directive");
2765 bool MipsAsmParser::parseDirectiveSet() {
2767 // Get the next token.
2768 const AsmToken &Tok = Parser.getTok();
2770 if (Tok.getString() == "noat") {
2771 return parseSetNoAtDirective();
2772 } else if (Tok.getString() == "at") {
2773 return parseSetAtDirective();
2774 } else if (Tok.getString() == "fp") {
2775 return parseSetFpDirective();
2776 } else if (Tok.getString() == "reorder") {
2777 return parseSetReorderDirective();
2778 } else if (Tok.getString() == "noreorder") {
2779 return parseSetNoReorderDirective();
2780 } else if (Tok.getString() == "macro") {
2781 return parseSetMacroDirective();
2782 } else if (Tok.getString() == "nomacro") {
2783 return parseSetNoMacroDirective();
2784 } else if (Tok.getString() == "mips16") {
2785 return parseSetFeature(Mips::FeatureMips16);
2786 } else if (Tok.getString() == "nomips16") {
2787 return parseSetNoMips16Directive();
2788 } else if (Tok.getString() == "nomicromips") {
2789 getTargetStreamer().emitDirectiveSetNoMicroMips();
2790 Parser.eatToEndOfStatement();
2792 } else if (Tok.getString() == "micromips") {
2793 return parseSetFeature(Mips::FeatureMicroMips);
2794 } else if (Tok.getString() == "mips1") {
2795 return parseSetFeature(Mips::FeatureMips1);
2796 } else if (Tok.getString() == "mips2") {
2797 return parseSetFeature(Mips::FeatureMips2);
2798 } else if (Tok.getString() == "mips3") {
2799 return parseSetFeature(Mips::FeatureMips3);
2800 } else if (Tok.getString() == "mips4") {
2801 return parseSetFeature(Mips::FeatureMips4);
2802 } else if (Tok.getString() == "mips5") {
2803 return parseSetFeature(Mips::FeatureMips5);
2804 } else if (Tok.getString() == "mips32") {
2805 return parseSetFeature(Mips::FeatureMips32);
2806 } else if (Tok.getString() == "mips32r2") {
2807 return parseSetFeature(Mips::FeatureMips32r2);
2808 } else if (Tok.getString() == "mips32r6") {
2809 return parseSetFeature(Mips::FeatureMips32r6);
2810 } else if (Tok.getString() == "mips64") {
2811 return parseSetFeature(Mips::FeatureMips64);
2812 } else if (Tok.getString() == "mips64r2") {
2813 return parseSetFeature(Mips::FeatureMips64r2);
2814 } else if (Tok.getString() == "mips64r6") {
2815 return parseSetFeature(Mips::FeatureMips64r6);
2816 } else if (Tok.getString() == "dsp") {
2817 return parseSetFeature(Mips::FeatureDSP);
2818 } else if (Tok.getString() == "msa") {
2819 return parseSetMsaDirective();
2820 } else if (Tok.getString() == "nomsa") {
2821 return parseSetNoMsaDirective();
2823 // It is just an identifier, look for an assignment.
2824 parseSetAssignment();
2831 /// parseDataDirective
2832 /// ::= .word [ expression (, expression)* ]
2833 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2834 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2836 const MCExpr *Value;
2837 if (getParser().parseExpression(Value))
2840 getParser().getStreamer().EmitValue(Value, Size);
2842 if (getLexer().is(AsmToken::EndOfStatement))
2845 // FIXME: Improve diagnostic.
2846 if (getLexer().isNot(AsmToken::Comma))
2847 return Error(L, "unexpected token in directive");
2856 /// parseDirectiveGpWord
2857 /// ::= .gpword local_sym
2858 bool MipsAsmParser::parseDirectiveGpWord() {
2859 const MCExpr *Value;
2860 // EmitGPRel32Value requires an expression, so we are using base class
2861 // method to evaluate the expression.
2862 if (getParser().parseExpression(Value))
2864 getParser().getStreamer().EmitGPRel32Value(Value);
2866 if (getLexer().isNot(AsmToken::EndOfStatement))
2867 return Error(getLexer().getLoc(), "unexpected token in directive");
2868 Parser.Lex(); // Eat EndOfStatement token.
2872 /// parseDirectiveGpDWord
2873 /// ::= .gpdword local_sym
2874 bool MipsAsmParser::parseDirectiveGpDWord() {
2875 const MCExpr *Value;
2876 // EmitGPRel64Value requires an expression, so we are using base class
2877 // method to evaluate the expression.
2878 if (getParser().parseExpression(Value))
2880 getParser().getStreamer().EmitGPRel64Value(Value);
2882 if (getLexer().isNot(AsmToken::EndOfStatement))
2883 return Error(getLexer().getLoc(), "unexpected token in directive");
2884 Parser.Lex(); // Eat EndOfStatement token.
2888 bool MipsAsmParser::parseDirectiveOption() {
2889 // Get the option token.
2890 AsmToken Tok = Parser.getTok();
2891 // At the moment only identifiers are supported.
2892 if (Tok.isNot(AsmToken::Identifier)) {
2893 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2894 Parser.eatToEndOfStatement();
2898 StringRef Option = Tok.getIdentifier();
2900 if (Option == "pic0") {
2901 getTargetStreamer().emitDirectiveOptionPic0();
2903 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2904 Error(Parser.getTok().getLoc(),
2905 "unexpected token in .option pic0 directive");
2906 Parser.eatToEndOfStatement();
2911 if (Option == "pic2") {
2912 getTargetStreamer().emitDirectiveOptionPic2();
2914 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2915 Error(Parser.getTok().getLoc(),
2916 "unexpected token in .option pic2 directive");
2917 Parser.eatToEndOfStatement();
2923 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2924 Parser.eatToEndOfStatement();
2928 /// parseDirectiveModule
2929 /// ::= .module oddspreg
2930 /// ::= .module nooddspreg
2931 /// ::= .module fp=value
2932 bool MipsAsmParser::parseDirectiveModule() {
2933 MCAsmLexer &Lexer = getLexer();
2934 SMLoc L = Lexer.getLoc();
2936 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
2937 // TODO : get a better message.
2938 reportParseError(".module directive must appear before any code");
2942 if (Lexer.is(AsmToken::Identifier)) {
2943 StringRef Option = Parser.getTok().getString();
2946 if (Option == "oddspreg") {
2947 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
2948 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2950 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2951 reportParseError("Expected end of statement");
2956 } else if (Option == "nooddspreg") {
2958 Error(L, "'.module nooddspreg' requires the O32 ABI");
2962 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
2963 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2965 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2966 reportParseError("Expected end of statement");
2971 } else if (Option == "fp") {
2972 return parseDirectiveModuleFP();
2975 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
2981 /// parseDirectiveModuleFP
2985 bool MipsAsmParser::parseDirectiveModuleFP() {
2986 MCAsmLexer &Lexer = getLexer();
2988 if (Lexer.isNot(AsmToken::Equal)) {
2989 reportParseError("unexpected token in statement");
2992 Parser.Lex(); // Eat '=' token.
2994 MipsABIFlagsSection::FpABIKind FpABI;
2995 if (!parseFpABIValue(FpABI, ".module"))
2998 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2999 reportParseError("unexpected token in statement");
3003 // Emit appropriate flags.
3004 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3005 Parser.Lex(); // Consume the EndOfStatement.
3009 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3010 StringRef Directive) {
3011 MCAsmLexer &Lexer = getLexer();
3013 if (Lexer.is(AsmToken::Identifier)) {
3014 StringRef Value = Parser.getTok().getString();
3017 if (Value != "xx") {
3018 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3023 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3027 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3031 if (Lexer.is(AsmToken::Integer)) {
3032 unsigned Value = Parser.getTok().getIntVal();
3035 if (Value != 32 && Value != 64) {
3036 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3042 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3046 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3048 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3056 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3057 StringRef IDVal = DirectiveID.getString();
3059 if (IDVal == ".cpload")
3060 return parseDirectiveCPLoad(DirectiveID.getLoc());
3061 if (IDVal == ".dword") {
3062 parseDataDirective(8, DirectiveID.getLoc());
3065 if (IDVal == ".ent") {
3066 StringRef SymbolName;
3068 if (Parser.parseIdentifier(SymbolName)) {
3069 reportParseError("expected identifier after .ent");
3073 // There's an undocumented extension that allows an integer to
3074 // follow the name of the procedure which AFAICS is ignored by GAS.
3075 // Example: .ent foo,2
3076 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3077 if (getLexer().isNot(AsmToken::Comma)) {
3078 // Even though we accept this undocumented extension for compatibility
3079 // reasons, the additional integer argument does not actually change
3080 // the behaviour of the '.ent' directive, so we would like to discourage
3081 // its use. We do this by not referring to the extended version in
3082 // error messages which are not directly related to its use.
3083 reportParseError("unexpected token, expected end of statement");
3086 Parser.Lex(); // Eat the comma.
3087 const MCExpr *DummyNumber;
3088 int64_t DummyNumberVal;
3089 // If the user was explicitly trying to use the extended version,
3090 // we still give helpful extension-related error messages.
3091 if (Parser.parseExpression(DummyNumber)) {
3092 reportParseError("expected number after comma");
3095 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3096 reportParseError("expected an absolute expression after comma");
3101 // If this is not the end of the statement, report an error.
3102 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3103 reportParseError("unexpected token, expected end of statement");
3107 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3109 getTargetStreamer().emitDirectiveEnt(*Sym);
3114 if (IDVal == ".end") {
3115 StringRef SymbolName;
3117 if (Parser.parseIdentifier(SymbolName)) {
3118 reportParseError("expected identifier after .end");
3122 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3123 reportParseError("unexpected token, expected end of statement");
3127 if (CurrentFn == nullptr) {
3128 reportParseError(".end used without .ent");
3132 if ((SymbolName != CurrentFn->getName())) {
3133 reportParseError(".end symbol does not match .ent symbol");
3137 getTargetStreamer().emitDirectiveEnd(SymbolName);
3138 CurrentFn = nullptr;
3142 if (IDVal == ".frame") {
3143 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3144 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3145 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
3146 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3147 reportParseError("expected stack register");
3151 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3152 if (!StackRegOpnd.isGPRAsmReg()) {
3153 reportParseError(StackRegOpnd.getStartLoc(),
3154 "expected general purpose register");
3157 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3159 if (Parser.getTok().is(AsmToken::Comma))
3162 reportParseError("unexpected token, expected comma");
3166 // Parse the frame size.
3167 const MCExpr *FrameSize;
3168 int64_t FrameSizeVal;
3170 if (Parser.parseExpression(FrameSize)) {
3171 reportParseError("expected frame size value");
3175 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3176 reportParseError("frame size not an absolute expression");
3180 if (Parser.getTok().is(AsmToken::Comma))
3183 reportParseError("unexpected token, expected comma");
3187 // Parse the return register.
3189 ResTy = ParseAnyRegister(TmpReg);
3190 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3191 reportParseError("expected return register");
3195 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3196 if (!ReturnRegOpnd.isGPRAsmReg()) {
3197 reportParseError(ReturnRegOpnd.getStartLoc(),
3198 "expected general purpose register");
3202 // If this is not the end of the statement, report an error.
3203 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3204 reportParseError("unexpected token, expected end of statement");
3208 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3209 ReturnRegOpnd.getGPR32Reg());
3213 if (IDVal == ".set") {
3214 return parseDirectiveSet();
3217 if (IDVal == ".mask" || IDVal == ".fmask") {
3218 // .mask bitmask, frame_offset
3219 // bitmask: One bit for each register used.
3220 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3221 // first register is expected to be saved.
3223 // .mask 0x80000000, -4
3224 // .fmask 0x80000000, -4
3227 // Parse the bitmask
3228 const MCExpr *BitMask;
3231 if (Parser.parseExpression(BitMask)) {
3232 reportParseError("expected bitmask value");
3236 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3237 reportParseError("bitmask not an absolute expression");
3241 if (Parser.getTok().is(AsmToken::Comma))
3244 reportParseError("unexpected token, expected comma");
3248 // Parse the frame_offset
3249 const MCExpr *FrameOffset;
3250 int64_t FrameOffsetVal;
3252 if (Parser.parseExpression(FrameOffset)) {
3253 reportParseError("expected frame offset value");
3257 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3258 reportParseError("frame offset not an absolute expression");
3262 // If this is not the end of the statement, report an error.
3263 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3264 reportParseError("unexpected token, expected end of statement");
3268 if (IDVal == ".mask")
3269 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3271 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3275 if (IDVal == ".nan")
3276 return parseDirectiveNaN();
3278 if (IDVal == ".gpword") {
3279 parseDirectiveGpWord();
3283 if (IDVal == ".gpdword") {
3284 parseDirectiveGpDWord();
3288 if (IDVal == ".word") {
3289 parseDataDirective(4, DirectiveID.getLoc());
3293 if (IDVal == ".option")
3294 return parseDirectiveOption();
3296 if (IDVal == ".abicalls") {
3297 getTargetStreamer().emitDirectiveAbiCalls();
3298 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3299 Error(Parser.getTok().getLoc(), "unexpected token in directive");
3301 Parser.eatToEndOfStatement();
3306 if (IDVal == ".cpsetup")
3307 return parseDirectiveCPSetup();
3309 if (IDVal == ".module")
3310 return parseDirectiveModule();
3315 extern "C" void LLVMInitializeMipsAsmParser() {
3316 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3317 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3318 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3319 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3322 #define GET_REGISTER_MATCHER
3323 #define GET_MATCHER_IMPLEMENTATION
3324 #include "MipsGenAsmMatcher.inc"