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 parseSetReorderDirective();
171 bool parseSetNoReorderDirective();
172 bool parseSetNoMips16Directive();
173 bool parseSetFpDirective();
175 bool parseSetAssignment();
177 bool parseDataDirective(unsigned Size, SMLoc L);
178 bool parseDirectiveGpWord();
179 bool parseDirectiveGpDWord();
180 bool parseDirectiveModule();
181 bool parseDirectiveModuleFP();
182 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
183 StringRef Directive);
185 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
187 bool eatComma(StringRef ErrorStr);
189 int matchCPURegisterName(StringRef Symbol);
191 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
193 int matchFPURegisterName(StringRef Name);
195 int matchFCCRegisterName(StringRef Name);
197 int matchACRegisterName(StringRef Name);
199 int matchMSA128RegisterName(StringRef Name);
201 int matchMSA128CtrlRegisterName(StringRef Name);
203 unsigned getReg(int RC, int RegNo);
205 unsigned getGPR(int RegNo);
207 int getATReg(SMLoc Loc);
209 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
210 SmallVectorImpl<MCInst> &Instructions);
212 // Helper function that checks if the value of a vector index is within the
213 // boundaries of accepted values for each RegisterKind
214 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
215 bool validateMSAIndex(int Val, int RegKind);
217 // Selects a new architecture by updating the FeatureBits with the necessary
218 // info including implied dependencies.
219 // Internally, it clears all the feature bits related to *any* architecture
220 // and selects the new one using the ToggleFeature functionality of the
221 // MCSubtargetInfo object that handles implied dependencies. The reason we
222 // clear all the arch related bits manually is because ToggleFeature only
223 // clears the features that imply the feature being cleared and not the
224 // features implied by the feature being cleared. This is easier to see
226 // --------------------------------------------------
227 // | Feature | Implies |
228 // | -------------------------------------------------|
229 // | FeatureMips1 | None |
230 // | FeatureMips2 | FeatureMips1 |
231 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
232 // | FeatureMips4 | FeatureMips3 |
234 // --------------------------------------------------
236 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
237 // FeatureMipsGP64 | FeatureMips1)
238 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
239 void selectArch(StringRef ArchFeature) {
240 uint64_t FeatureBits = STI.getFeatureBits();
241 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
242 STI.setFeatureBits(FeatureBits);
243 setAvailableFeatures(
244 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
247 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
248 if (!(STI.getFeatureBits() & Feature)) {
249 setAvailableFeatures(
250 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
254 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
255 if (STI.getFeatureBits() & Feature) {
256 setAvailableFeatures(
257 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
262 enum MipsMatchResultTy {
263 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
264 #define GET_OPERAND_DIAGNOSTIC_TYPES
265 #include "MipsGenAsmMatcher.inc"
266 #undef GET_OPERAND_DIAGNOSTIC_TYPES
270 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
271 const MCInstrInfo &MII, const MCTargetOptions &Options)
272 : MCTargetAsmParser(), STI(sti), Parser(parser) {
273 // Initialize the set of available features.
274 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
276 getTargetStreamer().updateABIInfo(*this);
278 // Assert exactly one ABI was chosen.
279 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
280 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
281 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
282 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
284 if (!isABI_O32() && !useOddSPReg() != 0)
285 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
288 MCAsmParser &getParser() const { return Parser; }
289 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
291 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
292 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
294 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
295 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
296 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
297 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
298 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
299 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
301 bool useOddSPReg() const {
302 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
305 bool inMicroMipsMode() const {
306 return STI.getFeatureBits() & Mips::FeatureMicroMips;
308 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
309 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
310 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
311 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
312 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
313 bool hasMips32() const {
314 return (STI.getFeatureBits() & Mips::FeatureMips32);
316 bool hasMips64() const {
317 return (STI.getFeatureBits() & Mips::FeatureMips64);
319 bool hasMips32r2() const {
320 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
322 bool hasMips64r2() const {
323 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
325 bool hasMips32r6() const {
326 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
328 bool hasMips64r6() const {
329 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
331 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
332 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
333 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
335 bool inMips16Mode() const {
336 return STI.getFeatureBits() & Mips::FeatureMips16;
338 // TODO: see how can we get this info.
339 bool abiUsesSoftFloat() const { return false; }
341 /// Warn if RegNo is the current assembler temporary.
342 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
348 /// MipsOperand - Instances of this class represent a parsed Mips machine
350 class MipsOperand : public MCParsedAsmOperand {
352 /// Broad categories of register classes
353 /// The exact class is finalized by the render method.
355 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
356 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
358 RegKind_FCC = 4, /// FCC
359 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
360 RegKind_MSACtrl = 16, /// MSA control registers
361 RegKind_COP2 = 32, /// COP2
362 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
364 RegKind_CCR = 128, /// CCR
365 RegKind_HWRegs = 256, /// HWRegs
366 RegKind_COP3 = 512, /// COP3
368 /// Potentially any (e.g. $1)
369 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
370 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
371 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
376 k_Immediate, /// An immediate (possibly involving symbol references)
377 k_Memory, /// Base + Offset Memory Address
378 k_PhysRegister, /// A physical register from the Mips namespace
379 k_RegisterIndex, /// A register index in one or more RegKind.
380 k_Token /// A simple token
384 MipsOperand(KindTy K, MipsAsmParser &Parser)
385 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
388 /// For diagnostics, and checking the assembler temporary
389 MipsAsmParser &AsmParser;
397 unsigned Num; /// Register Number
401 unsigned Index; /// Index into the register class
402 RegKind Kind; /// Bitfield of the kinds it could possibly be
403 const MCRegisterInfo *RegInfo;
417 struct PhysRegOp PhysReg;
418 struct RegIdxOp RegIdx;
423 SMLoc StartLoc, EndLoc;
425 /// Internal constructor for register kinds
426 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
427 const MCRegisterInfo *RegInfo,
429 MipsAsmParser &Parser) {
430 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
431 Op->RegIdx.Index = Index;
432 Op->RegIdx.RegInfo = RegInfo;
433 Op->RegIdx.Kind = RegKind;
440 /// Coerce the register to GPR32 and return the real register for the current
442 unsigned getGPR32Reg() const {
443 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
444 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
445 unsigned ClassID = Mips::GPR32RegClassID;
446 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
449 /// Coerce the register to GPR64 and return the real register for the current
451 unsigned getGPR64Reg() const {
452 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
453 unsigned ClassID = Mips::GPR64RegClassID;
454 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
458 /// Coerce the register to AFGR64 and return the real register for the current
460 unsigned getAFGR64Reg() const {
461 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
462 if (RegIdx.Index % 2 != 0)
463 AsmParser.Warning(StartLoc, "Float register should be even.");
464 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
465 .getRegister(RegIdx.Index / 2);
468 /// Coerce the register to FGR64 and return the real register for the current
470 unsigned getFGR64Reg() const {
471 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
472 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
473 .getRegister(RegIdx.Index);
476 /// Coerce the register to FGR32 and return the real register for the current
478 unsigned getFGR32Reg() const {
479 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
480 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
481 .getRegister(RegIdx.Index);
484 /// Coerce the register to FGRH32 and return the real register for the current
486 unsigned getFGRH32Reg() const {
487 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
488 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
489 .getRegister(RegIdx.Index);
492 /// Coerce the register to FCC and return the real register for the current
494 unsigned getFCCReg() const {
495 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
496 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
497 .getRegister(RegIdx.Index);
500 /// Coerce the register to MSA128 and return the real register for the current
502 unsigned getMSA128Reg() const {
503 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
504 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
506 unsigned ClassID = Mips::MSA128BRegClassID;
507 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
510 /// Coerce the register to MSACtrl and return the real register for the
512 unsigned getMSACtrlReg() const {
513 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
514 unsigned ClassID = Mips::MSACtrlRegClassID;
515 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
518 /// Coerce the register to COP2 and return the real register for the
520 unsigned getCOP2Reg() const {
521 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
522 unsigned ClassID = Mips::COP2RegClassID;
523 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
526 /// Coerce the register to COP3 and return the real register for the
528 unsigned getCOP3Reg() const {
529 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
530 unsigned ClassID = Mips::COP3RegClassID;
531 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
534 /// Coerce the register to ACC64DSP and return the real register for the
536 unsigned getACC64DSPReg() const {
537 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
538 unsigned ClassID = Mips::ACC64DSPRegClassID;
539 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
542 /// Coerce the register to HI32DSP and return the real register for the
544 unsigned getHI32DSPReg() const {
545 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
546 unsigned ClassID = Mips::HI32DSPRegClassID;
547 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
550 /// Coerce the register to LO32DSP and return the real register for the
552 unsigned getLO32DSPReg() const {
553 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
554 unsigned ClassID = Mips::LO32DSPRegClassID;
555 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
558 /// Coerce the register to CCR and return the real register for the
560 unsigned getCCRReg() const {
561 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
562 unsigned ClassID = Mips::CCRRegClassID;
563 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
566 /// Coerce the register to HWRegs and return the real register for the
568 unsigned getHWRegsReg() const {
569 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
570 unsigned ClassID = Mips::HWRegsRegClassID;
571 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
575 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
576 // Add as immediate when possible. Null MCExpr = 0.
578 Inst.addOperand(MCOperand::CreateImm(0));
579 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
580 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
582 Inst.addOperand(MCOperand::CreateExpr(Expr));
585 void addRegOperands(MCInst &Inst, unsigned N) const {
586 llvm_unreachable("Use a custom parser instead");
589 /// Render the operand to an MCInst as a GPR32
590 /// Asserts if the wrong number of operands are requested, or the operand
591 /// is not a k_RegisterIndex compatible with RegKind_GPR
592 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
593 assert(N == 1 && "Invalid number of operands!");
594 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
597 /// Render the operand to an MCInst as a GPR64
598 /// Asserts if the wrong number of operands are requested, or the operand
599 /// is not a k_RegisterIndex compatible with RegKind_GPR
600 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
601 assert(N == 1 && "Invalid number of operands!");
602 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
605 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
606 assert(N == 1 && "Invalid number of operands!");
607 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
610 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
611 assert(N == 1 && "Invalid number of operands!");
612 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
615 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
616 assert(N == 1 && "Invalid number of operands!");
617 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
618 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
619 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
620 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
624 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
625 assert(N == 1 && "Invalid number of operands!");
626 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
629 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
630 assert(N == 1 && "Invalid number of operands!");
631 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
634 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
635 assert(N == 1 && "Invalid number of operands!");
636 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
639 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
640 assert(N == 1 && "Invalid number of operands!");
641 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
644 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
645 assert(N == 1 && "Invalid number of operands!");
646 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
649 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
650 assert(N == 1 && "Invalid number of operands!");
651 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
654 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
655 assert(N == 1 && "Invalid number of operands!");
656 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
659 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
660 assert(N == 1 && "Invalid number of operands!");
661 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
664 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
665 assert(N == 1 && "Invalid number of operands!");
666 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
669 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
670 assert(N == 1 && "Invalid number of operands!");
671 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
674 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
675 assert(N == 1 && "Invalid number of operands!");
676 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
679 void addImmOperands(MCInst &Inst, unsigned N) const {
680 assert(N == 1 && "Invalid number of operands!");
681 const MCExpr *Expr = getImm();
685 void addMemOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 2 && "Invalid number of operands!");
688 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
690 const MCExpr *Expr = getMemOff();
694 bool isReg() const override {
695 // As a special case until we sort out the definition of div/divu, pretend
696 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
697 if (isGPRAsmReg() && RegIdx.Index == 0)
700 return Kind == k_PhysRegister;
702 bool isRegIdx() const { return Kind == k_RegisterIndex; }
703 bool isImm() const override { return Kind == k_Immediate; }
704 bool isConstantImm() const {
705 return isImm() && dyn_cast<MCConstantExpr>(getImm());
707 bool isToken() const override {
708 // Note: It's not possible to pretend that other operand kinds are tokens.
709 // The matcher emitter checks tokens first.
710 return Kind == k_Token;
712 bool isMem() const override { return Kind == k_Memory; }
713 bool isConstantMemOff() const {
714 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
716 template <unsigned Bits> bool isMemWithSimmOffset() const {
717 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
719 bool isInvNum() const { return Kind == k_Immediate; }
720 bool isLSAImm() const {
721 if (!isConstantImm())
723 int64_t Val = getConstantImm();
724 return 1 <= Val && Val <= 4;
727 StringRef getToken() const {
728 assert(Kind == k_Token && "Invalid access!");
729 return StringRef(Tok.Data, Tok.Length);
732 unsigned getReg() const override {
733 // As a special case until we sort out the definition of div/divu, pretend
734 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
735 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
736 RegIdx.Kind & RegKind_GPR)
737 return getGPR32Reg(); // FIXME: GPR64 too
739 assert(Kind == k_PhysRegister && "Invalid access!");
743 const MCExpr *getImm() const {
744 assert((Kind == k_Immediate) && "Invalid access!");
748 int64_t getConstantImm() const {
749 const MCExpr *Val = getImm();
750 return static_cast<const MCConstantExpr *>(Val)->getValue();
753 MipsOperand *getMemBase() const {
754 assert((Kind == k_Memory) && "Invalid access!");
758 const MCExpr *getMemOff() const {
759 assert((Kind == k_Memory) && "Invalid access!");
763 int64_t getConstantMemOff() const {
764 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
767 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
768 MipsAsmParser &Parser) {
769 auto Op = make_unique<MipsOperand>(k_Token, Parser);
770 Op->Tok.Data = Str.data();
771 Op->Tok.Length = Str.size();
777 /// Create a numeric register (e.g. $1). The exact register remains
778 /// unresolved until an instruction successfully matches
779 static std::unique_ptr<MipsOperand>
780 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
781 SMLoc E, MipsAsmParser &Parser) {
782 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
783 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
786 /// Create a register that is definitely a GPR.
787 /// This is typically only used for named registers such as $gp.
788 static std::unique_ptr<MipsOperand>
789 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
790 MipsAsmParser &Parser) {
791 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
794 /// Create a register that is definitely a FGR.
795 /// This is typically only used for named registers such as $f0.
796 static std::unique_ptr<MipsOperand>
797 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
798 MipsAsmParser &Parser) {
799 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
802 /// Create a register that is definitely an FCC.
803 /// This is typically only used for named registers such as $fcc0.
804 static std::unique_ptr<MipsOperand>
805 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
806 MipsAsmParser &Parser) {
807 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
810 /// Create a register that is definitely an ACC.
811 /// This is typically only used for named registers such as $ac0.
812 static std::unique_ptr<MipsOperand>
813 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
814 MipsAsmParser &Parser) {
815 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
818 /// Create a register that is definitely an MSA128.
819 /// This is typically only used for named registers such as $w0.
820 static std::unique_ptr<MipsOperand>
821 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
822 SMLoc E, MipsAsmParser &Parser) {
823 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
826 /// Create a register that is definitely an MSACtrl.
827 /// This is typically only used for named registers such as $msaaccess.
828 static std::unique_ptr<MipsOperand>
829 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
830 SMLoc E, MipsAsmParser &Parser) {
831 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
834 static std::unique_ptr<MipsOperand>
835 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
836 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
843 static std::unique_ptr<MipsOperand>
844 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
845 SMLoc E, MipsAsmParser &Parser) {
846 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
847 Op->Mem.Base = Base.release();
854 bool isGPRAsmReg() const {
855 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
857 bool isFGRAsmReg() const {
858 // AFGR64 is $0-$15 but we handle this in getAFGR64()
859 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
861 bool isHWRegsAsmReg() const {
862 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
864 bool isCCRAsmReg() const {
865 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
867 bool isFCCAsmReg() const {
868 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
870 if (!AsmParser.hasEightFccRegisters())
871 return RegIdx.Index == 0;
872 return RegIdx.Index <= 7;
874 bool isACCAsmReg() const {
875 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
877 bool isCOP2AsmReg() const {
878 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
880 bool isCOP3AsmReg() const {
881 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
883 bool isMSA128AsmReg() const {
884 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
886 bool isMSACtrlAsmReg() const {
887 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
890 /// getStartLoc - Get the location of the first token of this operand.
891 SMLoc getStartLoc() const override { return StartLoc; }
892 /// getEndLoc - Get the location of the last token of this operand.
893 SMLoc getEndLoc() const override { return EndLoc; }
895 virtual ~MipsOperand() {
903 case k_RegisterIndex:
909 void print(raw_ostream &OS) const override {
924 OS << "PhysReg<" << PhysReg.Num << ">";
926 case k_RegisterIndex:
927 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
934 }; // class MipsOperand
938 extern const MCInstrDesc MipsInsts[];
940 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
941 return MipsInsts[Opcode];
944 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
945 SmallVectorImpl<MCInst> &Instructions) {
946 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
950 if (MCID.isBranch() || MCID.isCall()) {
951 const unsigned Opcode = Inst.getOpcode();
961 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
962 Offset = Inst.getOperand(2);
964 break; // We'll deal with this situation later on when applying fixups.
965 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
966 return Error(IDLoc, "branch target out of range");
967 if (OffsetToAlignment(Offset.getImm(),
968 1LL << (inMicroMipsMode() ? 1 : 2)))
969 return Error(IDLoc, "branch to misaligned address");
983 case Mips::BGEZAL_MM:
984 case Mips::BLTZAL_MM:
987 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
988 Offset = Inst.getOperand(1);
990 break; // We'll deal with this situation later on when applying fixups.
991 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
992 return Error(IDLoc, "branch target out of range");
993 if (OffsetToAlignment(Offset.getImm(),
994 1LL << (inMicroMipsMode() ? 1 : 2)))
995 return Error(IDLoc, "branch to misaligned address");
1000 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1001 // We still accept it but it is a normal nop.
1002 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1003 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1004 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1008 if (MCID.hasDelaySlot() && Options.isReorder()) {
1009 // If this instruction has a delay slot and .set reorder is active,
1010 // emit a NOP after it.
1011 Instructions.push_back(Inst);
1013 NopInst.setOpcode(Mips::SLL);
1014 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1015 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1016 NopInst.addOperand(MCOperand::CreateImm(0));
1017 Instructions.push_back(NopInst);
1021 if (MCID.mayLoad() || MCID.mayStore()) {
1022 // Check the offset of memory operand, if it is a symbol
1023 // reference or immediate we may have to expand instructions.
1024 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1025 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1026 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1027 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1028 MCOperand &Op = Inst.getOperand(i);
1030 int MemOffset = Op.getImm();
1031 if (MemOffset < -32768 || MemOffset > 32767) {
1032 // Offset can't exceed 16bit value.
1033 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1036 } else if (Op.isExpr()) {
1037 const MCExpr *Expr = Op.getExpr();
1038 if (Expr->getKind() == MCExpr::SymbolRef) {
1039 const MCSymbolRefExpr *SR =
1040 static_cast<const MCSymbolRefExpr *>(Expr);
1041 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1043 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1046 } else if (!isEvaluated(Expr)) {
1047 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1055 if (needsExpansion(Inst))
1056 return expandInstruction(Inst, IDLoc, Instructions);
1058 Instructions.push_back(Inst);
1063 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1065 switch (Inst.getOpcode()) {
1066 case Mips::LoadImm32Reg:
1067 case Mips::LoadAddr32Imm:
1068 case Mips::LoadAddr32Reg:
1069 case Mips::LoadImm64Reg:
1076 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1077 SmallVectorImpl<MCInst> &Instructions) {
1078 switch (Inst.getOpcode()) {
1080 assert(0 && "unimplemented expansion");
1082 case Mips::LoadImm32Reg:
1083 return expandLoadImm(Inst, IDLoc, Instructions);
1084 case Mips::LoadImm64Reg:
1086 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1089 return expandLoadImm(Inst, IDLoc, Instructions);
1090 case Mips::LoadAddr32Imm:
1091 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1092 case Mips::LoadAddr32Reg:
1093 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1098 template <int Shift, bool PerformShift>
1099 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1100 SmallVectorImpl<MCInst> &Instructions) {
1103 tmpInst.setOpcode(Mips::DSLL);
1104 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1105 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1106 tmpInst.addOperand(MCOperand::CreateImm(16));
1107 tmpInst.setLoc(IDLoc);
1108 Instructions.push_back(tmpInst);
1111 tmpInst.setOpcode(Mips::ORi);
1112 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1113 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1115 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)));
1116 tmpInst.setLoc(IDLoc);
1117 Instructions.push_back(tmpInst);
1121 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1122 SmallVectorImpl<MCInst> &Instructions) {
1124 const MCOperand &ImmOp = Inst.getOperand(1);
1125 assert(ImmOp.isImm() && "expected immediate operand kind");
1126 const MCOperand &RegOp = Inst.getOperand(0);
1127 assert(RegOp.isReg() && "expected register operand kind");
1129 int64_t ImmValue = ImmOp.getImm();
1130 tmpInst.setLoc(IDLoc);
1131 // FIXME: gas has a special case for values that are 000...1111, which
1132 // becomes a li -1 and then a dsrl
1133 if (0 <= ImmValue && ImmValue <= 65535) {
1134 // For 0 <= j <= 65535.
1135 // li d,j => ori d,$zero,j
1136 tmpInst.setOpcode(Mips::ORi);
1137 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1138 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1139 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1140 Instructions.push_back(tmpInst);
1141 } else if (ImmValue < 0 && ImmValue >= -32768) {
1142 // For -32768 <= j < 0.
1143 // li d,j => addiu d,$zero,j
1144 tmpInst.setOpcode(Mips::ADDiu);
1145 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1146 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1147 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1148 Instructions.push_back(tmpInst);
1149 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1150 // For any value of j that is representable as a 32-bit integer, create
1152 // li d,j => lui d,hi16(j)
1154 tmpInst.setOpcode(Mips::LUi);
1155 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1156 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1157 Instructions.push_back(tmpInst);
1158 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1159 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1161 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1165 // <------- lo32 ------>
1166 // <------- hi32 ------>
1167 // <- hi16 -> <- lo16 ->
1168 // _________________________________
1170 // | 16-bytes | 16-bytes | 16-bytes |
1171 // |__________|__________|__________|
1173 // For any value of j that is representable as a 48-bit integer, create
1175 // li d,j => lui d,hi16(j)
1176 // ori d,d,hi16(lo32(j))
1178 // ori d,d,lo16(lo32(j))
1179 tmpInst.setOpcode(Mips::LUi);
1180 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1182 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1183 Instructions.push_back(tmpInst);
1184 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1185 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1188 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1192 // <------- hi32 ------> <------- lo32 ------>
1193 // <- hi16 -> <- lo16 ->
1194 // ___________________________________________
1196 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1197 // |__________|__________|__________|__________|
1199 // For any value of j that isn't representable as a 48-bit integer.
1200 // li d,j => lui d,hi16(j)
1201 // ori d,d,lo16(hi32(j))
1203 // ori d,d,hi16(lo32(j))
1205 // ori d,d,lo16(lo32(j))
1206 tmpInst.setOpcode(Mips::LUi);
1207 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1209 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1210 Instructions.push_back(tmpInst);
1211 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1212 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1213 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1219 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1220 SmallVectorImpl<MCInst> &Instructions) {
1222 const MCOperand &ImmOp = Inst.getOperand(2);
1223 assert(ImmOp.isImm() && "expected immediate operand kind");
1224 const MCOperand &SrcRegOp = Inst.getOperand(1);
1225 assert(SrcRegOp.isReg() && "expected register operand kind");
1226 const MCOperand &DstRegOp = Inst.getOperand(0);
1227 assert(DstRegOp.isReg() && "expected register operand kind");
1228 int ImmValue = ImmOp.getImm();
1229 if (-32768 <= ImmValue && ImmValue <= 65535) {
1230 // For -32768 <= j <= 65535.
1231 // la d,j(s) => addiu d,s,j
1232 tmpInst.setOpcode(Mips::ADDiu);
1233 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1234 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1235 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1236 Instructions.push_back(tmpInst);
1238 // For any other value of j that is representable as a 32-bit integer.
1239 // la d,j(s) => lui d,hi16(j)
1242 tmpInst.setOpcode(Mips::LUi);
1243 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1244 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1245 Instructions.push_back(tmpInst);
1247 tmpInst.setOpcode(Mips::ORi);
1248 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1249 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1250 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1251 Instructions.push_back(tmpInst);
1253 tmpInst.setOpcode(Mips::ADDu);
1254 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1255 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1256 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1257 Instructions.push_back(tmpInst);
1263 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1264 SmallVectorImpl<MCInst> &Instructions) {
1266 const MCOperand &ImmOp = Inst.getOperand(1);
1267 assert(ImmOp.isImm() && "expected immediate operand kind");
1268 const MCOperand &RegOp = Inst.getOperand(0);
1269 assert(RegOp.isReg() && "expected register operand kind");
1270 int ImmValue = ImmOp.getImm();
1271 if (-32768 <= ImmValue && ImmValue <= 65535) {
1272 // For -32768 <= j <= 65535.
1273 // la d,j => addiu d,$zero,j
1274 tmpInst.setOpcode(Mips::ADDiu);
1275 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1276 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1277 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1278 Instructions.push_back(tmpInst);
1280 // For any other value of j that is representable as a 32-bit integer.
1281 // la d,j => lui d,hi16(j)
1283 tmpInst.setOpcode(Mips::LUi);
1284 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1285 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1286 Instructions.push_back(tmpInst);
1288 tmpInst.setOpcode(Mips::ORi);
1289 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1290 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1291 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1292 Instructions.push_back(tmpInst);
1297 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1298 SmallVectorImpl<MCInst> &Instructions,
1299 bool isLoad, bool isImmOpnd) {
1300 const MCSymbolRefExpr *SR;
1302 unsigned ImmOffset, HiOffset, LoOffset;
1303 const MCExpr *ExprOffset;
1305 // 1st operand is either the source or destination register.
1306 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1307 unsigned RegOpNum = Inst.getOperand(0).getReg();
1308 // 2nd operand is the base register.
1309 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1310 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1311 // 3rd operand is either an immediate or expression.
1313 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1314 ImmOffset = Inst.getOperand(2).getImm();
1315 LoOffset = ImmOffset & 0x0000ffff;
1316 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1317 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1318 if (LoOffset & 0x8000)
1321 ExprOffset = Inst.getOperand(2).getExpr();
1322 // All instructions will have the same location.
1323 TempInst.setLoc(IDLoc);
1324 // These are some of the types of expansions we perform here:
1325 // 1) lw $8, sym => lui $8, %hi(sym)
1326 // lw $8, %lo(sym)($8)
1327 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1329 // lw $8, %lo(offset)($9)
1330 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1332 // lw $8, %lo(offset)($at)
1333 // 4) sw $8, sym => lui $at, %hi(sym)
1334 // sw $8, %lo(sym)($at)
1335 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1337 // sw $8, %lo(offset)($at)
1338 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1339 // ldc1 $f0, %lo(sym)($at)
1341 // For load instructions we can use the destination register as a temporary
1342 // if base and dst are different (examples 1 and 2) and if the base register
1343 // is general purpose otherwise we must use $at (example 6) and error if it's
1344 // not available. For stores we must use $at (examples 4 and 5) because we
1345 // must not clobber the source register setting up the offset.
1346 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1347 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1348 unsigned RegClassIDOp0 =
1349 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1350 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1351 (RegClassIDOp0 == Mips::GPR64RegClassID);
1352 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1353 TmpRegNum = RegOpNum;
1355 int AT = getATReg(IDLoc);
1356 // At this point we need AT to perform the expansions and we exit if it is
1361 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1364 TempInst.setOpcode(Mips::LUi);
1365 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1367 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1369 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1370 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1371 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1372 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1374 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1376 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1377 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1380 // Add the instruction to the list.
1381 Instructions.push_back(TempInst);
1382 // Prepare TempInst for next instruction.
1384 // Add temp register to base.
1385 TempInst.setOpcode(Mips::ADDu);
1386 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1387 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1388 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1389 Instructions.push_back(TempInst);
1391 // And finally, create original instruction with low part
1392 // of offset and new base.
1393 TempInst.setOpcode(Inst.getOpcode());
1394 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1395 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1397 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1399 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1400 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1401 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1403 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1405 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1406 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1409 Instructions.push_back(TempInst);
1413 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1414 // As described by the Mips32r2 spec, the registers Rd and Rs for
1415 // jalr.hb must be different.
1416 unsigned Opcode = Inst.getOpcode();
1418 if (Opcode == Mips::JALR_HB &&
1419 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1420 return Match_RequiresDifferentSrcAndDst;
1422 return Match_Success;
1425 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1426 OperandVector &Operands,
1428 unsigned &ErrorInfo,
1429 bool MatchingInlineAsm) {
1432 SmallVector<MCInst, 8> Instructions;
1433 unsigned MatchResult =
1434 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1436 switch (MatchResult) {
1439 case Match_Success: {
1440 if (processInstruction(Inst, IDLoc, Instructions))
1442 for (unsigned i = 0; i < Instructions.size(); i++)
1443 Out.EmitInstruction(Instructions[i], STI);
1446 case Match_MissingFeature:
1447 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1449 case Match_InvalidOperand: {
1450 SMLoc ErrorLoc = IDLoc;
1451 if (ErrorInfo != ~0U) {
1452 if (ErrorInfo >= Operands.size())
1453 return Error(IDLoc, "too few operands for instruction");
1455 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1456 if (ErrorLoc == SMLoc())
1460 return Error(ErrorLoc, "invalid operand for instruction");
1462 case Match_MnemonicFail:
1463 return Error(IDLoc, "invalid instruction");
1464 case Match_RequiresDifferentSrcAndDst:
1465 return Error(IDLoc, "source and destination must be different");
1470 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1471 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1473 Warning(Loc, "Used $at without \".set noat\"");
1475 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1476 Twine(RegIndex) + "\"");
1480 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1483 CC = StringSwitch<unsigned>(Name)
1519 if (isABI_N32() || isABI_N64()) {
1520 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1521 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1522 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1523 if (8 <= CC && CC <= 11)
1527 CC = StringSwitch<unsigned>(Name)
1540 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1542 if (Name[0] == 'f') {
1543 StringRef NumString = Name.substr(1);
1545 if (NumString.getAsInteger(10, IntVal))
1546 return -1; // This is not an integer.
1547 if (IntVal > 31) // Maximum index for fpu register.
1554 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1556 if (Name.startswith("fcc")) {
1557 StringRef NumString = Name.substr(3);
1559 if (NumString.getAsInteger(10, IntVal))
1560 return -1; // This is not an integer.
1561 if (IntVal > 7) // There are only 8 fcc registers.
1568 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1570 if (Name.startswith("ac")) {
1571 StringRef NumString = Name.substr(2);
1573 if (NumString.getAsInteger(10, IntVal))
1574 return -1; // This is not an integer.
1575 if (IntVal > 3) // There are only 3 acc registers.
1582 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1585 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1594 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1597 CC = StringSwitch<unsigned>(Name)
1600 .Case("msaaccess", 2)
1602 .Case("msamodify", 4)
1603 .Case("msarequest", 5)
1605 .Case("msaunmap", 7)
1611 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1619 int MipsAsmParser::getATReg(SMLoc Loc) {
1620 int AT = Options.getATRegNum();
1622 reportParseError(Loc,
1623 "Pseudo instruction requires $at, which is not available");
1627 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1628 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1631 unsigned MipsAsmParser::getGPR(int RegNo) {
1632 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1636 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1638 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1641 return getReg(RegClass, RegNum);
1644 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1645 DEBUG(dbgs() << "ParseOperand\n");
1647 // Check if the current operand has a custom associated parser, if so, try to
1648 // custom parse the operand, or fallback to the general approach.
1649 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1650 if (ResTy == MatchOperand_Success)
1652 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1653 // there was a match, but an error occurred, in which case, just return that
1654 // the operand parsing failed.
1655 if (ResTy == MatchOperand_ParseFail)
1658 DEBUG(dbgs() << ".. Generic Parser\n");
1660 switch (getLexer().getKind()) {
1662 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1664 case AsmToken::Dollar: {
1665 // Parse the register.
1666 SMLoc S = Parser.getTok().getLoc();
1668 // Almost all registers have been parsed by custom parsers. There is only
1669 // one exception to this. $zero (and it's alias $0) will reach this point
1670 // for div, divu, and similar instructions because it is not an operand
1671 // to the instruction definition but an explicit register. Special case
1672 // this situation for now.
1673 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1676 // Maybe it is a symbol reference.
1677 StringRef Identifier;
1678 if (Parser.parseIdentifier(Identifier))
1681 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1682 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1683 // Otherwise create a symbol reference.
1685 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1687 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1690 // Else drop to expression parsing.
1691 case AsmToken::LParen:
1692 case AsmToken::Minus:
1693 case AsmToken::Plus:
1694 case AsmToken::Integer:
1695 case AsmToken::Tilde:
1696 case AsmToken::String: {
1697 DEBUG(dbgs() << ".. generic integer\n");
1698 OperandMatchResultTy ResTy = ParseImm(Operands);
1699 return ResTy != MatchOperand_Success;
1701 case AsmToken::Percent: {
1702 // It is a symbol reference or constant expression.
1703 const MCExpr *IdVal;
1704 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1705 if (parseRelocOperand(IdVal))
1708 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1710 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1712 } // case AsmToken::Percent
1713 } // switch(getLexer().getKind())
1717 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1718 StringRef RelocStr) {
1720 // Check the type of the expression.
1721 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1722 // It's a constant, evaluate reloc value.
1724 switch (getVariantKind(RelocStr)) {
1725 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1726 // Get the 1st 16-bits.
1727 Val = MCE->getValue() & 0xffff;
1729 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1730 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1731 // 16 bits being negative.
1732 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1734 case MCSymbolRefExpr::VK_Mips_HIGHER:
1735 // Get the 3rd 16-bits.
1736 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1738 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1739 // Get the 4th 16-bits.
1740 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1743 report_fatal_error("Unsupported reloc value!");
1745 return MCConstantExpr::Create(Val, getContext());
1748 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1749 // It's a symbol, create a symbolic expression from the symbol.
1750 StringRef Symbol = MSRE->getSymbol().getName();
1751 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1752 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1756 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1757 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1759 // Try to create target expression.
1760 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1761 return MipsMCExpr::Create(VK, Expr, getContext());
1763 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1764 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1765 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1769 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1770 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1771 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1774 // Just return the original expression.
1778 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1780 switch (Expr->getKind()) {
1781 case MCExpr::Constant:
1783 case MCExpr::SymbolRef:
1784 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1785 case MCExpr::Binary:
1786 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1787 if (!isEvaluated(BE->getLHS()))
1789 return isEvaluated(BE->getRHS());
1792 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1793 case MCExpr::Target:
1799 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1800 Parser.Lex(); // Eat the % token.
1801 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1802 if (Tok.isNot(AsmToken::Identifier))
1805 std::string Str = Tok.getIdentifier().str();
1807 Parser.Lex(); // Eat the identifier.
1808 // Now make an expression from the rest of the operand.
1809 const MCExpr *IdVal;
1812 if (getLexer().getKind() == AsmToken::LParen) {
1814 Parser.Lex(); // Eat the '(' token.
1815 if (getLexer().getKind() == AsmToken::Percent) {
1816 Parser.Lex(); // Eat the % token.
1817 const AsmToken &nextTok = Parser.getTok();
1818 if (nextTok.isNot(AsmToken::Identifier))
1821 Str += nextTok.getIdentifier();
1822 Parser.Lex(); // Eat the identifier.
1823 if (getLexer().getKind() != AsmToken::LParen)
1828 if (getParser().parseParenExpression(IdVal, EndLoc))
1831 while (getLexer().getKind() == AsmToken::RParen)
1832 Parser.Lex(); // Eat the ')' token.
1835 return true; // Parenthesis must follow the relocation operand.
1837 Res = evaluateRelocExpr(IdVal, Str);
1841 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1843 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1844 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1845 if (ResTy == MatchOperand_Success) {
1846 assert(Operands.size() == 1);
1847 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1848 StartLoc = Operand.getStartLoc();
1849 EndLoc = Operand.getEndLoc();
1851 // AFAIK, we only support numeric registers and named GPR's in CFI
1853 // Don't worry about eating tokens before failing. Using an unrecognised
1854 // register is a parse error.
1855 if (Operand.isGPRAsmReg()) {
1856 // Resolve to GPR32 or GPR64 appropriately.
1857 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1860 return (RegNo == (unsigned)-1);
1863 assert(Operands.size() == 0);
1864 return (RegNo == (unsigned)-1);
1867 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1871 while (getLexer().getKind() == AsmToken::LParen)
1874 switch (getLexer().getKind()) {
1877 case AsmToken::Identifier:
1878 case AsmToken::LParen:
1879 case AsmToken::Integer:
1880 case AsmToken::Minus:
1881 case AsmToken::Plus:
1883 Result = getParser().parseParenExpression(Res, S);
1885 Result = (getParser().parseExpression(Res));
1886 while (getLexer().getKind() == AsmToken::RParen)
1889 case AsmToken::Percent:
1890 Result = parseRelocOperand(Res);
1895 MipsAsmParser::OperandMatchResultTy
1896 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1897 DEBUG(dbgs() << "parseMemOperand\n");
1898 const MCExpr *IdVal = nullptr;
1900 bool isParenExpr = false;
1901 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1902 // First operand is the offset.
1903 S = Parser.getTok().getLoc();
1905 if (getLexer().getKind() == AsmToken::LParen) {
1910 if (getLexer().getKind() != AsmToken::Dollar) {
1911 if (parseMemOffset(IdVal, isParenExpr))
1912 return MatchOperand_ParseFail;
1914 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1915 if (Tok.isNot(AsmToken::LParen)) {
1916 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
1917 if (Mnemonic.getToken() == "la") {
1919 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1920 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1921 return MatchOperand_Success;
1923 if (Tok.is(AsmToken::EndOfStatement)) {
1925 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1927 // Zero register assumed, add a memory operand with ZERO as its base.
1928 // "Base" will be managed by k_Memory.
1929 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
1932 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
1933 return MatchOperand_Success;
1935 Error(Parser.getTok().getLoc(), "'(' expected");
1936 return MatchOperand_ParseFail;
1939 Parser.Lex(); // Eat the '(' token.
1942 Res = ParseAnyRegister(Operands);
1943 if (Res != MatchOperand_Success)
1946 if (Parser.getTok().isNot(AsmToken::RParen)) {
1947 Error(Parser.getTok().getLoc(), "')' expected");
1948 return MatchOperand_ParseFail;
1951 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1953 Parser.Lex(); // Eat the ')' token.
1956 IdVal = MCConstantExpr::Create(0, getContext());
1958 // Replace the register operand with the memory operand.
1959 std::unique_ptr<MipsOperand> op(
1960 static_cast<MipsOperand *>(Operands.back().release()));
1961 // Remove the register from the operands.
1962 // "op" will be managed by k_Memory.
1963 Operands.pop_back();
1964 // Add the memory operand.
1965 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1967 if (IdVal->EvaluateAsAbsolute(Imm))
1968 IdVal = MCConstantExpr::Create(Imm, getContext());
1969 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1970 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1974 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
1975 return MatchOperand_Success;
1978 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
1980 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1982 SMLoc S = Parser.getTok().getLoc();
1984 if (Sym->isVariable())
1985 Expr = Sym->getVariableValue();
1988 if (Expr->getKind() == MCExpr::SymbolRef) {
1989 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1990 const StringRef DefSymbol = Ref->getSymbol().getName();
1991 if (DefSymbol.startswith("$")) {
1992 OperandMatchResultTy ResTy =
1993 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
1994 if (ResTy == MatchOperand_Success) {
1997 } else if (ResTy == MatchOperand_ParseFail)
1998 llvm_unreachable("Should never ParseFail");
2001 } else if (Expr->getKind() == MCExpr::Constant) {
2003 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2005 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2012 MipsAsmParser::OperandMatchResultTy
2013 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2014 StringRef Identifier,
2016 int Index = matchCPURegisterName(Identifier);
2018 Operands.push_back(MipsOperand::CreateGPRReg(
2019 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2020 return MatchOperand_Success;
2023 Index = matchFPURegisterName(Identifier);
2025 Operands.push_back(MipsOperand::CreateFGRReg(
2026 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2027 return MatchOperand_Success;
2030 Index = matchFCCRegisterName(Identifier);
2032 Operands.push_back(MipsOperand::CreateFCCReg(
2033 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2034 return MatchOperand_Success;
2037 Index = matchACRegisterName(Identifier);
2039 Operands.push_back(MipsOperand::CreateACCReg(
2040 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2041 return MatchOperand_Success;
2044 Index = matchMSA128RegisterName(Identifier);
2046 Operands.push_back(MipsOperand::CreateMSA128Reg(
2047 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2048 return MatchOperand_Success;
2051 Index = matchMSA128CtrlRegisterName(Identifier);
2053 Operands.push_back(MipsOperand::CreateMSACtrlReg(
2054 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2055 return MatchOperand_Success;
2058 return MatchOperand_NoMatch;
2061 MipsAsmParser::OperandMatchResultTy
2062 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2063 auto Token = Parser.getLexer().peekTok(false);
2065 if (Token.is(AsmToken::Identifier)) {
2066 DEBUG(dbgs() << ".. identifier\n");
2067 StringRef Identifier = Token.getIdentifier();
2068 OperandMatchResultTy ResTy =
2069 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2071 } else if (Token.is(AsmToken::Integer)) {
2072 DEBUG(dbgs() << ".. integer\n");
2073 Operands.push_back(MipsOperand::CreateNumericReg(
2074 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2076 return MatchOperand_Success;
2079 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2081 return MatchOperand_NoMatch;
2084 MipsAsmParser::OperandMatchResultTy
2085 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
2086 DEBUG(dbgs() << "ParseAnyRegister\n");
2088 auto Token = Parser.getTok();
2090 SMLoc S = Token.getLoc();
2092 if (Token.isNot(AsmToken::Dollar)) {
2093 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2094 if (Token.is(AsmToken::Identifier)) {
2095 if (searchSymbolAlias(Operands))
2096 return MatchOperand_Success;
2098 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2099 return MatchOperand_NoMatch;
2101 DEBUG(dbgs() << ".. $\n");
2103 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
2104 if (ResTy == MatchOperand_Success) {
2106 Parser.Lex(); // identifier
2111 MipsAsmParser::OperandMatchResultTy
2112 MipsAsmParser::ParseImm(OperandVector &Operands) {
2113 switch (getLexer().getKind()) {
2115 return MatchOperand_NoMatch;
2116 case AsmToken::LParen:
2117 case AsmToken::Minus:
2118 case AsmToken::Plus:
2119 case AsmToken::Integer:
2120 case AsmToken::Tilde:
2121 case AsmToken::String:
2125 const MCExpr *IdVal;
2126 SMLoc S = Parser.getTok().getLoc();
2127 if (getParser().parseExpression(IdVal))
2128 return MatchOperand_ParseFail;
2130 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2131 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2132 return MatchOperand_Success;
2135 MipsAsmParser::OperandMatchResultTy
2136 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
2137 DEBUG(dbgs() << "ParseJumpTarget\n");
2139 SMLoc S = getLexer().getLoc();
2141 // Integers and expressions are acceptable
2142 OperandMatchResultTy ResTy = ParseImm(Operands);
2143 if (ResTy != MatchOperand_NoMatch)
2146 // Registers are a valid target and have priority over symbols.
2147 ResTy = ParseAnyRegister(Operands);
2148 if (ResTy != MatchOperand_NoMatch)
2151 const MCExpr *Expr = nullptr;
2152 if (Parser.parseExpression(Expr)) {
2153 // We have no way of knowing if a symbol was consumed so we must ParseFail
2154 return MatchOperand_ParseFail;
2157 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2158 return MatchOperand_Success;
2161 MipsAsmParser::OperandMatchResultTy
2162 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2163 const MCExpr *IdVal;
2164 // If the first token is '$' we may have register operand.
2165 if (Parser.getTok().is(AsmToken::Dollar))
2166 return MatchOperand_NoMatch;
2167 SMLoc S = Parser.getTok().getLoc();
2168 if (getParser().parseExpression(IdVal))
2169 return MatchOperand_ParseFail;
2170 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2171 assert(MCE && "Unexpected MCExpr type.");
2172 int64_t Val = MCE->getValue();
2173 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2174 Operands.push_back(MipsOperand::CreateImm(
2175 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2176 return MatchOperand_Success;
2179 MipsAsmParser::OperandMatchResultTy
2180 MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
2181 switch (getLexer().getKind()) {
2183 return MatchOperand_NoMatch;
2184 case AsmToken::LParen:
2185 case AsmToken::Plus:
2186 case AsmToken::Minus:
2187 case AsmToken::Integer:
2192 SMLoc S = Parser.getTok().getLoc();
2194 if (getParser().parseExpression(Expr))
2195 return MatchOperand_ParseFail;
2198 if (!Expr->EvaluateAsAbsolute(Val)) {
2199 Error(S, "expected immediate value");
2200 return MatchOperand_ParseFail;
2203 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2204 // and because the CPU always adds one to the immediate field, the allowed
2205 // range becomes 1..4. We'll only check the range here and will deal
2206 // with the addition/subtraction when actually decoding/encoding
2208 if (Val < 1 || Val > 4) {
2209 Error(S, "immediate not in range (1..4)");
2210 return MatchOperand_ParseFail;
2214 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2215 return MatchOperand_Success;
2218 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2220 MCSymbolRefExpr::VariantKind VK =
2221 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2222 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2223 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2224 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2225 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2226 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2227 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2228 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2229 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2230 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2231 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2232 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2233 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2234 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2235 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2236 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2237 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2238 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2239 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2240 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2241 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2242 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2243 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2244 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2245 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2246 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2247 .Default(MCSymbolRefExpr::VK_None);
2249 assert(VK != MCSymbolRefExpr::VK_None);
2254 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2256 /// ::= '(', register, ')'
2257 /// handle it before we iterate so we don't get tripped up by the lack of
2259 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2260 if (getLexer().is(AsmToken::LParen)) {
2262 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2264 if (ParseOperand(Operands, Name)) {
2265 SMLoc Loc = getLexer().getLoc();
2266 Parser.eatToEndOfStatement();
2267 return Error(Loc, "unexpected token in argument list");
2269 if (Parser.getTok().isNot(AsmToken::RParen)) {
2270 SMLoc Loc = getLexer().getLoc();
2271 Parser.eatToEndOfStatement();
2272 return Error(Loc, "unexpected token, expected ')'");
2275 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2281 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2282 /// either one of these.
2283 /// ::= '[', register, ']'
2284 /// ::= '[', integer, ']'
2285 /// handle it before we iterate so we don't get tripped up by the lack of
2287 bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2288 OperandVector &Operands) {
2289 if (getLexer().is(AsmToken::LBrac)) {
2291 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2293 if (ParseOperand(Operands, Name)) {
2294 SMLoc Loc = getLexer().getLoc();
2295 Parser.eatToEndOfStatement();
2296 return Error(Loc, "unexpected token in argument list");
2298 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2299 SMLoc Loc = getLexer().getLoc();
2300 Parser.eatToEndOfStatement();
2301 return Error(Loc, "unexpected token, expected ']'");
2304 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2310 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2311 SMLoc NameLoc, OperandVector &Operands) {
2312 DEBUG(dbgs() << "ParseInstruction\n");
2313 // We have reached first instruction, module directive after
2314 // this is forbidden.
2315 getTargetStreamer().setCanHaveModuleDir(false);
2316 // Check if we have valid mnemonic
2317 if (!mnemonicIsValid(Name, 0)) {
2318 Parser.eatToEndOfStatement();
2319 return Error(NameLoc, "Unknown instruction");
2321 // First operand in MCInst is instruction mnemonic.
2322 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2324 // Read the remaining operands.
2325 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2326 // Read the first operand.
2327 if (ParseOperand(Operands, Name)) {
2328 SMLoc Loc = getLexer().getLoc();
2329 Parser.eatToEndOfStatement();
2330 return Error(Loc, "unexpected token in argument list");
2332 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2334 // AFAIK, parenthesis suffixes are never on the first operand
2336 while (getLexer().is(AsmToken::Comma)) {
2337 Parser.Lex(); // Eat the comma.
2338 // Parse and remember the operand.
2339 if (ParseOperand(Operands, Name)) {
2340 SMLoc Loc = getLexer().getLoc();
2341 Parser.eatToEndOfStatement();
2342 return Error(Loc, "unexpected token in argument list");
2344 // Parse bracket and parenthesis suffixes before we iterate
2345 if (getLexer().is(AsmToken::LBrac)) {
2346 if (ParseBracketSuffix(Name, Operands))
2348 } else if (getLexer().is(AsmToken::LParen) &&
2349 ParseParenSuffix(Name, Operands))
2353 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2354 SMLoc Loc = getLexer().getLoc();
2355 Parser.eatToEndOfStatement();
2356 return Error(Loc, "unexpected token in argument list");
2358 Parser.Lex(); // Consume the EndOfStatement.
2362 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2363 SMLoc Loc = getLexer().getLoc();
2364 Parser.eatToEndOfStatement();
2365 return Error(Loc, ErrorMsg);
2368 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2369 return Error(Loc, ErrorMsg);
2372 bool MipsAsmParser::parseSetNoAtDirective() {
2373 // Line should look like: ".set noat".
2375 Options.setATReg(0);
2378 // If this is not the end of the statement, report an error.
2379 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2380 reportParseError("unexpected token in statement");
2383 Parser.Lex(); // Consume the EndOfStatement.
2387 bool MipsAsmParser::parseSetAtDirective() {
2388 // Line can be .set at - defaults to $1
2392 if (getLexer().is(AsmToken::EndOfStatement)) {
2393 Options.setATReg(1);
2394 Parser.Lex(); // Consume the EndOfStatement.
2396 } else if (getLexer().is(AsmToken::Equal)) {
2397 getParser().Lex(); // Eat the '='.
2398 if (getLexer().isNot(AsmToken::Dollar)) {
2399 reportParseError("unexpected token in statement");
2402 Parser.Lex(); // Eat the '$'.
2403 const AsmToken &Reg = Parser.getTok();
2404 if (Reg.is(AsmToken::Identifier)) {
2405 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2406 } else if (Reg.is(AsmToken::Integer)) {
2407 AtRegNo = Reg.getIntVal();
2409 reportParseError("unexpected token in statement");
2413 if (AtRegNo < 0 || AtRegNo > 31) {
2414 reportParseError("unexpected token in statement");
2418 if (!Options.setATReg(AtRegNo)) {
2419 reportParseError("unexpected token in statement");
2422 getParser().Lex(); // Eat the register.
2424 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2425 reportParseError("unexpected token in statement");
2428 Parser.Lex(); // Consume the EndOfStatement.
2431 reportParseError("unexpected token in statement");
2436 bool MipsAsmParser::parseSetReorderDirective() {
2438 // If this is not the end of the statement, report an error.
2439 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2440 reportParseError("unexpected token in statement");
2443 Options.setReorder();
2444 getTargetStreamer().emitDirectiveSetReorder();
2445 Parser.Lex(); // Consume the EndOfStatement.
2449 bool MipsAsmParser::parseSetNoReorderDirective() {
2451 // If this is not the end of the statement, report an error.
2452 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2453 reportParseError("unexpected token in statement");
2456 Options.setNoreorder();
2457 getTargetStreamer().emitDirectiveSetNoReorder();
2458 Parser.Lex(); // Consume the EndOfStatement.
2462 bool MipsAsmParser::parseSetMacroDirective() {
2464 // If this is not the end of the statement, report an error.
2465 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2466 reportParseError("unexpected token in statement");
2470 Parser.Lex(); // Consume the EndOfStatement.
2474 bool MipsAsmParser::parseSetNoMacroDirective() {
2476 // If this is not the end of the statement, report an error.
2477 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2478 reportParseError("`noreorder' must be set before `nomacro'");
2481 if (Options.isReorder()) {
2482 reportParseError("`noreorder' must be set before `nomacro'");
2485 Options.setNomacro();
2486 Parser.Lex(); // Consume the EndOfStatement.
2490 bool MipsAsmParser::parseSetNoMips16Directive() {
2492 // If this is not the end of the statement, report an error.
2493 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2494 reportParseError("unexpected token in statement");
2497 // For now do nothing.
2498 Parser.Lex(); // Consume the EndOfStatement.
2502 bool MipsAsmParser::parseSetFpDirective() {
2503 MipsABIFlagsSection::FpABIKind FpAbiVal;
2504 // Line can be: .set fp=32
2507 Parser.Lex(); // Eat fp token
2508 AsmToken Tok = Parser.getTok();
2509 if (Tok.isNot(AsmToken::Equal)) {
2510 reportParseError("unexpected token in statement");
2513 Parser.Lex(); // Eat '=' token.
2514 Tok = Parser.getTok();
2516 if (!parseFpABIValue(FpAbiVal, ".set"))
2519 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2520 reportParseError("unexpected token in statement");
2523 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2524 Parser.Lex(); // Consume the EndOfStatement.
2528 bool MipsAsmParser::parseSetAssignment() {
2530 const MCExpr *Value;
2532 if (Parser.parseIdentifier(Name))
2533 reportParseError("expected identifier after .set");
2535 if (getLexer().isNot(AsmToken::Comma))
2536 return reportParseError("unexpected token in .set directive");
2539 if (Parser.parseExpression(Value))
2540 return reportParseError("expected valid expression after comma");
2542 // Check if the Name already exists as a symbol.
2543 MCSymbol *Sym = getContext().LookupSymbol(Name);
2545 return reportParseError("symbol already defined");
2546 Sym = getContext().GetOrCreateSymbol(Name);
2547 Sym->setVariableValue(Value);
2552 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2554 if (getLexer().isNot(AsmToken::EndOfStatement))
2555 return reportParseError("unexpected token in .set directive");
2559 llvm_unreachable("Unimplemented feature");
2560 case Mips::FeatureDSP:
2561 setFeatureBits(Mips::FeatureDSP, "dsp");
2562 getTargetStreamer().emitDirectiveSetDsp();
2564 case Mips::FeatureMicroMips:
2565 getTargetStreamer().emitDirectiveSetMicroMips();
2567 case Mips::FeatureMips16:
2568 getTargetStreamer().emitDirectiveSetMips16();
2570 case Mips::FeatureMips1:
2571 selectArch("mips1");
2572 getTargetStreamer().emitDirectiveSetMips1();
2574 case Mips::FeatureMips2:
2575 selectArch("mips2");
2576 getTargetStreamer().emitDirectiveSetMips2();
2578 case Mips::FeatureMips3:
2579 selectArch("mips3");
2580 getTargetStreamer().emitDirectiveSetMips3();
2582 case Mips::FeatureMips4:
2583 selectArch("mips4");
2584 getTargetStreamer().emitDirectiveSetMips4();
2586 case Mips::FeatureMips5:
2587 selectArch("mips5");
2588 getTargetStreamer().emitDirectiveSetMips5();
2590 case Mips::FeatureMips32:
2591 selectArch("mips32");
2592 getTargetStreamer().emitDirectiveSetMips32();
2594 case Mips::FeatureMips32r2:
2595 selectArch("mips32r2");
2596 getTargetStreamer().emitDirectiveSetMips32R2();
2598 case Mips::FeatureMips32r6:
2599 selectArch("mips32r6");
2600 getTargetStreamer().emitDirectiveSetMips32R6();
2602 case Mips::FeatureMips64:
2603 selectArch("mips64");
2604 getTargetStreamer().emitDirectiveSetMips64();
2606 case Mips::FeatureMips64r2:
2607 selectArch("mips64r2");
2608 getTargetStreamer().emitDirectiveSetMips64R2();
2610 case Mips::FeatureMips64r6:
2611 selectArch("mips64r6");
2612 getTargetStreamer().emitDirectiveSetMips64R6();
2618 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2619 if (getLexer().isNot(AsmToken::Comma)) {
2620 SMLoc Loc = getLexer().getLoc();
2621 Parser.eatToEndOfStatement();
2622 return Error(Loc, ErrorStr);
2625 Parser.Lex(); // Eat the comma.
2629 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2630 if (Options.isReorder())
2631 Warning(Loc, ".cpload in reorder section");
2633 // FIXME: Warn if cpload is used in Mips16 mode.
2635 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2636 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2637 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2638 reportParseError("expected register containing function address");
2642 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2643 if (!RegOpnd.isGPRAsmReg()) {
2644 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2648 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2652 bool MipsAsmParser::parseDirectiveCPSetup() {
2655 bool SaveIsReg = true;
2657 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2658 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2659 if (ResTy == MatchOperand_NoMatch) {
2660 reportParseError("expected register containing function address");
2661 Parser.eatToEndOfStatement();
2665 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2666 if (!FuncRegOpnd.isGPRAsmReg()) {
2667 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2668 Parser.eatToEndOfStatement();
2672 FuncReg = FuncRegOpnd.getGPR32Reg();
2675 if (!eatComma("expected comma parsing directive"))
2678 ResTy = ParseAnyRegister(TmpReg);
2679 if (ResTy == MatchOperand_NoMatch) {
2680 const AsmToken &Tok = Parser.getTok();
2681 if (Tok.is(AsmToken::Integer)) {
2682 Save = Tok.getIntVal();
2686 reportParseError("expected save register or stack offset");
2687 Parser.eatToEndOfStatement();
2691 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2692 if (!SaveOpnd.isGPRAsmReg()) {
2693 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2694 Parser.eatToEndOfStatement();
2697 Save = SaveOpnd.getGPR32Reg();
2700 if (!eatComma("expected comma parsing directive"))
2704 if (Parser.parseIdentifier(Name))
2705 reportParseError("expected identifier");
2706 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2708 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2712 bool MipsAsmParser::parseDirectiveNaN() {
2713 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2714 const AsmToken &Tok = Parser.getTok();
2716 if (Tok.getString() == "2008") {
2718 getTargetStreamer().emitDirectiveNaN2008();
2720 } else if (Tok.getString() == "legacy") {
2722 getTargetStreamer().emitDirectiveNaNLegacy();
2726 // If we don't recognize the option passed to the .nan
2727 // directive (e.g. no option or unknown option), emit an error.
2728 reportParseError("invalid option in .nan directive");
2732 bool MipsAsmParser::parseDirectiveSet() {
2734 // Get the next token.
2735 const AsmToken &Tok = Parser.getTok();
2737 if (Tok.getString() == "noat") {
2738 return parseSetNoAtDirective();
2739 } else if (Tok.getString() == "at") {
2740 return parseSetAtDirective();
2741 } else if (Tok.getString() == "fp") {
2742 return parseSetFpDirective();
2743 } else if (Tok.getString() == "reorder") {
2744 return parseSetReorderDirective();
2745 } else if (Tok.getString() == "noreorder") {
2746 return parseSetNoReorderDirective();
2747 } else if (Tok.getString() == "macro") {
2748 return parseSetMacroDirective();
2749 } else if (Tok.getString() == "nomacro") {
2750 return parseSetNoMacroDirective();
2751 } else if (Tok.getString() == "mips16") {
2752 return parseSetFeature(Mips::FeatureMips16);
2753 } else if (Tok.getString() == "nomips16") {
2754 return parseSetNoMips16Directive();
2755 } else if (Tok.getString() == "nomicromips") {
2756 getTargetStreamer().emitDirectiveSetNoMicroMips();
2757 Parser.eatToEndOfStatement();
2759 } else if (Tok.getString() == "micromips") {
2760 return parseSetFeature(Mips::FeatureMicroMips);
2761 } else if (Tok.getString() == "mips1") {
2762 return parseSetFeature(Mips::FeatureMips1);
2763 } else if (Tok.getString() == "mips2") {
2764 return parseSetFeature(Mips::FeatureMips2);
2765 } else if (Tok.getString() == "mips3") {
2766 return parseSetFeature(Mips::FeatureMips3);
2767 } else if (Tok.getString() == "mips4") {
2768 return parseSetFeature(Mips::FeatureMips4);
2769 } else if (Tok.getString() == "mips5") {
2770 return parseSetFeature(Mips::FeatureMips5);
2771 } else if (Tok.getString() == "mips32") {
2772 return parseSetFeature(Mips::FeatureMips32);
2773 } else if (Tok.getString() == "mips32r2") {
2774 return parseSetFeature(Mips::FeatureMips32r2);
2775 } else if (Tok.getString() == "mips32r6") {
2776 return parseSetFeature(Mips::FeatureMips32r6);
2777 } else if (Tok.getString() == "mips64") {
2778 return parseSetFeature(Mips::FeatureMips64);
2779 } else if (Tok.getString() == "mips64r2") {
2780 return parseSetFeature(Mips::FeatureMips64r2);
2781 } else if (Tok.getString() == "mips64r6") {
2782 return parseSetFeature(Mips::FeatureMips64r6);
2783 } else if (Tok.getString() == "dsp") {
2784 return parseSetFeature(Mips::FeatureDSP);
2786 // It is just an identifier, look for an assignment.
2787 parseSetAssignment();
2794 /// parseDataDirective
2795 /// ::= .word [ expression (, expression)* ]
2796 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2797 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2799 const MCExpr *Value;
2800 if (getParser().parseExpression(Value))
2803 getParser().getStreamer().EmitValue(Value, Size);
2805 if (getLexer().is(AsmToken::EndOfStatement))
2808 // FIXME: Improve diagnostic.
2809 if (getLexer().isNot(AsmToken::Comma))
2810 return Error(L, "unexpected token in directive");
2819 /// parseDirectiveGpWord
2820 /// ::= .gpword local_sym
2821 bool MipsAsmParser::parseDirectiveGpWord() {
2822 const MCExpr *Value;
2823 // EmitGPRel32Value requires an expression, so we are using base class
2824 // method to evaluate the expression.
2825 if (getParser().parseExpression(Value))
2827 getParser().getStreamer().EmitGPRel32Value(Value);
2829 if (getLexer().isNot(AsmToken::EndOfStatement))
2830 return Error(getLexer().getLoc(), "unexpected token in directive");
2831 Parser.Lex(); // Eat EndOfStatement token.
2835 /// parseDirectiveGpDWord
2836 /// ::= .gpdword local_sym
2837 bool MipsAsmParser::parseDirectiveGpDWord() {
2838 const MCExpr *Value;
2839 // EmitGPRel64Value requires an expression, so we are using base class
2840 // method to evaluate the expression.
2841 if (getParser().parseExpression(Value))
2843 getParser().getStreamer().EmitGPRel64Value(Value);
2845 if (getLexer().isNot(AsmToken::EndOfStatement))
2846 return Error(getLexer().getLoc(), "unexpected token in directive");
2847 Parser.Lex(); // Eat EndOfStatement token.
2851 bool MipsAsmParser::parseDirectiveOption() {
2852 // Get the option token.
2853 AsmToken Tok = Parser.getTok();
2854 // At the moment only identifiers are supported.
2855 if (Tok.isNot(AsmToken::Identifier)) {
2856 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2857 Parser.eatToEndOfStatement();
2861 StringRef Option = Tok.getIdentifier();
2863 if (Option == "pic0") {
2864 getTargetStreamer().emitDirectiveOptionPic0();
2866 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2867 Error(Parser.getTok().getLoc(),
2868 "unexpected token in .option pic0 directive");
2869 Parser.eatToEndOfStatement();
2874 if (Option == "pic2") {
2875 getTargetStreamer().emitDirectiveOptionPic2();
2877 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2878 Error(Parser.getTok().getLoc(),
2879 "unexpected token in .option pic2 directive");
2880 Parser.eatToEndOfStatement();
2886 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2887 Parser.eatToEndOfStatement();
2891 /// parseDirectiveModule
2892 /// ::= .module oddspreg
2893 /// ::= .module nooddspreg
2894 /// ::= .module fp=value
2895 bool MipsAsmParser::parseDirectiveModule() {
2896 MCAsmLexer &Lexer = getLexer();
2897 SMLoc L = Lexer.getLoc();
2899 if (!getTargetStreamer().getCanHaveModuleDir()) {
2900 // TODO : get a better message.
2901 reportParseError(".module directive must appear before any code");
2905 if (Lexer.is(AsmToken::Identifier)) {
2906 StringRef Option = Parser.getTok().getString();
2909 if (Option == "oddspreg") {
2910 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
2911 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2913 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2914 reportParseError("Expected end of statement");
2919 } else if (Option == "nooddspreg") {
2921 Error(L, "'.module nooddspreg' requires the O32 ABI");
2925 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
2926 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2928 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2929 reportParseError("Expected end of statement");
2934 } else if (Option == "fp") {
2935 return parseDirectiveModuleFP();
2938 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
2944 /// parseDirectiveModuleFP
2948 bool MipsAsmParser::parseDirectiveModuleFP() {
2949 MCAsmLexer &Lexer = getLexer();
2951 if (Lexer.isNot(AsmToken::Equal)) {
2952 reportParseError("unexpected token in statement");
2955 Parser.Lex(); // Eat '=' token.
2957 MipsABIFlagsSection::FpABIKind FpABI;
2958 if (!parseFpABIValue(FpABI, ".module"))
2961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2962 reportParseError("unexpected token in statement");
2966 // Emit appropriate flags.
2967 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
2968 Parser.Lex(); // Consume the EndOfStatement.
2972 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
2973 StringRef Directive) {
2974 MCAsmLexer &Lexer = getLexer();
2976 if (Lexer.is(AsmToken::Identifier)) {
2977 StringRef Value = Parser.getTok().getString();
2980 if (Value != "xx") {
2981 reportParseError("unsupported value, expected 'xx', '32' or '64'");
2986 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
2990 FpABI = MipsABIFlagsSection::FpABIKind::XX;
2994 if (Lexer.is(AsmToken::Integer)) {
2995 unsigned Value = Parser.getTok().getIntVal();
2998 if (Value != 32 && Value != 64) {
2999 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3005 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3009 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3011 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3019 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3020 StringRef IDVal = DirectiveID.getString();
3022 if (IDVal == ".cpload")
3023 return parseDirectiveCPLoad(DirectiveID.getLoc());
3024 if (IDVal == ".dword") {
3025 parseDataDirective(8, DirectiveID.getLoc());
3029 if (IDVal == ".ent") {
3030 // Ignore this directive for now.
3035 if (IDVal == ".end") {
3036 // Ignore this directive for now.
3041 if (IDVal == ".frame") {
3042 // Ignore this directive for now.
3043 Parser.eatToEndOfStatement();
3047 if (IDVal == ".set") {
3048 return parseDirectiveSet();
3051 if (IDVal == ".fmask") {
3052 // Ignore this directive for now.
3053 Parser.eatToEndOfStatement();
3057 if (IDVal == ".mask") {
3058 // Ignore this directive for now.
3059 Parser.eatToEndOfStatement();
3063 if (IDVal == ".nan")
3064 return parseDirectiveNaN();
3066 if (IDVal == ".gpword") {
3067 parseDirectiveGpWord();
3071 if (IDVal == ".gpdword") {
3072 parseDirectiveGpDWord();
3076 if (IDVal == ".word") {
3077 parseDataDirective(4, DirectiveID.getLoc());
3081 if (IDVal == ".option")
3082 return parseDirectiveOption();
3084 if (IDVal == ".abicalls") {
3085 getTargetStreamer().emitDirectiveAbiCalls();
3086 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3087 Error(Parser.getTok().getLoc(), "unexpected token in directive");
3089 Parser.eatToEndOfStatement();
3094 if (IDVal == ".cpsetup")
3095 return parseDirectiveCPSetup();
3097 if (IDVal == ".module")
3098 return parseDirectiveModule();
3103 extern "C" void LLVMInitializeMipsAsmParser() {
3104 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3105 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3106 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3107 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3110 #define GET_REGISTER_MATCHER
3111 #define GET_MATCHER_IMPLEMENTATION
3112 #include "MipsGenAsmMatcher.inc"