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;
86 #define GET_ASSEMBLER_HEADER
87 #include "MipsGenAsmMatcher.inc"
89 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
91 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
92 OperandVector &Operands, MCStreamer &Out,
94 bool MatchingInlineAsm) override;
96 /// Parse a register as used in CFI directives
97 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
99 bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
101 bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
103 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
104 SMLoc NameLoc, OperandVector &Operands) override;
106 bool ParseDirective(AsmToken DirectiveID) override;
108 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
110 MipsAsmParser::OperandMatchResultTy
111 MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
112 StringRef Identifier, SMLoc S);
114 MipsAsmParser::OperandMatchResultTy
115 MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
117 MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
119 MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
121 MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
123 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
125 MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
127 bool searchSymbolAlias(OperandVector &Operands);
129 bool ParseOperand(OperandVector &, StringRef Mnemonic);
131 bool needsExpansion(MCInst &Inst);
133 // Expands assembly pseudo instructions.
134 // Returns false on success, true otherwise.
135 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
136 SmallVectorImpl<MCInst> &Instructions);
138 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
139 SmallVectorImpl<MCInst> &Instructions);
141 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
142 SmallVectorImpl<MCInst> &Instructions);
144 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
145 SmallVectorImpl<MCInst> &Instructions);
147 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
148 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
150 bool reportParseError(Twine ErrorMsg);
151 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
153 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
154 bool parseRelocOperand(const MCExpr *&Res);
156 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
158 bool isEvaluated(const MCExpr *Expr);
159 bool parseSetFeature(uint64_t Feature);
160 bool parseDirectiveCPLoad(SMLoc Loc);
161 bool parseDirectiveCPSetup();
162 bool parseDirectiveNaN();
163 bool parseDirectiveSet();
164 bool parseDirectiveOption();
166 bool parseSetAtDirective();
167 bool parseSetNoAtDirective();
168 bool parseSetMacroDirective();
169 bool parseSetNoMacroDirective();
170 bool parseSetMsaDirective();
171 bool parseSetNoMsaDirective();
172 bool parseSetReorderDirective();
173 bool parseSetNoReorderDirective();
174 bool parseSetNoMips16Directive();
175 bool parseSetFpDirective();
177 bool parseSetAssignment();
179 bool parseDataDirective(unsigned Size, SMLoc L);
180 bool parseDirectiveGpWord();
181 bool parseDirectiveGpDWord();
182 bool parseDirectiveModule();
183 bool parseDirectiveModuleFP();
184 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
185 StringRef Directive);
187 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
189 bool eatComma(StringRef ErrorStr);
191 int matchCPURegisterName(StringRef Symbol);
193 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
195 int matchFPURegisterName(StringRef Name);
197 int matchFCCRegisterName(StringRef Name);
199 int matchACRegisterName(StringRef Name);
201 int matchMSA128RegisterName(StringRef Name);
203 int matchMSA128CtrlRegisterName(StringRef Name);
205 unsigned getReg(int RC, int RegNo);
207 unsigned getGPR(int RegNo);
209 int getATReg(SMLoc Loc);
211 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
212 SmallVectorImpl<MCInst> &Instructions);
214 // Helper function that checks if the value of a vector index is within the
215 // boundaries of accepted values for each RegisterKind
216 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
217 bool validateMSAIndex(int Val, int RegKind);
219 // Selects a new architecture by updating the FeatureBits with the necessary
220 // info including implied dependencies.
221 // Internally, it clears all the feature bits related to *any* architecture
222 // and selects the new one using the ToggleFeature functionality of the
223 // MCSubtargetInfo object that handles implied dependencies. The reason we
224 // clear all the arch related bits manually is because ToggleFeature only
225 // clears the features that imply the feature being cleared and not the
226 // features implied by the feature being cleared. This is easier to see
228 // --------------------------------------------------
229 // | Feature | Implies |
230 // | -------------------------------------------------|
231 // | FeatureMips1 | None |
232 // | FeatureMips2 | FeatureMips1 |
233 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
234 // | FeatureMips4 | FeatureMips3 |
236 // --------------------------------------------------
238 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
239 // FeatureMipsGP64 | FeatureMips1)
240 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
241 void selectArch(StringRef ArchFeature) {
242 uint64_t FeatureBits = STI.getFeatureBits();
243 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
244 STI.setFeatureBits(FeatureBits);
245 setAvailableFeatures(
246 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
249 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
250 if (!(STI.getFeatureBits() & Feature)) {
251 setAvailableFeatures(
252 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
256 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
257 if (STI.getFeatureBits() & Feature) {
258 setAvailableFeatures(
259 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
264 enum MipsMatchResultTy {
265 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
266 #define GET_OPERAND_DIAGNOSTIC_TYPES
267 #include "MipsGenAsmMatcher.inc"
268 #undef GET_OPERAND_DIAGNOSTIC_TYPES
272 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
273 const MCInstrInfo &MII, const MCTargetOptions &Options)
274 : MCTargetAsmParser(), STI(sti), Parser(parser) {
275 // Initialize the set of available features.
276 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
278 getTargetStreamer().updateABIInfo(*this);
280 // Assert exactly one ABI was chosen.
281 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
282 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
283 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
284 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
286 if (!isABI_O32() && !useOddSPReg() != 0)
287 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
290 MCAsmParser &getParser() const { return Parser; }
291 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
293 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
294 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
296 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
297 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
298 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
299 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
300 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
301 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
303 bool useOddSPReg() const {
304 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
307 bool inMicroMipsMode() const {
308 return STI.getFeatureBits() & Mips::FeatureMicroMips;
310 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
311 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
312 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
313 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
314 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
315 bool hasMips32() const {
316 return (STI.getFeatureBits() & Mips::FeatureMips32);
318 bool hasMips64() const {
319 return (STI.getFeatureBits() & Mips::FeatureMips64);
321 bool hasMips32r2() const {
322 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
324 bool hasMips64r2() const {
325 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
327 bool hasMips32r6() const {
328 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
330 bool hasMips64r6() const {
331 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
333 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
334 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
335 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
337 bool inMips16Mode() const {
338 return STI.getFeatureBits() & Mips::FeatureMips16;
340 // TODO: see how can we get this info.
341 bool abiUsesSoftFloat() const { return false; }
343 /// Warn if RegNo is the current assembler temporary.
344 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
350 /// MipsOperand - Instances of this class represent a parsed Mips machine
352 class MipsOperand : public MCParsedAsmOperand {
354 /// Broad categories of register classes
355 /// The exact class is finalized by the render method.
357 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
358 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
360 RegKind_FCC = 4, /// FCC
361 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
362 RegKind_MSACtrl = 16, /// MSA control registers
363 RegKind_COP2 = 32, /// COP2
364 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
366 RegKind_CCR = 128, /// CCR
367 RegKind_HWRegs = 256, /// HWRegs
368 RegKind_COP3 = 512, /// COP3
370 /// Potentially any (e.g. $1)
371 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
372 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
373 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
378 k_Immediate, /// An immediate (possibly involving symbol references)
379 k_Memory, /// Base + Offset Memory Address
380 k_PhysRegister, /// A physical register from the Mips namespace
381 k_RegisterIndex, /// A register index in one or more RegKind.
382 k_Token /// A simple token
386 MipsOperand(KindTy K, MipsAsmParser &Parser)
387 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
390 /// For diagnostics, and checking the assembler temporary
391 MipsAsmParser &AsmParser;
399 unsigned Num; /// Register Number
403 unsigned Index; /// Index into the register class
404 RegKind Kind; /// Bitfield of the kinds it could possibly be
405 const MCRegisterInfo *RegInfo;
419 struct PhysRegOp PhysReg;
420 struct RegIdxOp RegIdx;
425 SMLoc StartLoc, EndLoc;
427 /// Internal constructor for register kinds
428 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
429 const MCRegisterInfo *RegInfo,
431 MipsAsmParser &Parser) {
432 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
433 Op->RegIdx.Index = Index;
434 Op->RegIdx.RegInfo = RegInfo;
435 Op->RegIdx.Kind = RegKind;
442 /// Coerce the register to GPR32 and return the real register for the current
444 unsigned getGPR32Reg() const {
445 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
446 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
447 unsigned ClassID = Mips::GPR32RegClassID;
448 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
451 /// Coerce the register to GPR64 and return the real register for the current
453 unsigned getGPR64Reg() const {
454 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
455 unsigned ClassID = Mips::GPR64RegClassID;
456 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
460 /// Coerce the register to AFGR64 and return the real register for the current
462 unsigned getAFGR64Reg() const {
463 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
464 if (RegIdx.Index % 2 != 0)
465 AsmParser.Warning(StartLoc, "Float register should be even.");
466 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
467 .getRegister(RegIdx.Index / 2);
470 /// Coerce the register to FGR64 and return the real register for the current
472 unsigned getFGR64Reg() const {
473 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
474 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
475 .getRegister(RegIdx.Index);
478 /// Coerce the register to FGR32 and return the real register for the current
480 unsigned getFGR32Reg() const {
481 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
482 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
483 .getRegister(RegIdx.Index);
486 /// Coerce the register to FGRH32 and return the real register for the current
488 unsigned getFGRH32Reg() const {
489 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
490 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
491 .getRegister(RegIdx.Index);
494 /// Coerce the register to FCC and return the real register for the current
496 unsigned getFCCReg() const {
497 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
498 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
499 .getRegister(RegIdx.Index);
502 /// Coerce the register to MSA128 and return the real register for the current
504 unsigned getMSA128Reg() const {
505 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
506 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
508 unsigned ClassID = Mips::MSA128BRegClassID;
509 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
512 /// Coerce the register to MSACtrl and return the real register for the
514 unsigned getMSACtrlReg() const {
515 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
516 unsigned ClassID = Mips::MSACtrlRegClassID;
517 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
520 /// Coerce the register to COP2 and return the real register for the
522 unsigned getCOP2Reg() const {
523 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
524 unsigned ClassID = Mips::COP2RegClassID;
525 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
528 /// Coerce the register to COP3 and return the real register for the
530 unsigned getCOP3Reg() const {
531 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
532 unsigned ClassID = Mips::COP3RegClassID;
533 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
536 /// Coerce the register to ACC64DSP and return the real register for the
538 unsigned getACC64DSPReg() const {
539 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
540 unsigned ClassID = Mips::ACC64DSPRegClassID;
541 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
544 /// Coerce the register to HI32DSP and return the real register for the
546 unsigned getHI32DSPReg() const {
547 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
548 unsigned ClassID = Mips::HI32DSPRegClassID;
549 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
552 /// Coerce the register to LO32DSP and return the real register for the
554 unsigned getLO32DSPReg() const {
555 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
556 unsigned ClassID = Mips::LO32DSPRegClassID;
557 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
560 /// Coerce the register to CCR and return the real register for the
562 unsigned getCCRReg() const {
563 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
564 unsigned ClassID = Mips::CCRRegClassID;
565 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
568 /// Coerce the register to HWRegs and return the real register for the
570 unsigned getHWRegsReg() const {
571 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
572 unsigned ClassID = Mips::HWRegsRegClassID;
573 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
577 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
578 // Add as immediate when possible. Null MCExpr = 0.
580 Inst.addOperand(MCOperand::CreateImm(0));
581 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
582 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
584 Inst.addOperand(MCOperand::CreateExpr(Expr));
587 void addRegOperands(MCInst &Inst, unsigned N) const {
588 llvm_unreachable("Use a custom parser instead");
591 /// Render the operand to an MCInst as a GPR32
592 /// Asserts if the wrong number of operands are requested, or the operand
593 /// is not a k_RegisterIndex compatible with RegKind_GPR
594 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
595 assert(N == 1 && "Invalid number of operands!");
596 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
599 /// Render the operand to an MCInst as a GPR64
600 /// Asserts if the wrong number of operands are requested, or the operand
601 /// is not a k_RegisterIndex compatible with RegKind_GPR
602 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
603 assert(N == 1 && "Invalid number of operands!");
604 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
607 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
608 assert(N == 1 && "Invalid number of operands!");
609 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
612 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
613 assert(N == 1 && "Invalid number of operands!");
614 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
617 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
618 assert(N == 1 && "Invalid number of operands!");
619 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
620 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
621 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
622 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
626 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
627 assert(N == 1 && "Invalid number of operands!");
628 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
631 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
632 assert(N == 1 && "Invalid number of operands!");
633 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
636 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
637 assert(N == 1 && "Invalid number of operands!");
638 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
641 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
642 assert(N == 1 && "Invalid number of operands!");
643 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
646 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
647 assert(N == 1 && "Invalid number of operands!");
648 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
651 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
652 assert(N == 1 && "Invalid number of operands!");
653 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
656 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
661 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
662 assert(N == 1 && "Invalid number of operands!");
663 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
666 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
667 assert(N == 1 && "Invalid number of operands!");
668 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
671 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
672 assert(N == 1 && "Invalid number of operands!");
673 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
676 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
677 assert(N == 1 && "Invalid number of operands!");
678 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
681 void addImmOperands(MCInst &Inst, unsigned N) const {
682 assert(N == 1 && "Invalid number of operands!");
683 const MCExpr *Expr = getImm();
687 void addMemOperands(MCInst &Inst, unsigned N) const {
688 assert(N == 2 && "Invalid number of operands!");
690 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
692 const MCExpr *Expr = getMemOff();
696 bool isReg() const override {
697 // As a special case until we sort out the definition of div/divu, pretend
698 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
699 if (isGPRAsmReg() && RegIdx.Index == 0)
702 return Kind == k_PhysRegister;
704 bool isRegIdx() const { return Kind == k_RegisterIndex; }
705 bool isImm() const override { return Kind == k_Immediate; }
706 bool isConstantImm() const {
707 return isImm() && dyn_cast<MCConstantExpr>(getImm());
709 bool isToken() const override {
710 // Note: It's not possible to pretend that other operand kinds are tokens.
711 // The matcher emitter checks tokens first.
712 return Kind == k_Token;
714 bool isMem() const override { return Kind == k_Memory; }
715 bool isConstantMemOff() const {
716 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
718 template <unsigned Bits> bool isMemWithSimmOffset() const {
719 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
721 bool isInvNum() const { return Kind == k_Immediate; }
722 bool isLSAImm() const {
723 if (!isConstantImm())
725 int64_t Val = getConstantImm();
726 return 1 <= Val && Val <= 4;
729 StringRef getToken() const {
730 assert(Kind == k_Token && "Invalid access!");
731 return StringRef(Tok.Data, Tok.Length);
734 unsigned getReg() const override {
735 // As a special case until we sort out the definition of div/divu, pretend
736 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
737 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
738 RegIdx.Kind & RegKind_GPR)
739 return getGPR32Reg(); // FIXME: GPR64 too
741 assert(Kind == k_PhysRegister && "Invalid access!");
745 const MCExpr *getImm() const {
746 assert((Kind == k_Immediate) && "Invalid access!");
750 int64_t getConstantImm() const {
751 const MCExpr *Val = getImm();
752 return static_cast<const MCConstantExpr *>(Val)->getValue();
755 MipsOperand *getMemBase() const {
756 assert((Kind == k_Memory) && "Invalid access!");
760 const MCExpr *getMemOff() const {
761 assert((Kind == k_Memory) && "Invalid access!");
765 int64_t getConstantMemOff() const {
766 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
769 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
770 MipsAsmParser &Parser) {
771 auto Op = make_unique<MipsOperand>(k_Token, Parser);
772 Op->Tok.Data = Str.data();
773 Op->Tok.Length = Str.size();
779 /// Create a numeric register (e.g. $1). The exact register remains
780 /// unresolved until an instruction successfully matches
781 static std::unique_ptr<MipsOperand>
782 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
783 SMLoc E, MipsAsmParser &Parser) {
784 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
785 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
788 /// Create a register that is definitely a GPR.
789 /// This is typically only used for named registers such as $gp.
790 static std::unique_ptr<MipsOperand>
791 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
792 MipsAsmParser &Parser) {
793 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
796 /// Create a register that is definitely a FGR.
797 /// This is typically only used for named registers such as $f0.
798 static std::unique_ptr<MipsOperand>
799 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
800 MipsAsmParser &Parser) {
801 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
804 /// Create a register that is definitely an FCC.
805 /// This is typically only used for named registers such as $fcc0.
806 static std::unique_ptr<MipsOperand>
807 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
808 MipsAsmParser &Parser) {
809 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
812 /// Create a register that is definitely an ACC.
813 /// This is typically only used for named registers such as $ac0.
814 static std::unique_ptr<MipsOperand>
815 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
816 MipsAsmParser &Parser) {
817 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
820 /// Create a register that is definitely an MSA128.
821 /// This is typically only used for named registers such as $w0.
822 static std::unique_ptr<MipsOperand>
823 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
824 SMLoc E, MipsAsmParser &Parser) {
825 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
828 /// Create a register that is definitely an MSACtrl.
829 /// This is typically only used for named registers such as $msaaccess.
830 static std::unique_ptr<MipsOperand>
831 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
832 SMLoc E, MipsAsmParser &Parser) {
833 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
836 static std::unique_ptr<MipsOperand>
837 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
838 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
845 static std::unique_ptr<MipsOperand>
846 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
847 SMLoc E, MipsAsmParser &Parser) {
848 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
849 Op->Mem.Base = Base.release();
856 bool isGPRAsmReg() const {
857 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
859 bool isFGRAsmReg() const {
860 // AFGR64 is $0-$15 but we handle this in getAFGR64()
861 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
863 bool isHWRegsAsmReg() const {
864 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
866 bool isCCRAsmReg() const {
867 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
869 bool isFCCAsmReg() const {
870 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
872 if (!AsmParser.hasEightFccRegisters())
873 return RegIdx.Index == 0;
874 return RegIdx.Index <= 7;
876 bool isACCAsmReg() const {
877 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
879 bool isCOP2AsmReg() const {
880 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
882 bool isCOP3AsmReg() const {
883 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
885 bool isMSA128AsmReg() const {
886 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
888 bool isMSACtrlAsmReg() const {
889 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
892 /// getStartLoc - Get the location of the first token of this operand.
893 SMLoc getStartLoc() const override { return StartLoc; }
894 /// getEndLoc - Get the location of the last token of this operand.
895 SMLoc getEndLoc() const override { return EndLoc; }
897 virtual ~MipsOperand() {
905 case k_RegisterIndex:
911 void print(raw_ostream &OS) const override {
926 OS << "PhysReg<" << PhysReg.Num << ">";
928 case k_RegisterIndex:
929 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
936 }; // class MipsOperand
940 extern const MCInstrDesc MipsInsts[];
942 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
943 return MipsInsts[Opcode];
946 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
947 SmallVectorImpl<MCInst> &Instructions) {
948 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
952 if (MCID.isBranch() || MCID.isCall()) {
953 const unsigned Opcode = Inst.getOpcode();
963 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
964 Offset = Inst.getOperand(2);
966 break; // We'll deal with this situation later on when applying fixups.
967 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
968 return Error(IDLoc, "branch target out of range");
969 if (OffsetToAlignment(Offset.getImm(),
970 1LL << (inMicroMipsMode() ? 1 : 2)))
971 return Error(IDLoc, "branch to misaligned address");
985 case Mips::BGEZAL_MM:
986 case Mips::BLTZAL_MM:
989 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
990 Offset = Inst.getOperand(1);
992 break; // We'll deal with this situation later on when applying fixups.
993 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
994 return Error(IDLoc, "branch target out of range");
995 if (OffsetToAlignment(Offset.getImm(),
996 1LL << (inMicroMipsMode() ? 1 : 2)))
997 return Error(IDLoc, "branch to misaligned address");
1002 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1003 // We still accept it but it is a normal nop.
1004 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1005 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1006 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1010 if (MCID.hasDelaySlot() && Options.isReorder()) {
1011 // If this instruction has a delay slot and .set reorder is active,
1012 // emit a NOP after it.
1013 Instructions.push_back(Inst);
1015 NopInst.setOpcode(Mips::SLL);
1016 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1017 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1018 NopInst.addOperand(MCOperand::CreateImm(0));
1019 Instructions.push_back(NopInst);
1023 if (MCID.mayLoad() || MCID.mayStore()) {
1024 // Check the offset of memory operand, if it is a symbol
1025 // reference or immediate we may have to expand instructions.
1026 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1027 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1028 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1029 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1030 MCOperand &Op = Inst.getOperand(i);
1032 int MemOffset = Op.getImm();
1033 if (MemOffset < -32768 || MemOffset > 32767) {
1034 // Offset can't exceed 16bit value.
1035 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1038 } else if (Op.isExpr()) {
1039 const MCExpr *Expr = Op.getExpr();
1040 if (Expr->getKind() == MCExpr::SymbolRef) {
1041 const MCSymbolRefExpr *SR =
1042 static_cast<const MCSymbolRefExpr *>(Expr);
1043 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1045 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1048 } else if (!isEvaluated(Expr)) {
1049 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1057 if (needsExpansion(Inst))
1058 return expandInstruction(Inst, IDLoc, Instructions);
1060 Instructions.push_back(Inst);
1065 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1067 switch (Inst.getOpcode()) {
1068 case Mips::LoadImm32Reg:
1069 case Mips::LoadAddr32Imm:
1070 case Mips::LoadAddr32Reg:
1071 case Mips::LoadImm64Reg:
1078 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1079 SmallVectorImpl<MCInst> &Instructions) {
1080 switch (Inst.getOpcode()) {
1082 assert(0 && "unimplemented expansion");
1084 case Mips::LoadImm32Reg:
1085 return expandLoadImm(Inst, IDLoc, Instructions);
1086 case Mips::LoadImm64Reg:
1088 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1091 return expandLoadImm(Inst, IDLoc, Instructions);
1092 case Mips::LoadAddr32Imm:
1093 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1094 case Mips::LoadAddr32Reg:
1095 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1100 template <int Shift, bool PerformShift>
1101 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1102 SmallVectorImpl<MCInst> &Instructions) {
1105 tmpInst.setOpcode(Mips::DSLL);
1106 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1107 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1108 tmpInst.addOperand(MCOperand::CreateImm(16));
1109 tmpInst.setLoc(IDLoc);
1110 Instructions.push_back(tmpInst);
1113 tmpInst.setOpcode(Mips::ORi);
1114 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1115 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1117 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)));
1118 tmpInst.setLoc(IDLoc);
1119 Instructions.push_back(tmpInst);
1123 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1124 SmallVectorImpl<MCInst> &Instructions) {
1126 const MCOperand &ImmOp = Inst.getOperand(1);
1127 assert(ImmOp.isImm() && "expected immediate operand kind");
1128 const MCOperand &RegOp = Inst.getOperand(0);
1129 assert(RegOp.isReg() && "expected register operand kind");
1131 int64_t ImmValue = ImmOp.getImm();
1132 tmpInst.setLoc(IDLoc);
1133 // FIXME: gas has a special case for values that are 000...1111, which
1134 // becomes a li -1 and then a dsrl
1135 if (0 <= ImmValue && ImmValue <= 65535) {
1136 // For 0 <= j <= 65535.
1137 // li d,j => ori d,$zero,j
1138 tmpInst.setOpcode(Mips::ORi);
1139 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1140 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1141 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1142 Instructions.push_back(tmpInst);
1143 } else if (ImmValue < 0 && ImmValue >= -32768) {
1144 // For -32768 <= j < 0.
1145 // li d,j => addiu d,$zero,j
1146 tmpInst.setOpcode(Mips::ADDiu);
1147 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1148 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1149 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1150 Instructions.push_back(tmpInst);
1151 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1152 // For any value of j that is representable as a 32-bit integer, create
1154 // li d,j => lui d,hi16(j)
1156 tmpInst.setOpcode(Mips::LUi);
1157 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1158 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1159 Instructions.push_back(tmpInst);
1160 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1161 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1163 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1167 // <------- lo32 ------>
1168 // <------- hi32 ------>
1169 // <- hi16 -> <- lo16 ->
1170 // _________________________________
1172 // | 16-bytes | 16-bytes | 16-bytes |
1173 // |__________|__________|__________|
1175 // For any value of j that is representable as a 48-bit integer, create
1177 // li d,j => lui d,hi16(j)
1178 // ori d,d,hi16(lo32(j))
1180 // ori d,d,lo16(lo32(j))
1181 tmpInst.setOpcode(Mips::LUi);
1182 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1184 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1185 Instructions.push_back(tmpInst);
1186 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1187 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1190 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1194 // <------- hi32 ------> <------- lo32 ------>
1195 // <- hi16 -> <- lo16 ->
1196 // ___________________________________________
1198 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1199 // |__________|__________|__________|__________|
1201 // For any value of j that isn't representable as a 48-bit integer.
1202 // li d,j => lui d,hi16(j)
1203 // ori d,d,lo16(hi32(j))
1205 // ori d,d,hi16(lo32(j))
1207 // ori d,d,lo16(lo32(j))
1208 tmpInst.setOpcode(Mips::LUi);
1209 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1211 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1212 Instructions.push_back(tmpInst);
1213 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1214 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1215 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1221 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1222 SmallVectorImpl<MCInst> &Instructions) {
1224 const MCOperand &ImmOp = Inst.getOperand(2);
1225 assert(ImmOp.isImm() && "expected immediate operand kind");
1226 const MCOperand &SrcRegOp = Inst.getOperand(1);
1227 assert(SrcRegOp.isReg() && "expected register operand kind");
1228 const MCOperand &DstRegOp = Inst.getOperand(0);
1229 assert(DstRegOp.isReg() && "expected register operand kind");
1230 int ImmValue = ImmOp.getImm();
1231 if (-32768 <= ImmValue && ImmValue <= 65535) {
1232 // For -32768 <= j <= 65535.
1233 // la d,j(s) => addiu d,s,j
1234 tmpInst.setOpcode(Mips::ADDiu);
1235 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1236 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1237 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1238 Instructions.push_back(tmpInst);
1240 // For any other value of j that is representable as a 32-bit integer.
1241 // la d,j(s) => lui d,hi16(j)
1244 tmpInst.setOpcode(Mips::LUi);
1245 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1246 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1247 Instructions.push_back(tmpInst);
1249 tmpInst.setOpcode(Mips::ORi);
1250 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1251 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1252 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1253 Instructions.push_back(tmpInst);
1255 tmpInst.setOpcode(Mips::ADDu);
1256 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1257 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1258 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1259 Instructions.push_back(tmpInst);
1265 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1266 SmallVectorImpl<MCInst> &Instructions) {
1268 const MCOperand &ImmOp = Inst.getOperand(1);
1269 assert(ImmOp.isImm() && "expected immediate operand kind");
1270 const MCOperand &RegOp = Inst.getOperand(0);
1271 assert(RegOp.isReg() && "expected register operand kind");
1272 int ImmValue = ImmOp.getImm();
1273 if (-32768 <= ImmValue && ImmValue <= 65535) {
1274 // For -32768 <= j <= 65535.
1275 // la d,j => addiu d,$zero,j
1276 tmpInst.setOpcode(Mips::ADDiu);
1277 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1278 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1279 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1280 Instructions.push_back(tmpInst);
1282 // For any other value of j that is representable as a 32-bit integer.
1283 // la d,j => lui d,hi16(j)
1285 tmpInst.setOpcode(Mips::LUi);
1286 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1287 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1288 Instructions.push_back(tmpInst);
1290 tmpInst.setOpcode(Mips::ORi);
1291 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1292 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1293 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1294 Instructions.push_back(tmpInst);
1299 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1300 SmallVectorImpl<MCInst> &Instructions,
1301 bool isLoad, bool isImmOpnd) {
1302 const MCSymbolRefExpr *SR;
1304 unsigned ImmOffset, HiOffset, LoOffset;
1305 const MCExpr *ExprOffset;
1307 // 1st operand is either the source or destination register.
1308 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1309 unsigned RegOpNum = Inst.getOperand(0).getReg();
1310 // 2nd operand is the base register.
1311 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1312 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1313 // 3rd operand is either an immediate or expression.
1315 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1316 ImmOffset = Inst.getOperand(2).getImm();
1317 LoOffset = ImmOffset & 0x0000ffff;
1318 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1319 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1320 if (LoOffset & 0x8000)
1323 ExprOffset = Inst.getOperand(2).getExpr();
1324 // All instructions will have the same location.
1325 TempInst.setLoc(IDLoc);
1326 // These are some of the types of expansions we perform here:
1327 // 1) lw $8, sym => lui $8, %hi(sym)
1328 // lw $8, %lo(sym)($8)
1329 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1331 // lw $8, %lo(offset)($9)
1332 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1334 // lw $8, %lo(offset)($at)
1335 // 4) sw $8, sym => lui $at, %hi(sym)
1336 // sw $8, %lo(sym)($at)
1337 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1339 // sw $8, %lo(offset)($at)
1340 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1341 // ldc1 $f0, %lo(sym)($at)
1343 // For load instructions we can use the destination register as a temporary
1344 // if base and dst are different (examples 1 and 2) and if the base register
1345 // is general purpose otherwise we must use $at (example 6) and error if it's
1346 // not available. For stores we must use $at (examples 4 and 5) because we
1347 // must not clobber the source register setting up the offset.
1348 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1349 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1350 unsigned RegClassIDOp0 =
1351 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1352 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1353 (RegClassIDOp0 == Mips::GPR64RegClassID);
1354 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1355 TmpRegNum = RegOpNum;
1357 int AT = getATReg(IDLoc);
1358 // At this point we need AT to perform the expansions and we exit if it is
1363 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1366 TempInst.setOpcode(Mips::LUi);
1367 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1369 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1371 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1372 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1373 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1374 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1376 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1378 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1379 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1382 // Add the instruction to the list.
1383 Instructions.push_back(TempInst);
1384 // Prepare TempInst for next instruction.
1386 // Add temp register to base.
1387 TempInst.setOpcode(Mips::ADDu);
1388 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1389 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1390 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1391 Instructions.push_back(TempInst);
1393 // And finally, create original instruction with low part
1394 // of offset and new base.
1395 TempInst.setOpcode(Inst.getOpcode());
1396 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1397 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1399 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1401 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1402 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1403 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1405 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1407 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1408 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1411 Instructions.push_back(TempInst);
1415 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1416 // As described by the Mips32r2 spec, the registers Rd and Rs for
1417 // jalr.hb must be different.
1418 unsigned Opcode = Inst.getOpcode();
1420 if (Opcode == Mips::JALR_HB &&
1421 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1422 return Match_RequiresDifferentSrcAndDst;
1424 return Match_Success;
1427 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1428 OperandVector &Operands,
1430 unsigned &ErrorInfo,
1431 bool MatchingInlineAsm) {
1434 SmallVector<MCInst, 8> Instructions;
1435 unsigned MatchResult =
1436 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1438 switch (MatchResult) {
1441 case Match_Success: {
1442 if (processInstruction(Inst, IDLoc, Instructions))
1444 for (unsigned i = 0; i < Instructions.size(); i++)
1445 Out.EmitInstruction(Instructions[i], STI);
1448 case Match_MissingFeature:
1449 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1451 case Match_InvalidOperand: {
1452 SMLoc ErrorLoc = IDLoc;
1453 if (ErrorInfo != ~0U) {
1454 if (ErrorInfo >= Operands.size())
1455 return Error(IDLoc, "too few operands for instruction");
1457 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1458 if (ErrorLoc == SMLoc())
1462 return Error(ErrorLoc, "invalid operand for instruction");
1464 case Match_MnemonicFail:
1465 return Error(IDLoc, "invalid instruction");
1466 case Match_RequiresDifferentSrcAndDst:
1467 return Error(IDLoc, "source and destination must be different");
1472 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1473 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1475 Warning(Loc, "Used $at without \".set noat\"");
1477 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1478 Twine(RegIndex) + "\"");
1482 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1485 CC = StringSwitch<unsigned>(Name)
1521 if (isABI_N32() || isABI_N64()) {
1522 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1523 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1524 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1525 if (8 <= CC && CC <= 11)
1529 CC = StringSwitch<unsigned>(Name)
1542 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1544 if (Name[0] == 'f') {
1545 StringRef NumString = Name.substr(1);
1547 if (NumString.getAsInteger(10, IntVal))
1548 return -1; // This is not an integer.
1549 if (IntVal > 31) // Maximum index for fpu register.
1556 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1558 if (Name.startswith("fcc")) {
1559 StringRef NumString = Name.substr(3);
1561 if (NumString.getAsInteger(10, IntVal))
1562 return -1; // This is not an integer.
1563 if (IntVal > 7) // There are only 8 fcc registers.
1570 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1572 if (Name.startswith("ac")) {
1573 StringRef NumString = Name.substr(2);
1575 if (NumString.getAsInteger(10, IntVal))
1576 return -1; // This is not an integer.
1577 if (IntVal > 3) // There are only 3 acc registers.
1584 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1587 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1596 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1599 CC = StringSwitch<unsigned>(Name)
1602 .Case("msaaccess", 2)
1604 .Case("msamodify", 4)
1605 .Case("msarequest", 5)
1607 .Case("msaunmap", 7)
1613 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1621 int MipsAsmParser::getATReg(SMLoc Loc) {
1622 int AT = Options.getATRegNum();
1624 reportParseError(Loc,
1625 "Pseudo instruction requires $at, which is not available");
1629 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1630 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1633 unsigned MipsAsmParser::getGPR(int RegNo) {
1634 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1638 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1640 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1643 return getReg(RegClass, RegNum);
1646 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1647 DEBUG(dbgs() << "ParseOperand\n");
1649 // Check if the current operand has a custom associated parser, if so, try to
1650 // custom parse the operand, or fallback to the general approach.
1651 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1652 if (ResTy == MatchOperand_Success)
1654 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1655 // there was a match, but an error occurred, in which case, just return that
1656 // the operand parsing failed.
1657 if (ResTy == MatchOperand_ParseFail)
1660 DEBUG(dbgs() << ".. Generic Parser\n");
1662 switch (getLexer().getKind()) {
1664 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1666 case AsmToken::Dollar: {
1667 // Parse the register.
1668 SMLoc S = Parser.getTok().getLoc();
1670 // Almost all registers have been parsed by custom parsers. There is only
1671 // one exception to this. $zero (and it's alias $0) will reach this point
1672 // for div, divu, and similar instructions because it is not an operand
1673 // to the instruction definition but an explicit register. Special case
1674 // this situation for now.
1675 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1678 // Maybe it is a symbol reference.
1679 StringRef Identifier;
1680 if (Parser.parseIdentifier(Identifier))
1683 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1684 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1685 // Otherwise create a symbol reference.
1687 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1689 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1692 // Else drop to expression parsing.
1693 case AsmToken::LParen:
1694 case AsmToken::Minus:
1695 case AsmToken::Plus:
1696 case AsmToken::Integer:
1697 case AsmToken::Tilde:
1698 case AsmToken::String: {
1699 DEBUG(dbgs() << ".. generic integer\n");
1700 OperandMatchResultTy ResTy = ParseImm(Operands);
1701 return ResTy != MatchOperand_Success;
1703 case AsmToken::Percent: {
1704 // It is a symbol reference or constant expression.
1705 const MCExpr *IdVal;
1706 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1707 if (parseRelocOperand(IdVal))
1710 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1712 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1714 } // case AsmToken::Percent
1715 } // switch(getLexer().getKind())
1719 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1720 StringRef RelocStr) {
1722 // Check the type of the expression.
1723 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1724 // It's a constant, evaluate reloc value.
1726 switch (getVariantKind(RelocStr)) {
1727 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1728 // Get the 1st 16-bits.
1729 Val = MCE->getValue() & 0xffff;
1731 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1732 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1733 // 16 bits being negative.
1734 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1736 case MCSymbolRefExpr::VK_Mips_HIGHER:
1737 // Get the 3rd 16-bits.
1738 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1740 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1741 // Get the 4th 16-bits.
1742 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1745 report_fatal_error("Unsupported reloc value!");
1747 return MCConstantExpr::Create(Val, getContext());
1750 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1751 // It's a symbol, create a symbolic expression from the symbol.
1752 StringRef Symbol = MSRE->getSymbol().getName();
1753 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1754 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1758 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1759 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1761 // Try to create target expression.
1762 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1763 return MipsMCExpr::Create(VK, Expr, getContext());
1765 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1766 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1767 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1771 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1772 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1773 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1776 // Just return the original expression.
1780 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1782 switch (Expr->getKind()) {
1783 case MCExpr::Constant:
1785 case MCExpr::SymbolRef:
1786 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1787 case MCExpr::Binary:
1788 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1789 if (!isEvaluated(BE->getLHS()))
1791 return isEvaluated(BE->getRHS());
1794 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1795 case MCExpr::Target:
1801 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1802 Parser.Lex(); // Eat the % token.
1803 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1804 if (Tok.isNot(AsmToken::Identifier))
1807 std::string Str = Tok.getIdentifier().str();
1809 Parser.Lex(); // Eat the identifier.
1810 // Now make an expression from the rest of the operand.
1811 const MCExpr *IdVal;
1814 if (getLexer().getKind() == AsmToken::LParen) {
1816 Parser.Lex(); // Eat the '(' token.
1817 if (getLexer().getKind() == AsmToken::Percent) {
1818 Parser.Lex(); // Eat the % token.
1819 const AsmToken &nextTok = Parser.getTok();
1820 if (nextTok.isNot(AsmToken::Identifier))
1823 Str += nextTok.getIdentifier();
1824 Parser.Lex(); // Eat the identifier.
1825 if (getLexer().getKind() != AsmToken::LParen)
1830 if (getParser().parseParenExpression(IdVal, EndLoc))
1833 while (getLexer().getKind() == AsmToken::RParen)
1834 Parser.Lex(); // Eat the ')' token.
1837 return true; // Parenthesis must follow the relocation operand.
1839 Res = evaluateRelocExpr(IdVal, Str);
1843 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1845 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1846 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1847 if (ResTy == MatchOperand_Success) {
1848 assert(Operands.size() == 1);
1849 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1850 StartLoc = Operand.getStartLoc();
1851 EndLoc = Operand.getEndLoc();
1853 // AFAIK, we only support numeric registers and named GPR's in CFI
1855 // Don't worry about eating tokens before failing. Using an unrecognised
1856 // register is a parse error.
1857 if (Operand.isGPRAsmReg()) {
1858 // Resolve to GPR32 or GPR64 appropriately.
1859 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1862 return (RegNo == (unsigned)-1);
1865 assert(Operands.size() == 0);
1866 return (RegNo == (unsigned)-1);
1869 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1873 while (getLexer().getKind() == AsmToken::LParen)
1876 switch (getLexer().getKind()) {
1879 case AsmToken::Identifier:
1880 case AsmToken::LParen:
1881 case AsmToken::Integer:
1882 case AsmToken::Minus:
1883 case AsmToken::Plus:
1885 Result = getParser().parseParenExpression(Res, S);
1887 Result = (getParser().parseExpression(Res));
1888 while (getLexer().getKind() == AsmToken::RParen)
1891 case AsmToken::Percent:
1892 Result = parseRelocOperand(Res);
1897 MipsAsmParser::OperandMatchResultTy
1898 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1899 DEBUG(dbgs() << "parseMemOperand\n");
1900 const MCExpr *IdVal = nullptr;
1902 bool isParenExpr = false;
1903 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1904 // First operand is the offset.
1905 S = Parser.getTok().getLoc();
1907 if (getLexer().getKind() == AsmToken::LParen) {
1912 if (getLexer().getKind() != AsmToken::Dollar) {
1913 if (parseMemOffset(IdVal, isParenExpr))
1914 return MatchOperand_ParseFail;
1916 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1917 if (Tok.isNot(AsmToken::LParen)) {
1918 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
1919 if (Mnemonic.getToken() == "la") {
1921 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1922 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1923 return MatchOperand_Success;
1925 if (Tok.is(AsmToken::EndOfStatement)) {
1927 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1929 // Zero register assumed, add a memory operand with ZERO as its base.
1930 // "Base" will be managed by k_Memory.
1931 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
1934 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
1935 return MatchOperand_Success;
1937 Error(Parser.getTok().getLoc(), "'(' expected");
1938 return MatchOperand_ParseFail;
1941 Parser.Lex(); // Eat the '(' token.
1944 Res = ParseAnyRegister(Operands);
1945 if (Res != MatchOperand_Success)
1948 if (Parser.getTok().isNot(AsmToken::RParen)) {
1949 Error(Parser.getTok().getLoc(), "')' expected");
1950 return MatchOperand_ParseFail;
1953 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1955 Parser.Lex(); // Eat the ')' token.
1958 IdVal = MCConstantExpr::Create(0, getContext());
1960 // Replace the register operand with the memory operand.
1961 std::unique_ptr<MipsOperand> op(
1962 static_cast<MipsOperand *>(Operands.back().release()));
1963 // Remove the register from the operands.
1964 // "op" will be managed by k_Memory.
1965 Operands.pop_back();
1966 // Add the memory operand.
1967 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1969 if (IdVal->EvaluateAsAbsolute(Imm))
1970 IdVal = MCConstantExpr::Create(Imm, getContext());
1971 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1972 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1976 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
1977 return MatchOperand_Success;
1980 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
1982 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1984 SMLoc S = Parser.getTok().getLoc();
1986 if (Sym->isVariable())
1987 Expr = Sym->getVariableValue();
1990 if (Expr->getKind() == MCExpr::SymbolRef) {
1991 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1992 const StringRef DefSymbol = Ref->getSymbol().getName();
1993 if (DefSymbol.startswith("$")) {
1994 OperandMatchResultTy ResTy =
1995 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
1996 if (ResTy == MatchOperand_Success) {
1999 } else if (ResTy == MatchOperand_ParseFail)
2000 llvm_unreachable("Should never ParseFail");
2003 } else if (Expr->getKind() == MCExpr::Constant) {
2005 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2007 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2014 MipsAsmParser::OperandMatchResultTy
2015 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2016 StringRef Identifier,
2018 int Index = matchCPURegisterName(Identifier);
2020 Operands.push_back(MipsOperand::CreateGPRReg(
2021 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2022 return MatchOperand_Success;
2025 Index = matchFPURegisterName(Identifier);
2027 Operands.push_back(MipsOperand::CreateFGRReg(
2028 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2029 return MatchOperand_Success;
2032 Index = matchFCCRegisterName(Identifier);
2034 Operands.push_back(MipsOperand::CreateFCCReg(
2035 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2036 return MatchOperand_Success;
2039 Index = matchACRegisterName(Identifier);
2041 Operands.push_back(MipsOperand::CreateACCReg(
2042 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2043 return MatchOperand_Success;
2046 Index = matchMSA128RegisterName(Identifier);
2048 Operands.push_back(MipsOperand::CreateMSA128Reg(
2049 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2050 return MatchOperand_Success;
2053 Index = matchMSA128CtrlRegisterName(Identifier);
2055 Operands.push_back(MipsOperand::CreateMSACtrlReg(
2056 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2057 return MatchOperand_Success;
2060 return MatchOperand_NoMatch;
2063 MipsAsmParser::OperandMatchResultTy
2064 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2065 auto Token = Parser.getLexer().peekTok(false);
2067 if (Token.is(AsmToken::Identifier)) {
2068 DEBUG(dbgs() << ".. identifier\n");
2069 StringRef Identifier = Token.getIdentifier();
2070 OperandMatchResultTy ResTy =
2071 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2073 } else if (Token.is(AsmToken::Integer)) {
2074 DEBUG(dbgs() << ".. integer\n");
2075 Operands.push_back(MipsOperand::CreateNumericReg(
2076 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2078 return MatchOperand_Success;
2081 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2083 return MatchOperand_NoMatch;
2086 MipsAsmParser::OperandMatchResultTy
2087 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
2088 DEBUG(dbgs() << "ParseAnyRegister\n");
2090 auto Token = Parser.getTok();
2092 SMLoc S = Token.getLoc();
2094 if (Token.isNot(AsmToken::Dollar)) {
2095 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2096 if (Token.is(AsmToken::Identifier)) {
2097 if (searchSymbolAlias(Operands))
2098 return MatchOperand_Success;
2100 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2101 return MatchOperand_NoMatch;
2103 DEBUG(dbgs() << ".. $\n");
2105 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
2106 if (ResTy == MatchOperand_Success) {
2108 Parser.Lex(); // identifier
2113 MipsAsmParser::OperandMatchResultTy
2114 MipsAsmParser::ParseImm(OperandVector &Operands) {
2115 switch (getLexer().getKind()) {
2117 return MatchOperand_NoMatch;
2118 case AsmToken::LParen:
2119 case AsmToken::Minus:
2120 case AsmToken::Plus:
2121 case AsmToken::Integer:
2122 case AsmToken::Tilde:
2123 case AsmToken::String:
2127 const MCExpr *IdVal;
2128 SMLoc S = Parser.getTok().getLoc();
2129 if (getParser().parseExpression(IdVal))
2130 return MatchOperand_ParseFail;
2132 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2133 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2134 return MatchOperand_Success;
2137 MipsAsmParser::OperandMatchResultTy
2138 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
2139 DEBUG(dbgs() << "ParseJumpTarget\n");
2141 SMLoc S = getLexer().getLoc();
2143 // Integers and expressions are acceptable
2144 OperandMatchResultTy ResTy = ParseImm(Operands);
2145 if (ResTy != MatchOperand_NoMatch)
2148 // Registers are a valid target and have priority over symbols.
2149 ResTy = ParseAnyRegister(Operands);
2150 if (ResTy != MatchOperand_NoMatch)
2153 const MCExpr *Expr = nullptr;
2154 if (Parser.parseExpression(Expr)) {
2155 // We have no way of knowing if a symbol was consumed so we must ParseFail
2156 return MatchOperand_ParseFail;
2159 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2160 return MatchOperand_Success;
2163 MipsAsmParser::OperandMatchResultTy
2164 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2165 const MCExpr *IdVal;
2166 // If the first token is '$' we may have register operand.
2167 if (Parser.getTok().is(AsmToken::Dollar))
2168 return MatchOperand_NoMatch;
2169 SMLoc S = Parser.getTok().getLoc();
2170 if (getParser().parseExpression(IdVal))
2171 return MatchOperand_ParseFail;
2172 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2173 assert(MCE && "Unexpected MCExpr type.");
2174 int64_t Val = MCE->getValue();
2175 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2176 Operands.push_back(MipsOperand::CreateImm(
2177 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2178 return MatchOperand_Success;
2181 MipsAsmParser::OperandMatchResultTy
2182 MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
2183 switch (getLexer().getKind()) {
2185 return MatchOperand_NoMatch;
2186 case AsmToken::LParen:
2187 case AsmToken::Plus:
2188 case AsmToken::Minus:
2189 case AsmToken::Integer:
2194 SMLoc S = Parser.getTok().getLoc();
2196 if (getParser().parseExpression(Expr))
2197 return MatchOperand_ParseFail;
2200 if (!Expr->EvaluateAsAbsolute(Val)) {
2201 Error(S, "expected immediate value");
2202 return MatchOperand_ParseFail;
2205 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2206 // and because the CPU always adds one to the immediate field, the allowed
2207 // range becomes 1..4. We'll only check the range here and will deal
2208 // with the addition/subtraction when actually decoding/encoding
2210 if (Val < 1 || Val > 4) {
2211 Error(S, "immediate not in range (1..4)");
2212 return MatchOperand_ParseFail;
2216 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2217 return MatchOperand_Success;
2220 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2222 MCSymbolRefExpr::VariantKind VK =
2223 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2224 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2225 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2226 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2227 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2228 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2229 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2230 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2231 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2232 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2233 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2234 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2235 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2236 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2237 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2238 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2239 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2240 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2241 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2242 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2243 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2244 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2245 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2246 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2247 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2248 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2249 .Default(MCSymbolRefExpr::VK_None);
2251 assert(VK != MCSymbolRefExpr::VK_None);
2256 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2258 /// ::= '(', register, ')'
2259 /// handle it before we iterate so we don't get tripped up by the lack of
2261 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2262 if (getLexer().is(AsmToken::LParen)) {
2264 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2266 if (ParseOperand(Operands, Name)) {
2267 SMLoc Loc = getLexer().getLoc();
2268 Parser.eatToEndOfStatement();
2269 return Error(Loc, "unexpected token in argument list");
2271 if (Parser.getTok().isNot(AsmToken::RParen)) {
2272 SMLoc Loc = getLexer().getLoc();
2273 Parser.eatToEndOfStatement();
2274 return Error(Loc, "unexpected token, expected ')'");
2277 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2283 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2284 /// either one of these.
2285 /// ::= '[', register, ']'
2286 /// ::= '[', integer, ']'
2287 /// handle it before we iterate so we don't get tripped up by the lack of
2289 bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2290 OperandVector &Operands) {
2291 if (getLexer().is(AsmToken::LBrac)) {
2293 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2295 if (ParseOperand(Operands, Name)) {
2296 SMLoc Loc = getLexer().getLoc();
2297 Parser.eatToEndOfStatement();
2298 return Error(Loc, "unexpected token in argument list");
2300 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2301 SMLoc Loc = getLexer().getLoc();
2302 Parser.eatToEndOfStatement();
2303 return Error(Loc, "unexpected token, expected ']'");
2306 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2312 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2313 SMLoc NameLoc, OperandVector &Operands) {
2314 DEBUG(dbgs() << "ParseInstruction\n");
2315 // We have reached first instruction, module directive after
2316 // this is forbidden.
2317 getTargetStreamer().setCanHaveModuleDir(false);
2318 // Check if we have valid mnemonic
2319 if (!mnemonicIsValid(Name, 0)) {
2320 Parser.eatToEndOfStatement();
2321 return Error(NameLoc, "Unknown instruction");
2323 // First operand in MCInst is instruction mnemonic.
2324 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2326 // Read the remaining operands.
2327 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2328 // Read the first operand.
2329 if (ParseOperand(Operands, Name)) {
2330 SMLoc Loc = getLexer().getLoc();
2331 Parser.eatToEndOfStatement();
2332 return Error(Loc, "unexpected token in argument list");
2334 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2336 // AFAIK, parenthesis suffixes are never on the first operand
2338 while (getLexer().is(AsmToken::Comma)) {
2339 Parser.Lex(); // Eat the comma.
2340 // Parse and remember the operand.
2341 if (ParseOperand(Operands, Name)) {
2342 SMLoc Loc = getLexer().getLoc();
2343 Parser.eatToEndOfStatement();
2344 return Error(Loc, "unexpected token in argument list");
2346 // Parse bracket and parenthesis suffixes before we iterate
2347 if (getLexer().is(AsmToken::LBrac)) {
2348 if (ParseBracketSuffix(Name, Operands))
2350 } else if (getLexer().is(AsmToken::LParen) &&
2351 ParseParenSuffix(Name, Operands))
2355 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2356 SMLoc Loc = getLexer().getLoc();
2357 Parser.eatToEndOfStatement();
2358 return Error(Loc, "unexpected token in argument list");
2360 Parser.Lex(); // Consume the EndOfStatement.
2364 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2365 SMLoc Loc = getLexer().getLoc();
2366 Parser.eatToEndOfStatement();
2367 return Error(Loc, ErrorMsg);
2370 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2371 return Error(Loc, ErrorMsg);
2374 bool MipsAsmParser::parseSetNoAtDirective() {
2375 // Line should look like: ".set noat".
2377 Options.setATReg(0);
2380 // If this is not the end of the statement, report an error.
2381 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2382 reportParseError("unexpected token in statement");
2385 Parser.Lex(); // Consume the EndOfStatement.
2389 bool MipsAsmParser::parseSetAtDirective() {
2390 // Line can be .set at - defaults to $1
2394 if (getLexer().is(AsmToken::EndOfStatement)) {
2395 Options.setATReg(1);
2396 Parser.Lex(); // Consume the EndOfStatement.
2398 } else if (getLexer().is(AsmToken::Equal)) {
2399 getParser().Lex(); // Eat the '='.
2400 if (getLexer().isNot(AsmToken::Dollar)) {
2401 reportParseError("unexpected token in statement");
2404 Parser.Lex(); // Eat the '$'.
2405 const AsmToken &Reg = Parser.getTok();
2406 if (Reg.is(AsmToken::Identifier)) {
2407 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2408 } else if (Reg.is(AsmToken::Integer)) {
2409 AtRegNo = Reg.getIntVal();
2411 reportParseError("unexpected token in statement");
2415 if (AtRegNo < 0 || AtRegNo > 31) {
2416 reportParseError("unexpected token in statement");
2420 if (!Options.setATReg(AtRegNo)) {
2421 reportParseError("unexpected token in statement");
2424 getParser().Lex(); // Eat the register.
2426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2427 reportParseError("unexpected token in statement");
2430 Parser.Lex(); // Consume the EndOfStatement.
2433 reportParseError("unexpected token in statement");
2438 bool MipsAsmParser::parseSetReorderDirective() {
2440 // If this is not the end of the statement, report an error.
2441 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2442 reportParseError("unexpected token in statement");
2445 Options.setReorder();
2446 getTargetStreamer().emitDirectiveSetReorder();
2447 Parser.Lex(); // Consume the EndOfStatement.
2451 bool MipsAsmParser::parseSetNoReorderDirective() {
2453 // If this is not the end of the statement, report an error.
2454 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2455 reportParseError("unexpected token in statement");
2458 Options.setNoreorder();
2459 getTargetStreamer().emitDirectiveSetNoReorder();
2460 Parser.Lex(); // Consume the EndOfStatement.
2464 bool MipsAsmParser::parseSetMacroDirective() {
2466 // If this is not the end of the statement, report an error.
2467 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2468 reportParseError("unexpected token in statement");
2472 Parser.Lex(); // Consume the EndOfStatement.
2476 bool MipsAsmParser::parseSetNoMacroDirective() {
2478 // If this is not the end of the statement, report an error.
2479 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2480 reportParseError("`noreorder' must be set before `nomacro'");
2483 if (Options.isReorder()) {
2484 reportParseError("`noreorder' must be set before `nomacro'");
2487 Options.setNomacro();
2488 Parser.Lex(); // Consume the EndOfStatement.
2492 bool MipsAsmParser::parseSetMsaDirective() {
2495 // If this is not the end of the statement, report an error.
2496 if (getLexer().isNot(AsmToken::EndOfStatement))
2497 return reportParseError("unexpected token in statement");
2499 setFeatureBits(Mips::FeatureMSA, "msa");
2500 getTargetStreamer().emitDirectiveSetMsa();
2504 bool MipsAsmParser::parseSetNoMsaDirective() {
2507 // If this is not the end of the statement, report an error.
2508 if (getLexer().isNot(AsmToken::EndOfStatement))
2509 return reportParseError("unexpected token in statement");
2511 clearFeatureBits(Mips::FeatureMSA, "msa");
2512 getTargetStreamer().emitDirectiveSetNoMsa();
2516 bool MipsAsmParser::parseSetNoMips16Directive() {
2518 // If this is not the end of the statement, report an error.
2519 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2520 reportParseError("unexpected token in statement");
2523 // For now do nothing.
2524 Parser.Lex(); // Consume the EndOfStatement.
2528 bool MipsAsmParser::parseSetFpDirective() {
2529 MipsABIFlagsSection::FpABIKind FpAbiVal;
2530 // Line can be: .set fp=32
2533 Parser.Lex(); // Eat fp token
2534 AsmToken Tok = Parser.getTok();
2535 if (Tok.isNot(AsmToken::Equal)) {
2536 reportParseError("unexpected token in statement");
2539 Parser.Lex(); // Eat '=' token.
2540 Tok = Parser.getTok();
2542 if (!parseFpABIValue(FpAbiVal, ".set"))
2545 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2546 reportParseError("unexpected token in statement");
2549 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2550 Parser.Lex(); // Consume the EndOfStatement.
2554 bool MipsAsmParser::parseSetAssignment() {
2556 const MCExpr *Value;
2558 if (Parser.parseIdentifier(Name))
2559 reportParseError("expected identifier after .set");
2561 if (getLexer().isNot(AsmToken::Comma))
2562 return reportParseError("unexpected token in .set directive");
2565 if (Parser.parseExpression(Value))
2566 return reportParseError("expected valid expression after comma");
2568 // Check if the Name already exists as a symbol.
2569 MCSymbol *Sym = getContext().LookupSymbol(Name);
2571 return reportParseError("symbol already defined");
2572 Sym = getContext().GetOrCreateSymbol(Name);
2573 Sym->setVariableValue(Value);
2578 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2580 if (getLexer().isNot(AsmToken::EndOfStatement))
2581 return reportParseError("unexpected token in .set directive");
2585 llvm_unreachable("Unimplemented feature");
2586 case Mips::FeatureDSP:
2587 setFeatureBits(Mips::FeatureDSP, "dsp");
2588 getTargetStreamer().emitDirectiveSetDsp();
2590 case Mips::FeatureMicroMips:
2591 getTargetStreamer().emitDirectiveSetMicroMips();
2593 case Mips::FeatureMips16:
2594 getTargetStreamer().emitDirectiveSetMips16();
2596 case Mips::FeatureMips1:
2597 selectArch("mips1");
2598 getTargetStreamer().emitDirectiveSetMips1();
2600 case Mips::FeatureMips2:
2601 selectArch("mips2");
2602 getTargetStreamer().emitDirectiveSetMips2();
2604 case Mips::FeatureMips3:
2605 selectArch("mips3");
2606 getTargetStreamer().emitDirectiveSetMips3();
2608 case Mips::FeatureMips4:
2609 selectArch("mips4");
2610 getTargetStreamer().emitDirectiveSetMips4();
2612 case Mips::FeatureMips5:
2613 selectArch("mips5");
2614 getTargetStreamer().emitDirectiveSetMips5();
2616 case Mips::FeatureMips32:
2617 selectArch("mips32");
2618 getTargetStreamer().emitDirectiveSetMips32();
2620 case Mips::FeatureMips32r2:
2621 selectArch("mips32r2");
2622 getTargetStreamer().emitDirectiveSetMips32R2();
2624 case Mips::FeatureMips32r6:
2625 selectArch("mips32r6");
2626 getTargetStreamer().emitDirectiveSetMips32R6();
2628 case Mips::FeatureMips64:
2629 selectArch("mips64");
2630 getTargetStreamer().emitDirectiveSetMips64();
2632 case Mips::FeatureMips64r2:
2633 selectArch("mips64r2");
2634 getTargetStreamer().emitDirectiveSetMips64R2();
2636 case Mips::FeatureMips64r6:
2637 selectArch("mips64r6");
2638 getTargetStreamer().emitDirectiveSetMips64R6();
2644 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2645 if (getLexer().isNot(AsmToken::Comma)) {
2646 SMLoc Loc = getLexer().getLoc();
2647 Parser.eatToEndOfStatement();
2648 return Error(Loc, ErrorStr);
2651 Parser.Lex(); // Eat the comma.
2655 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2656 if (Options.isReorder())
2657 Warning(Loc, ".cpload in reorder section");
2659 // FIXME: Warn if cpload is used in Mips16 mode.
2661 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2662 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2663 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2664 reportParseError("expected register containing function address");
2668 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2669 if (!RegOpnd.isGPRAsmReg()) {
2670 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2674 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2678 bool MipsAsmParser::parseDirectiveCPSetup() {
2681 bool SaveIsReg = true;
2683 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2684 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2685 if (ResTy == MatchOperand_NoMatch) {
2686 reportParseError("expected register containing function address");
2687 Parser.eatToEndOfStatement();
2691 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2692 if (!FuncRegOpnd.isGPRAsmReg()) {
2693 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2694 Parser.eatToEndOfStatement();
2698 FuncReg = FuncRegOpnd.getGPR32Reg();
2701 if (!eatComma("expected comma parsing directive"))
2704 ResTy = ParseAnyRegister(TmpReg);
2705 if (ResTy == MatchOperand_NoMatch) {
2706 const AsmToken &Tok = Parser.getTok();
2707 if (Tok.is(AsmToken::Integer)) {
2708 Save = Tok.getIntVal();
2712 reportParseError("expected save register or stack offset");
2713 Parser.eatToEndOfStatement();
2717 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2718 if (!SaveOpnd.isGPRAsmReg()) {
2719 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2720 Parser.eatToEndOfStatement();
2723 Save = SaveOpnd.getGPR32Reg();
2726 if (!eatComma("expected comma parsing directive"))
2730 if (Parser.parseIdentifier(Name))
2731 reportParseError("expected identifier");
2732 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2734 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2738 bool MipsAsmParser::parseDirectiveNaN() {
2739 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2740 const AsmToken &Tok = Parser.getTok();
2742 if (Tok.getString() == "2008") {
2744 getTargetStreamer().emitDirectiveNaN2008();
2746 } else if (Tok.getString() == "legacy") {
2748 getTargetStreamer().emitDirectiveNaNLegacy();
2752 // If we don't recognize the option passed to the .nan
2753 // directive (e.g. no option or unknown option), emit an error.
2754 reportParseError("invalid option in .nan directive");
2758 bool MipsAsmParser::parseDirectiveSet() {
2760 // Get the next token.
2761 const AsmToken &Tok = Parser.getTok();
2763 if (Tok.getString() == "noat") {
2764 return parseSetNoAtDirective();
2765 } else if (Tok.getString() == "at") {
2766 return parseSetAtDirective();
2767 } else if (Tok.getString() == "fp") {
2768 return parseSetFpDirective();
2769 } else if (Tok.getString() == "reorder") {
2770 return parseSetReorderDirective();
2771 } else if (Tok.getString() == "noreorder") {
2772 return parseSetNoReorderDirective();
2773 } else if (Tok.getString() == "macro") {
2774 return parseSetMacroDirective();
2775 } else if (Tok.getString() == "nomacro") {
2776 return parseSetNoMacroDirective();
2777 } else if (Tok.getString() == "mips16") {
2778 return parseSetFeature(Mips::FeatureMips16);
2779 } else if (Tok.getString() == "nomips16") {
2780 return parseSetNoMips16Directive();
2781 } else if (Tok.getString() == "nomicromips") {
2782 getTargetStreamer().emitDirectiveSetNoMicroMips();
2783 Parser.eatToEndOfStatement();
2785 } else if (Tok.getString() == "micromips") {
2786 return parseSetFeature(Mips::FeatureMicroMips);
2787 } else if (Tok.getString() == "mips1") {
2788 return parseSetFeature(Mips::FeatureMips1);
2789 } else if (Tok.getString() == "mips2") {
2790 return parseSetFeature(Mips::FeatureMips2);
2791 } else if (Tok.getString() == "mips3") {
2792 return parseSetFeature(Mips::FeatureMips3);
2793 } else if (Tok.getString() == "mips4") {
2794 return parseSetFeature(Mips::FeatureMips4);
2795 } else if (Tok.getString() == "mips5") {
2796 return parseSetFeature(Mips::FeatureMips5);
2797 } else if (Tok.getString() == "mips32") {
2798 return parseSetFeature(Mips::FeatureMips32);
2799 } else if (Tok.getString() == "mips32r2") {
2800 return parseSetFeature(Mips::FeatureMips32r2);
2801 } else if (Tok.getString() == "mips32r6") {
2802 return parseSetFeature(Mips::FeatureMips32r6);
2803 } else if (Tok.getString() == "mips64") {
2804 return parseSetFeature(Mips::FeatureMips64);
2805 } else if (Tok.getString() == "mips64r2") {
2806 return parseSetFeature(Mips::FeatureMips64r2);
2807 } else if (Tok.getString() == "mips64r6") {
2808 return parseSetFeature(Mips::FeatureMips64r6);
2809 } else if (Tok.getString() == "dsp") {
2810 return parseSetFeature(Mips::FeatureDSP);
2811 } else if (Tok.getString() == "msa") {
2812 return parseSetMsaDirective();
2813 } else if (Tok.getString() == "nomsa") {
2814 return parseSetNoMsaDirective();
2816 // It is just an identifier, look for an assignment.
2817 parseSetAssignment();
2824 /// parseDataDirective
2825 /// ::= .word [ expression (, expression)* ]
2826 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2827 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2829 const MCExpr *Value;
2830 if (getParser().parseExpression(Value))
2833 getParser().getStreamer().EmitValue(Value, Size);
2835 if (getLexer().is(AsmToken::EndOfStatement))
2838 // FIXME: Improve diagnostic.
2839 if (getLexer().isNot(AsmToken::Comma))
2840 return Error(L, "unexpected token in directive");
2849 /// parseDirectiveGpWord
2850 /// ::= .gpword local_sym
2851 bool MipsAsmParser::parseDirectiveGpWord() {
2852 const MCExpr *Value;
2853 // EmitGPRel32Value requires an expression, so we are using base class
2854 // method to evaluate the expression.
2855 if (getParser().parseExpression(Value))
2857 getParser().getStreamer().EmitGPRel32Value(Value);
2859 if (getLexer().isNot(AsmToken::EndOfStatement))
2860 return Error(getLexer().getLoc(), "unexpected token in directive");
2861 Parser.Lex(); // Eat EndOfStatement token.
2865 /// parseDirectiveGpDWord
2866 /// ::= .gpdword local_sym
2867 bool MipsAsmParser::parseDirectiveGpDWord() {
2868 const MCExpr *Value;
2869 // EmitGPRel64Value requires an expression, so we are using base class
2870 // method to evaluate the expression.
2871 if (getParser().parseExpression(Value))
2873 getParser().getStreamer().EmitGPRel64Value(Value);
2875 if (getLexer().isNot(AsmToken::EndOfStatement))
2876 return Error(getLexer().getLoc(), "unexpected token in directive");
2877 Parser.Lex(); // Eat EndOfStatement token.
2881 bool MipsAsmParser::parseDirectiveOption() {
2882 // Get the option token.
2883 AsmToken Tok = Parser.getTok();
2884 // At the moment only identifiers are supported.
2885 if (Tok.isNot(AsmToken::Identifier)) {
2886 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2887 Parser.eatToEndOfStatement();
2891 StringRef Option = Tok.getIdentifier();
2893 if (Option == "pic0") {
2894 getTargetStreamer().emitDirectiveOptionPic0();
2896 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2897 Error(Parser.getTok().getLoc(),
2898 "unexpected token in .option pic0 directive");
2899 Parser.eatToEndOfStatement();
2904 if (Option == "pic2") {
2905 getTargetStreamer().emitDirectiveOptionPic2();
2907 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2908 Error(Parser.getTok().getLoc(),
2909 "unexpected token in .option pic2 directive");
2910 Parser.eatToEndOfStatement();
2916 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2917 Parser.eatToEndOfStatement();
2921 /// parseDirectiveModule
2922 /// ::= .module oddspreg
2923 /// ::= .module nooddspreg
2924 /// ::= .module fp=value
2925 bool MipsAsmParser::parseDirectiveModule() {
2926 MCAsmLexer &Lexer = getLexer();
2927 SMLoc L = Lexer.getLoc();
2929 if (!getTargetStreamer().getCanHaveModuleDir()) {
2930 // TODO : get a better message.
2931 reportParseError(".module directive must appear before any code");
2935 if (Lexer.is(AsmToken::Identifier)) {
2936 StringRef Option = Parser.getTok().getString();
2939 if (Option == "oddspreg") {
2940 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
2941 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2943 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2944 reportParseError("Expected end of statement");
2949 } else if (Option == "nooddspreg") {
2951 Error(L, "'.module nooddspreg' requires the O32 ABI");
2955 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
2956 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2958 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2959 reportParseError("Expected end of statement");
2964 } else if (Option == "fp") {
2965 return parseDirectiveModuleFP();
2968 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
2974 /// parseDirectiveModuleFP
2978 bool MipsAsmParser::parseDirectiveModuleFP() {
2979 MCAsmLexer &Lexer = getLexer();
2981 if (Lexer.isNot(AsmToken::Equal)) {
2982 reportParseError("unexpected token in statement");
2985 Parser.Lex(); // Eat '=' token.
2987 MipsABIFlagsSection::FpABIKind FpABI;
2988 if (!parseFpABIValue(FpABI, ".module"))
2991 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2992 reportParseError("unexpected token in statement");
2996 // Emit appropriate flags.
2997 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
2998 Parser.Lex(); // Consume the EndOfStatement.
3002 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3003 StringRef Directive) {
3004 MCAsmLexer &Lexer = getLexer();
3006 if (Lexer.is(AsmToken::Identifier)) {
3007 StringRef Value = Parser.getTok().getString();
3010 if (Value != "xx") {
3011 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3016 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3020 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3024 if (Lexer.is(AsmToken::Integer)) {
3025 unsigned Value = Parser.getTok().getIntVal();
3028 if (Value != 32 && Value != 64) {
3029 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3035 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3039 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3041 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3049 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3050 StringRef IDVal = DirectiveID.getString();
3052 if (IDVal == ".cpload")
3053 return parseDirectiveCPLoad(DirectiveID.getLoc());
3054 if (IDVal == ".dword") {
3055 parseDataDirective(8, DirectiveID.getLoc());
3059 if (IDVal == ".ent") {
3060 // Ignore this directive for now.
3065 if (IDVal == ".end") {
3066 // Ignore this directive for now.
3071 if (IDVal == ".frame") {
3072 // Ignore this directive for now.
3073 Parser.eatToEndOfStatement();
3077 if (IDVal == ".set") {
3078 return parseDirectiveSet();
3081 if (IDVal == ".fmask") {
3082 // Ignore this directive for now.
3083 Parser.eatToEndOfStatement();
3087 if (IDVal == ".mask") {
3088 // Ignore this directive for now.
3089 Parser.eatToEndOfStatement();
3093 if (IDVal == ".nan")
3094 return parseDirectiveNaN();
3096 if (IDVal == ".gpword") {
3097 parseDirectiveGpWord();
3101 if (IDVal == ".gpdword") {
3102 parseDirectiveGpDWord();
3106 if (IDVal == ".word") {
3107 parseDataDirective(4, DirectiveID.getLoc());
3111 if (IDVal == ".option")
3112 return parseDirectiveOption();
3114 if (IDVal == ".abicalls") {
3115 getTargetStreamer().emitDirectiveAbiCalls();
3116 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3117 Error(Parser.getTok().getLoc(), "unexpected token in directive");
3119 Parser.eatToEndOfStatement();
3124 if (IDVal == ".cpsetup")
3125 return parseDirectiveCPSetup();
3127 if (IDVal == ".module")
3128 return parseDirectiveModule();
3133 extern "C" void LLVMInitializeMipsAsmParser() {
3134 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3135 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3136 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3137 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3140 #define GET_REGISTER_MATCHER
3141 #define GET_MATCHER_IMPLEMENTATION
3142 #include "MipsGenAsmMatcher.inc"