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; }
62 class MipsAsmParser : public MCTargetAsmParser {
63 MipsTargetStreamer &getTargetStreamer() {
64 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
65 return static_cast<MipsTargetStreamer &>(TS);
70 MipsAssemblerOptions Options;
72 #define GET_ASSEMBLER_HEADER
73 #include "MipsGenAsmMatcher.inc"
75 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
76 SmallVectorImpl<MCParsedAsmOperand *> &Operands,
77 MCStreamer &Out, unsigned &ErrorInfo,
78 bool MatchingInlineAsm) override;
80 /// Parse a register as used in CFI directives
81 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
83 bool ParseParenSuffix(StringRef Name,
84 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
86 bool ParseBracketSuffix(StringRef Name,
87 SmallVectorImpl<MCParsedAsmOperand *> &Operands);
90 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
91 SmallVectorImpl<MCParsedAsmOperand *> &Operands) override;
93 bool ParseDirective(AsmToken DirectiveID) override;
95 MipsAsmParser::OperandMatchResultTy
96 parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
98 MipsAsmParser::OperandMatchResultTy MatchAnyRegisterNameWithoutDollar(
99 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
102 MipsAsmParser::OperandMatchResultTy
103 MatchAnyRegisterWithoutDollar(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
106 MipsAsmParser::OperandMatchResultTy
107 ParseAnyRegister(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
109 MipsAsmParser::OperandMatchResultTy
110 ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
112 MipsAsmParser::OperandMatchResultTy
113 ParseJumpTarget(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
115 MipsAsmParser::OperandMatchResultTy
116 parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
118 MipsAsmParser::OperandMatchResultTy
119 ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
121 bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
123 bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
126 bool needsExpansion(MCInst &Inst);
128 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
129 SmallVectorImpl<MCInst> &Instructions);
130 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
131 SmallVectorImpl<MCInst> &Instructions);
132 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
133 SmallVectorImpl<MCInst> &Instructions);
134 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
135 SmallVectorImpl<MCInst> &Instructions);
136 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
137 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
139 bool reportParseError(StringRef ErrorMsg);
140 bool reportParseError(SMLoc Loc, StringRef ErrorMsg);
142 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
143 bool parseRelocOperand(const MCExpr *&Res);
145 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
147 bool isEvaluated(const MCExpr *Expr);
148 bool parseSetFeature(uint64_t Feature);
149 bool parseDirectiveCPLoad(SMLoc Loc);
150 bool parseDirectiveCPSetup();
151 bool parseDirectiveNaN();
152 bool parseDirectiveSet();
153 bool parseDirectiveOption();
155 bool parseSetAtDirective();
156 bool parseSetNoAtDirective();
157 bool parseSetMacroDirective();
158 bool parseSetNoMacroDirective();
159 bool parseSetReorderDirective();
160 bool parseSetNoReorderDirective();
161 bool parseSetNoMips16Directive();
163 bool parseSetAssignment();
165 bool parseDataDirective(unsigned Size, SMLoc L);
166 bool parseDirectiveGpWord();
167 bool parseDirectiveGpDWord();
169 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
171 bool isGP64() const {
172 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
175 bool isFP64() const {
176 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
179 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
180 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
182 bool isMicroMips() const {
183 return STI.getFeatureBits() & Mips::FeatureMicroMips;
186 bool parseRegister(unsigned &RegNum);
188 bool eatComma(StringRef ErrorStr);
190 int matchCPURegisterName(StringRef Symbol);
192 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
194 int matchFPURegisterName(StringRef Name);
196 int matchFCCRegisterName(StringRef Name);
198 int matchACRegisterName(StringRef Name);
200 int matchMSA128RegisterName(StringRef Name);
202 int matchMSA128CtrlRegisterName(StringRef Name);
204 unsigned getReg(int RC, int RegNo);
206 unsigned getGPR(int RegNo);
210 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
211 SmallVectorImpl<MCInst> &Instructions);
213 // Helper function that checks if the value of a vector index is within the
214 // boundaries of accepted values for each RegisterKind
215 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
216 bool validateMSAIndex(int Val, int RegKind);
218 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
219 if (!(STI.getFeatureBits() & Feature)) {
220 setAvailableFeatures(
221 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
225 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
226 if (STI.getFeatureBits() & Feature) {
227 setAvailableFeatures(
228 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
233 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
234 const MCInstrInfo &MII,
235 const MCTargetOptions &Options)
236 : MCTargetAsmParser(), STI(sti), Parser(parser) {
237 // Initialize the set of available features.
238 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
240 // Assert exactly one ABI was chosen.
241 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
242 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
243 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
244 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
247 MCAsmParser &getParser() const { return Parser; }
248 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
250 /// Warn if RegNo is the current assembler temporary.
251 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
257 /// MipsOperand - Instances of this class represent a parsed Mips machine
259 class MipsOperand : public MCParsedAsmOperand {
261 /// Broad categories of register classes
262 /// The exact class is finalized by the render method.
264 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64())
265 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
267 RegKind_FCC = 4, /// FCC
268 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
269 RegKind_MSACtrl = 16, /// MSA control registers
270 RegKind_COP2 = 32, /// COP2
271 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
273 RegKind_CCR = 128, /// CCR
274 RegKind_HWRegs = 256, /// HWRegs
276 /// Potentially any (e.g. $1)
277 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
278 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
279 RegKind_CCR | RegKind_HWRegs
284 k_Immediate, /// An immediate (possibly involving symbol references)
285 k_Memory, /// Base + Offset Memory Address
286 k_PhysRegister, /// A physical register from the Mips namespace
287 k_RegisterIndex, /// A register index in one or more RegKind.
288 k_Token /// A simple token
291 MipsOperand(KindTy K, MipsAsmParser &Parser)
292 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
294 /// For diagnostics, and checking the assembler temporary
295 MipsAsmParser &AsmParser;
303 unsigned Num; /// Register Number
307 unsigned Index; /// Index into the register class
308 RegKind Kind; /// Bitfield of the kinds it could possibly be
309 const MCRegisterInfo *RegInfo;
323 struct PhysRegOp PhysReg;
324 struct RegIdxOp RegIdx;
329 SMLoc StartLoc, EndLoc;
331 /// Internal constructor for register kinds
332 static MipsOperand *CreateReg(unsigned Index, RegKind RegKind,
333 const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
334 MipsAsmParser &Parser) {
335 MipsOperand *Op = new MipsOperand(k_RegisterIndex, Parser);
336 Op->RegIdx.Index = Index;
337 Op->RegIdx.RegInfo = RegInfo;
338 Op->RegIdx.Kind = RegKind;
345 /// Coerce the register to GPR32 and return the real register for the current
347 unsigned getGPR32Reg() const {
348 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
349 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
350 unsigned ClassID = Mips::GPR32RegClassID;
351 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
354 /// Coerce the register to GPR64 and return the real register for the current
356 unsigned getGPR64Reg() const {
357 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
358 unsigned ClassID = Mips::GPR64RegClassID;
359 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
363 /// Coerce the register to AFGR64 and return the real register for the current
365 unsigned getAFGR64Reg() const {
366 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
367 if (RegIdx.Index % 2 != 0)
368 AsmParser.Warning(StartLoc, "Float register should be even.");
369 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
370 .getRegister(RegIdx.Index / 2);
373 /// Coerce the register to FGR64 and return the real register for the current
375 unsigned getFGR64Reg() const {
376 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
377 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
378 .getRegister(RegIdx.Index);
381 /// Coerce the register to FGR32 and return the real register for the current
383 unsigned getFGR32Reg() const {
384 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
385 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
386 .getRegister(RegIdx.Index);
389 /// Coerce the register to FGRH32 and return the real register for the current
391 unsigned getFGRH32Reg() const {
392 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
393 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
394 .getRegister(RegIdx.Index);
397 /// Coerce the register to FCC and return the real register for the current
399 unsigned getFCCReg() const {
400 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
401 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
402 .getRegister(RegIdx.Index);
405 /// Coerce the register to MSA128 and return the real register for the current
407 unsigned getMSA128Reg() const {
408 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
409 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
411 unsigned ClassID = Mips::MSA128BRegClassID;
412 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
415 /// Coerce the register to MSACtrl and return the real register for the
417 unsigned getMSACtrlReg() const {
418 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
419 unsigned ClassID = Mips::MSACtrlRegClassID;
420 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
423 /// Coerce the register to COP2 and return the real register for the
425 unsigned getCOP2Reg() const {
426 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
427 unsigned ClassID = Mips::COP2RegClassID;
428 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
431 /// Coerce the register to ACC64DSP and return the real register for the
433 unsigned getACC64DSPReg() const {
434 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
435 unsigned ClassID = Mips::ACC64DSPRegClassID;
436 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
439 /// Coerce the register to HI32DSP and return the real register for the
441 unsigned getHI32DSPReg() const {
442 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
443 unsigned ClassID = Mips::HI32DSPRegClassID;
444 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
447 /// Coerce the register to LO32DSP and return the real register for the
449 unsigned getLO32DSPReg() const {
450 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
451 unsigned ClassID = Mips::LO32DSPRegClassID;
452 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
455 /// Coerce the register to CCR and return the real register for the
457 unsigned getCCRReg() const {
458 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
459 unsigned ClassID = Mips::CCRRegClassID;
460 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
463 /// Coerce the register to HWRegs and return the real register for the
465 unsigned getHWRegsReg() const {
466 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
467 unsigned ClassID = Mips::HWRegsRegClassID;
468 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
472 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
473 // Add as immediate when possible. Null MCExpr = 0.
475 Inst.addOperand(MCOperand::CreateImm(0));
476 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
477 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
479 Inst.addOperand(MCOperand::CreateExpr(Expr));
482 void addRegOperands(MCInst &Inst, unsigned N) const {
483 llvm_unreachable("Use a custom parser instead");
486 /// Render the operand to an MCInst as a GPR32
487 /// Asserts if the wrong number of operands are requested, or the operand
488 /// is not a k_RegisterIndex compatible with RegKind_GPR
489 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
490 assert(N == 1 && "Invalid number of operands!");
491 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
494 /// Render the operand to an MCInst as a GPR64
495 /// Asserts if the wrong number of operands are requested, or the operand
496 /// is not a k_RegisterIndex compatible with RegKind_GPR
497 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
498 assert(N == 1 && "Invalid number of operands!");
499 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
502 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
503 assert(N == 1 && "Invalid number of operands!");
504 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
507 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
508 assert(N == 1 && "Invalid number of operands!");
509 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
512 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
513 assert(N == 1 && "Invalid number of operands!");
514 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
517 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
518 assert(N == 1 && "Invalid number of operands!");
519 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
522 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
523 assert(N == 1 && "Invalid number of operands!");
524 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
527 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
528 assert(N == 1 && "Invalid number of operands!");
529 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
532 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
533 assert(N == 1 && "Invalid number of operands!");
534 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
537 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
538 assert(N == 1 && "Invalid number of operands!");
539 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
542 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
543 assert(N == 1 && "Invalid number of operands!");
544 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
547 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
548 assert(N == 1 && "Invalid number of operands!");
549 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
552 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
553 assert(N == 1 && "Invalid number of operands!");
554 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
557 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
558 assert(N == 1 && "Invalid number of operands!");
559 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
562 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
563 assert(N == 1 && "Invalid number of operands!");
564 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
567 void addImmOperands(MCInst &Inst, unsigned N) const {
568 assert(N == 1 && "Invalid number of operands!");
569 const MCExpr *Expr = getImm();
573 void addMemOperands(MCInst &Inst, unsigned N) const {
574 assert(N == 2 && "Invalid number of operands!");
576 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
578 const MCExpr *Expr = getMemOff();
582 bool isReg() const override {
583 // As a special case until we sort out the definition of div/divu, pretend
584 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
585 if (isGPRAsmReg() && RegIdx.Index == 0)
588 return Kind == k_PhysRegister;
590 bool isRegIdx() const { return Kind == k_RegisterIndex; }
591 bool isImm() const override { return Kind == k_Immediate; }
592 bool isConstantImm() const {
593 return isImm() && dyn_cast<MCConstantExpr>(getImm());
595 bool isToken() const override {
596 // Note: It's not possible to pretend that other operand kinds are tokens.
597 // The matcher emitter checks tokens first.
598 return Kind == k_Token;
600 bool isMem() const override { return Kind == k_Memory; }
601 bool isInvNum() const { return Kind == k_Immediate; }
602 bool isLSAImm() const {
603 if (!isConstantImm())
605 int64_t Val = getConstantImm();
606 return 1 <= Val && Val <= 4;
609 StringRef getToken() const {
610 assert(Kind == k_Token && "Invalid access!");
611 return StringRef(Tok.Data, Tok.Length);
614 unsigned getReg() const override {
615 // As a special case until we sort out the definition of div/divu, pretend
616 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
617 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
618 RegIdx.Kind & RegKind_GPR)
619 return getGPR32Reg(); // FIXME: GPR64 too
621 assert(Kind == k_PhysRegister && "Invalid access!");
625 const MCExpr *getImm() const {
626 assert((Kind == k_Immediate) && "Invalid access!");
630 int64_t getConstantImm() const {
631 const MCExpr *Val = getImm();
632 return static_cast<const MCConstantExpr *>(Val)->getValue();
635 MipsOperand *getMemBase() const {
636 assert((Kind == k_Memory) && "Invalid access!");
640 const MCExpr *getMemOff() const {
641 assert((Kind == k_Memory) && "Invalid access!");
645 static MipsOperand *CreateToken(StringRef Str, SMLoc S,
646 MipsAsmParser &Parser) {
647 MipsOperand *Op = new MipsOperand(k_Token, Parser);
648 Op->Tok.Data = Str.data();
649 Op->Tok.Length = Str.size();
655 /// Create a numeric register (e.g. $1). The exact register remains
656 /// unresolved until an instruction successfully matches
657 static MipsOperand *CreateNumericReg(unsigned Index,
658 const MCRegisterInfo *RegInfo, SMLoc S,
659 SMLoc E, MipsAsmParser &Parser) {
660 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
661 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
664 /// Create a register that is definitely a GPR.
665 /// This is typically only used for named registers such as $gp.
666 static MipsOperand *CreateGPRReg(unsigned Index,
667 const MCRegisterInfo *RegInfo, SMLoc S,
668 SMLoc E, MipsAsmParser &Parser) {
669 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
672 /// Create a register that is definitely a FGR.
673 /// This is typically only used for named registers such as $f0.
674 static MipsOperand *CreateFGRReg(unsigned Index,
675 const MCRegisterInfo *RegInfo, SMLoc S,
676 SMLoc E, MipsAsmParser &Parser) {
677 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
680 /// Create a register that is definitely an FCC.
681 /// This is typically only used for named registers such as $fcc0.
682 static MipsOperand *CreateFCCReg(unsigned Index,
683 const MCRegisterInfo *RegInfo, SMLoc S,
684 SMLoc E, MipsAsmParser &Parser) {
685 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
688 /// Create a register that is definitely an ACC.
689 /// This is typically only used for named registers such as $ac0.
690 static MipsOperand *CreateACCReg(unsigned Index,
691 const MCRegisterInfo *RegInfo, SMLoc S,
692 SMLoc E, MipsAsmParser &Parser) {
693 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
696 /// Create a register that is definitely an MSA128.
697 /// This is typically only used for named registers such as $w0.
698 static MipsOperand *CreateMSA128Reg(unsigned Index,
699 const MCRegisterInfo *RegInfo, SMLoc S,
700 SMLoc E, MipsAsmParser &Parser) {
701 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
704 /// Create a register that is definitely an MSACtrl.
705 /// This is typically only used for named registers such as $msaaccess.
706 static MipsOperand *CreateMSACtrlReg(unsigned Index,
707 const MCRegisterInfo *RegInfo, SMLoc S,
708 SMLoc E, MipsAsmParser &Parser) {
709 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
712 static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E,
713 MipsAsmParser &Parser) {
714 MipsOperand *Op = new MipsOperand(k_Immediate, Parser);
721 static MipsOperand *CreateMem(MipsOperand *Base, const MCExpr *Off, SMLoc S,
722 SMLoc E, MipsAsmParser &Parser) {
723 MipsOperand *Op = new MipsOperand(k_Memory, Parser);
731 bool isGPRAsmReg() const {
732 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
734 bool isFGRAsmReg() const {
735 // AFGR64 is $0-$15 but we handle this in getAFGR64()
736 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
738 bool isHWRegsAsmReg() const {
739 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
741 bool isCCRAsmReg() const {
742 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
744 bool isFCCAsmReg() const {
745 return isRegIdx() && RegIdx.Kind & RegKind_FCC && RegIdx.Index <= 7;
747 bool isACCAsmReg() const {
748 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
750 bool isCOP2AsmReg() const {
751 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
753 bool isMSA128AsmReg() const {
754 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
756 bool isMSACtrlAsmReg() const {
757 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
760 /// getStartLoc - Get the location of the first token of this operand.
761 SMLoc getStartLoc() const override { return StartLoc; }
762 /// getEndLoc - Get the location of the last token of this operand.
763 SMLoc getEndLoc() const override { return EndLoc; }
765 virtual ~MipsOperand() {
773 case k_RegisterIndex:
779 void print(raw_ostream &OS) const override {
794 OS << "PhysReg<" << PhysReg.Num << ">";
796 case k_RegisterIndex:
797 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
804 }; // class MipsOperand
808 extern const MCInstrDesc MipsInsts[];
810 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
811 return MipsInsts[Opcode];
814 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
815 SmallVectorImpl<MCInst> &Instructions) {
816 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
820 if (MCID.isBranch() || MCID.isCall()) {
821 const unsigned Opcode = Inst.getOpcode();
831 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
832 Offset = Inst.getOperand(2);
834 break; // We'll deal with this situation later on when applying fixups.
835 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
836 return Error(IDLoc, "branch target out of range");
837 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
838 return Error(IDLoc, "branch to misaligned address");
852 case Mips::BGEZAL_MM:
853 case Mips::BLTZAL_MM:
856 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
857 Offset = Inst.getOperand(1);
859 break; // We'll deal with this situation later on when applying fixups.
860 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
861 return Error(IDLoc, "branch target out of range");
862 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
863 return Error(IDLoc, "branch to misaligned address");
868 if (MCID.hasDelaySlot() && Options.isReorder()) {
869 // If this instruction has a delay slot and .set reorder is active,
870 // emit a NOP after it.
871 Instructions.push_back(Inst);
873 NopInst.setOpcode(Mips::SLL);
874 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
875 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
876 NopInst.addOperand(MCOperand::CreateImm(0));
877 Instructions.push_back(NopInst);
881 if (MCID.mayLoad() || MCID.mayStore()) {
882 // Check the offset of memory operand, if it is a symbol
883 // reference or immediate we may have to expand instructions.
884 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
885 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
886 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
887 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
888 MCOperand &Op = Inst.getOperand(i);
890 int MemOffset = Op.getImm();
891 if (MemOffset < -32768 || MemOffset > 32767) {
892 // Offset can't exceed 16bit value.
893 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
896 } else if (Op.isExpr()) {
897 const MCExpr *Expr = Op.getExpr();
898 if (Expr->getKind() == MCExpr::SymbolRef) {
899 const MCSymbolRefExpr *SR =
900 static_cast<const MCSymbolRefExpr *>(Expr);
901 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
903 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
906 } else if (!isEvaluated(Expr)) {
907 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
915 if (needsExpansion(Inst))
916 expandInstruction(Inst, IDLoc, Instructions);
918 Instructions.push_back(Inst);
923 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
925 switch (Inst.getOpcode()) {
926 case Mips::LoadImm32Reg:
927 case Mips::LoadAddr32Imm:
928 case Mips::LoadAddr32Reg:
935 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
936 SmallVectorImpl<MCInst> &Instructions) {
937 switch (Inst.getOpcode()) {
938 case Mips::LoadImm32Reg:
939 return expandLoadImm(Inst, IDLoc, Instructions);
940 case Mips::LoadAddr32Imm:
941 return expandLoadAddressImm(Inst, IDLoc, Instructions);
942 case Mips::LoadAddr32Reg:
943 return expandLoadAddressReg(Inst, IDLoc, Instructions);
947 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
948 SmallVectorImpl<MCInst> &Instructions) {
950 const MCOperand &ImmOp = Inst.getOperand(1);
951 assert(ImmOp.isImm() && "expected immediate operand kind");
952 const MCOperand &RegOp = Inst.getOperand(0);
953 assert(RegOp.isReg() && "expected register operand kind");
955 int ImmValue = ImmOp.getImm();
956 tmpInst.setLoc(IDLoc);
957 if (0 <= ImmValue && ImmValue <= 65535) {
958 // For 0 <= j <= 65535.
959 // li d,j => ori d,$zero,j
960 tmpInst.setOpcode(Mips::ORi);
961 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
962 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
963 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
964 Instructions.push_back(tmpInst);
965 } else if (ImmValue < 0 && ImmValue >= -32768) {
966 // For -32768 <= j < 0.
967 // li d,j => addiu d,$zero,j
968 tmpInst.setOpcode(Mips::ADDiu);
969 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
970 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
971 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
972 Instructions.push_back(tmpInst);
974 // For any other value of j that is representable as a 32-bit integer.
975 // li d,j => lui d,hi16(j)
977 tmpInst.setOpcode(Mips::LUi);
978 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
979 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
980 Instructions.push_back(tmpInst);
982 tmpInst.setOpcode(Mips::ORi);
983 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
984 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
985 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
986 tmpInst.setLoc(IDLoc);
987 Instructions.push_back(tmpInst);
992 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
993 SmallVectorImpl<MCInst> &Instructions) {
995 const MCOperand &ImmOp = Inst.getOperand(2);
996 assert(ImmOp.isImm() && "expected immediate operand kind");
997 const MCOperand &SrcRegOp = Inst.getOperand(1);
998 assert(SrcRegOp.isReg() && "expected register operand kind");
999 const MCOperand &DstRegOp = Inst.getOperand(0);
1000 assert(DstRegOp.isReg() && "expected register operand kind");
1001 int ImmValue = ImmOp.getImm();
1002 if (-32768 <= ImmValue && ImmValue <= 65535) {
1003 // For -32768 <= j <= 65535.
1004 // la d,j(s) => addiu d,s,j
1005 tmpInst.setOpcode(Mips::ADDiu);
1006 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1007 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1008 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1009 Instructions.push_back(tmpInst);
1011 // For any other value of j that is representable as a 32-bit integer.
1012 // la d,j(s) => lui d,hi16(j)
1015 tmpInst.setOpcode(Mips::LUi);
1016 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1017 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1018 Instructions.push_back(tmpInst);
1020 tmpInst.setOpcode(Mips::ORi);
1021 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1022 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1023 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1024 Instructions.push_back(tmpInst);
1026 tmpInst.setOpcode(Mips::ADDu);
1027 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1028 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1029 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1030 Instructions.push_back(tmpInst);
1035 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1036 SmallVectorImpl<MCInst> &Instructions) {
1038 const MCOperand &ImmOp = Inst.getOperand(1);
1039 assert(ImmOp.isImm() && "expected immediate operand kind");
1040 const MCOperand &RegOp = Inst.getOperand(0);
1041 assert(RegOp.isReg() && "expected register operand kind");
1042 int ImmValue = ImmOp.getImm();
1043 if (-32768 <= ImmValue && ImmValue <= 65535) {
1044 // For -32768 <= j <= 65535.
1045 // la d,j => addiu d,$zero,j
1046 tmpInst.setOpcode(Mips::ADDiu);
1047 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1048 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1049 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1050 Instructions.push_back(tmpInst);
1052 // For any other value of j that is representable as a 32-bit integer.
1053 // la d,j => lui d,hi16(j)
1055 tmpInst.setOpcode(Mips::LUi);
1056 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1057 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1058 Instructions.push_back(tmpInst);
1060 tmpInst.setOpcode(Mips::ORi);
1061 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1062 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1063 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1064 Instructions.push_back(tmpInst);
1068 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1069 SmallVectorImpl<MCInst> &Instructions,
1070 bool isLoad, bool isImmOpnd) {
1071 const MCSymbolRefExpr *SR;
1073 unsigned ImmOffset, HiOffset, LoOffset;
1074 const MCExpr *ExprOffset;
1076 unsigned AtRegNum = getReg(
1077 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
1078 // 1st operand is either the source or destination register.
1079 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1080 unsigned RegOpNum = Inst.getOperand(0).getReg();
1081 // 2nd operand is the base register.
1082 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1083 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1084 // 3rd operand is either an immediate or expression.
1086 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1087 ImmOffset = Inst.getOperand(2).getImm();
1088 LoOffset = ImmOffset & 0x0000ffff;
1089 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1090 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1091 if (LoOffset & 0x8000)
1094 ExprOffset = Inst.getOperand(2).getExpr();
1095 // All instructions will have the same location.
1096 TempInst.setLoc(IDLoc);
1097 // 1st instruction in expansion is LUi. For load instruction we can use
1098 // the dst register as a temporary if base and dst are different,
1099 // but for stores we must use $at.
1100 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
1101 TempInst.setOpcode(Mips::LUi);
1102 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1104 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1106 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1107 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1108 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1109 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1111 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1113 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1114 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1117 // Add the instruction to the list.
1118 Instructions.push_back(TempInst);
1119 // Prepare TempInst for next instruction.
1121 // Add temp register to base.
1122 TempInst.setOpcode(Mips::ADDu);
1123 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1124 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1125 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1126 Instructions.push_back(TempInst);
1128 // And finally, create original instruction with low part
1129 // of offset and new base.
1130 TempInst.setOpcode(Inst.getOpcode());
1131 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1132 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1134 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1136 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1137 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1138 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1140 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1142 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1143 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1146 Instructions.push_back(TempInst);
1150 bool MipsAsmParser::MatchAndEmitInstruction(
1151 SMLoc IDLoc, unsigned &Opcode,
1152 SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
1153 unsigned &ErrorInfo, bool MatchingInlineAsm) {
1155 SmallVector<MCInst, 8> Instructions;
1156 unsigned MatchResult =
1157 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1159 switch (MatchResult) {
1162 case Match_Success: {
1163 if (processInstruction(Inst, IDLoc, Instructions))
1165 for (unsigned i = 0; i < Instructions.size(); i++)
1166 Out.EmitInstruction(Instructions[i], STI);
1169 case Match_MissingFeature:
1170 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1172 case Match_InvalidOperand: {
1173 SMLoc ErrorLoc = IDLoc;
1174 if (ErrorInfo != ~0U) {
1175 if (ErrorInfo >= Operands.size())
1176 return Error(IDLoc, "too few operands for instruction");
1178 ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
1179 if (ErrorLoc == SMLoc())
1183 return Error(ErrorLoc, "invalid operand for instruction");
1185 case Match_MnemonicFail:
1186 return Error(IDLoc, "invalid instruction");
1191 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1192 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1194 Warning(Loc, "Used $at without \".set noat\"");
1196 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1197 Twine(RegIndex) + "\"");
1201 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1204 CC = StringSwitch<unsigned>(Name)
1240 if (isN32() || isN64()) {
1241 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1242 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1243 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1244 if (8 <= CC && CC <= 11)
1248 CC = StringSwitch<unsigned>(Name)
1261 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1263 if (Name[0] == 'f') {
1264 StringRef NumString = Name.substr(1);
1266 if (NumString.getAsInteger(10, IntVal))
1267 return -1; // This is not an integer.
1268 if (IntVal > 31) // Maximum index for fpu register.
1275 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1277 if (Name.startswith("fcc")) {
1278 StringRef NumString = Name.substr(3);
1280 if (NumString.getAsInteger(10, IntVal))
1281 return -1; // This is not an integer.
1282 if (IntVal > 7) // There are only 8 fcc registers.
1289 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1291 if (Name.startswith("ac")) {
1292 StringRef NumString = Name.substr(2);
1294 if (NumString.getAsInteger(10, IntVal))
1295 return -1; // This is not an integer.
1296 if (IntVal > 3) // There are only 3 acc registers.
1303 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1306 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1315 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1318 CC = StringSwitch<unsigned>(Name)
1321 .Case("msaaccess", 2)
1323 .Case("msamodify", 4)
1324 .Case("msarequest", 5)
1326 .Case("msaunmap", 7)
1332 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1340 int MipsAsmParser::getATReg() {
1341 int AT = Options.getATRegNum();
1343 TokError("Pseudo instruction requires $at, which is not available");
1347 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1348 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1351 unsigned MipsAsmParser::getGPR(int RegNo) {
1352 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1356 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1358 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1361 return getReg(RegClass, RegNum);
1365 MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1366 StringRef Mnemonic) {
1367 DEBUG(dbgs() << "ParseOperand\n");
1369 // Check if the current operand has a custom associated parser, if so, try to
1370 // custom parse the operand, or fallback to the general approach.
1371 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1372 if (ResTy == MatchOperand_Success)
1374 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1375 // there was a match, but an error occurred, in which case, just return that
1376 // the operand parsing failed.
1377 if (ResTy == MatchOperand_ParseFail)
1380 DEBUG(dbgs() << ".. Generic Parser\n");
1382 switch (getLexer().getKind()) {
1384 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1386 case AsmToken::Dollar: {
1387 // Parse the register.
1388 SMLoc S = Parser.getTok().getLoc();
1390 // Almost all registers have been parsed by custom parsers. There is only
1391 // one exception to this. $zero (and it's alias $0) will reach this point
1392 // for div, divu, and similar instructions because it is not an operand
1393 // to the instruction definition but an explicit register. Special case
1394 // this situation for now.
1395 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1398 // Maybe it is a symbol reference.
1399 StringRef Identifier;
1400 if (Parser.parseIdentifier(Identifier))
1403 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1404 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1405 // Otherwise create a symbol reference.
1407 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1409 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1412 // Else drop to expression parsing.
1413 case AsmToken::LParen:
1414 case AsmToken::Minus:
1415 case AsmToken::Plus:
1416 case AsmToken::Integer:
1417 case AsmToken::String: {
1418 DEBUG(dbgs() << ".. generic integer\n");
1419 OperandMatchResultTy ResTy = ParseImm(Operands);
1420 return ResTy != MatchOperand_Success;
1422 case AsmToken::Percent: {
1423 // It is a symbol reference or constant expression.
1424 const MCExpr *IdVal;
1425 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1426 if (parseRelocOperand(IdVal))
1429 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1431 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1433 } // case AsmToken::Percent
1434 } // switch(getLexer().getKind())
1438 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1439 StringRef RelocStr) {
1441 // Check the type of the expression.
1442 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1443 // It's a constant, evaluate reloc value.
1445 switch (getVariantKind(RelocStr)) {
1446 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1447 // Get the 1st 16-bits.
1448 Val = MCE->getValue() & 0xffff;
1450 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1451 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1452 // 16 bits being negative.
1453 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1455 case MCSymbolRefExpr::VK_Mips_HIGHER:
1456 // Get the 3rd 16-bits.
1457 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1459 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1460 // Get the 4th 16-bits.
1461 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1464 report_fatal_error("Unsupported reloc value!");
1466 return MCConstantExpr::Create(Val, getContext());
1469 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1470 // It's a symbol, create a symbolic expression from the symbol.
1471 StringRef Symbol = MSRE->getSymbol().getName();
1472 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1473 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1477 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1478 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1480 // Try to create target expression.
1481 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1482 return MipsMCExpr::Create(VK, Expr, getContext());
1484 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1485 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1486 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1490 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1491 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1492 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1495 // Just return the original expression.
1499 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1501 switch (Expr->getKind()) {
1502 case MCExpr::Constant:
1504 case MCExpr::SymbolRef:
1505 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1506 case MCExpr::Binary:
1507 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1508 if (!isEvaluated(BE->getLHS()))
1510 return isEvaluated(BE->getRHS());
1513 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1514 case MCExpr::Target:
1520 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1521 Parser.Lex(); // Eat the % token.
1522 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1523 if (Tok.isNot(AsmToken::Identifier))
1526 std::string Str = Tok.getIdentifier().str();
1528 Parser.Lex(); // Eat the identifier.
1529 // Now make an expression from the rest of the operand.
1530 const MCExpr *IdVal;
1533 if (getLexer().getKind() == AsmToken::LParen) {
1535 Parser.Lex(); // Eat the '(' token.
1536 if (getLexer().getKind() == AsmToken::Percent) {
1537 Parser.Lex(); // Eat the % token.
1538 const AsmToken &nextTok = Parser.getTok();
1539 if (nextTok.isNot(AsmToken::Identifier))
1542 Str += nextTok.getIdentifier();
1543 Parser.Lex(); // Eat the identifier.
1544 if (getLexer().getKind() != AsmToken::LParen)
1549 if (getParser().parseParenExpression(IdVal, EndLoc))
1552 while (getLexer().getKind() == AsmToken::RParen)
1553 Parser.Lex(); // Eat the ')' token.
1556 return true; // Parenthesis must follow the relocation operand.
1558 Res = evaluateRelocExpr(IdVal, Str);
1562 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1564 SmallVector<MCParsedAsmOperand *, 1> Operands;
1565 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1566 if (ResTy == MatchOperand_Success) {
1567 assert(Operands.size() == 1);
1568 MipsOperand &Operand = *static_cast<MipsOperand *>(Operands.front());
1569 StartLoc = Operand.getStartLoc();
1570 EndLoc = Operand.getEndLoc();
1572 // AFAIK, we only support numeric registers and named GPR's in CFI
1574 // Don't worry about eating tokens before failing. Using an unrecognised
1575 // register is a parse error.
1576 if (Operand.isGPRAsmReg()) {
1577 // Resolve to GPR32 or GPR64 appropriately.
1578 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1583 return (RegNo == (unsigned)-1);
1586 assert(Operands.size() == 0);
1587 return (RegNo == (unsigned)-1);
1590 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1594 while (getLexer().getKind() == AsmToken::LParen)
1597 switch (getLexer().getKind()) {
1600 case AsmToken::Identifier:
1601 case AsmToken::LParen:
1602 case AsmToken::Integer:
1603 case AsmToken::Minus:
1604 case AsmToken::Plus:
1606 Result = getParser().parseParenExpression(Res, S);
1608 Result = (getParser().parseExpression(Res));
1609 while (getLexer().getKind() == AsmToken::RParen)
1612 case AsmToken::Percent:
1613 Result = parseRelocOperand(Res);
1618 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1619 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1620 DEBUG(dbgs() << "parseMemOperand\n");
1621 const MCExpr *IdVal = nullptr;
1623 bool isParenExpr = false;
1624 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1625 // First operand is the offset.
1626 S = Parser.getTok().getLoc();
1628 if (getLexer().getKind() == AsmToken::LParen) {
1633 if (getLexer().getKind() != AsmToken::Dollar) {
1634 if (parseMemOffset(IdVal, isParenExpr))
1635 return MatchOperand_ParseFail;
1637 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1638 if (Tok.isNot(AsmToken::LParen)) {
1639 MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1640 if (Mnemonic->getToken() == "la") {
1642 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1643 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1644 return MatchOperand_Success;
1646 if (Tok.is(AsmToken::EndOfStatement)) {
1648 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1650 // Zero register assumed, add a memory operand with ZERO as its base.
1651 // "Base" will be managed by k_Memory.
1652 MipsOperand *Base = MipsOperand::CreateGPRReg(
1653 0, getContext().getRegisterInfo(), S, E, *this);
1654 Operands.push_back(MipsOperand::CreateMem(Base, IdVal, S, E, *this));
1655 return MatchOperand_Success;
1657 Error(Parser.getTok().getLoc(), "'(' expected");
1658 return MatchOperand_ParseFail;
1661 Parser.Lex(); // Eat the '(' token.
1664 Res = ParseAnyRegister(Operands);
1665 if (Res != MatchOperand_Success)
1668 if (Parser.getTok().isNot(AsmToken::RParen)) {
1669 Error(Parser.getTok().getLoc(), "')' expected");
1670 return MatchOperand_ParseFail;
1673 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1675 Parser.Lex(); // Eat the ')' token.
1678 IdVal = MCConstantExpr::Create(0, getContext());
1680 // Replace the register operand with the memory operand.
1681 MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
1682 // Remove the register from the operands.
1683 // "op" will be managed by k_Memory.
1684 Operands.pop_back();
1685 // Add the memory operand.
1686 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1688 if (IdVal->EvaluateAsAbsolute(Imm))
1689 IdVal = MCConstantExpr::Create(Imm, getContext());
1690 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1691 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1695 Operands.push_back(MipsOperand::CreateMem(op, IdVal, S, E, *this));
1696 return MatchOperand_Success;
1699 bool MipsAsmParser::searchSymbolAlias(
1700 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1702 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1704 SMLoc S = Parser.getTok().getLoc();
1706 if (Sym->isVariable())
1707 Expr = Sym->getVariableValue();
1710 if (Expr->getKind() == MCExpr::SymbolRef) {
1711 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1712 const StringRef DefSymbol = Ref->getSymbol().getName();
1713 if (DefSymbol.startswith("$")) {
1714 OperandMatchResultTy ResTy =
1715 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
1716 if (ResTy == MatchOperand_Success) {
1719 } else if (ResTy == MatchOperand_ParseFail)
1720 llvm_unreachable("Should never ParseFail");
1723 } else if (Expr->getKind() == MCExpr::Constant) {
1725 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1727 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this);
1728 Operands.push_back(op);
1735 MipsAsmParser::OperandMatchResultTy
1736 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(
1737 SmallVectorImpl<MCParsedAsmOperand *> &Operands, StringRef Identifier,
1739 int Index = matchCPURegisterName(Identifier);
1741 Operands.push_back(MipsOperand::CreateGPRReg(
1742 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1743 return MatchOperand_Success;
1746 Index = matchFPURegisterName(Identifier);
1748 Operands.push_back(MipsOperand::CreateFGRReg(
1749 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1750 return MatchOperand_Success;
1753 Index = matchFCCRegisterName(Identifier);
1755 Operands.push_back(MipsOperand::CreateFCCReg(
1756 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1757 return MatchOperand_Success;
1760 Index = matchACRegisterName(Identifier);
1762 Operands.push_back(MipsOperand::CreateACCReg(
1763 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1764 return MatchOperand_Success;
1767 Index = matchMSA128RegisterName(Identifier);
1769 Operands.push_back(MipsOperand::CreateMSA128Reg(
1770 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1771 return MatchOperand_Success;
1774 Index = matchMSA128CtrlRegisterName(Identifier);
1776 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1777 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1778 return MatchOperand_Success;
1781 return MatchOperand_NoMatch;
1784 MipsAsmParser::OperandMatchResultTy
1785 MipsAsmParser::MatchAnyRegisterWithoutDollar(
1786 SmallVectorImpl<MCParsedAsmOperand *> &Operands, SMLoc S) {
1787 auto Token = Parser.getLexer().peekTok(false);
1789 if (Token.is(AsmToken::Identifier)) {
1790 DEBUG(dbgs() << ".. identifier\n");
1791 StringRef Identifier = Token.getIdentifier();
1792 OperandMatchResultTy ResTy =
1793 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
1795 } else if (Token.is(AsmToken::Integer)) {
1796 DEBUG(dbgs() << ".. integer\n");
1797 Operands.push_back(MipsOperand::CreateNumericReg(
1798 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
1800 return MatchOperand_Success;
1803 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
1805 return MatchOperand_NoMatch;
1808 MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseAnyRegister(
1809 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1810 DEBUG(dbgs() << "ParseAnyRegister\n");
1812 auto Token = Parser.getTok();
1814 SMLoc S = Token.getLoc();
1816 if (Token.isNot(AsmToken::Dollar)) {
1817 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
1818 if (Token.is(AsmToken::Identifier)) {
1819 if (searchSymbolAlias(Operands))
1820 return MatchOperand_Success;
1822 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
1823 return MatchOperand_NoMatch;
1825 DEBUG(dbgs() << ".. $\n");
1827 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
1828 if (ResTy == MatchOperand_Success) {
1830 Parser.Lex(); // identifier
1835 MipsAsmParser::OperandMatchResultTy
1836 MipsAsmParser::ParseImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1837 switch (getLexer().getKind()) {
1839 return MatchOperand_NoMatch;
1840 case AsmToken::LParen:
1841 case AsmToken::Minus:
1842 case AsmToken::Plus:
1843 case AsmToken::Integer:
1844 case AsmToken::String:
1848 const MCExpr *IdVal;
1849 SMLoc S = Parser.getTok().getLoc();
1850 if (getParser().parseExpression(IdVal))
1851 return MatchOperand_ParseFail;
1853 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1854 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1855 return MatchOperand_Success;
1858 MipsAsmParser::OperandMatchResultTy MipsAsmParser::ParseJumpTarget(
1859 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1860 DEBUG(dbgs() << "ParseJumpTarget\n");
1862 SMLoc S = getLexer().getLoc();
1864 // Integers and expressions are acceptable
1865 OperandMatchResultTy ResTy = ParseImm(Operands);
1866 if (ResTy != MatchOperand_NoMatch)
1869 // Registers are a valid target and have priority over symbols.
1870 ResTy = ParseAnyRegister(Operands);
1871 if (ResTy != MatchOperand_NoMatch)
1874 const MCExpr *Expr = nullptr;
1875 if (Parser.parseExpression(Expr)) {
1876 // We have no way of knowing if a symbol was consumed so we must ParseFail
1877 return MatchOperand_ParseFail;
1880 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
1881 return MatchOperand_Success;
1884 MipsAsmParser::OperandMatchResultTy
1885 MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1886 const MCExpr *IdVal;
1887 // If the first token is '$' we may have register operand.
1888 if (Parser.getTok().is(AsmToken::Dollar))
1889 return MatchOperand_NoMatch;
1890 SMLoc S = Parser.getTok().getLoc();
1891 if (getParser().parseExpression(IdVal))
1892 return MatchOperand_ParseFail;
1893 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
1894 assert(MCE && "Unexpected MCExpr type.");
1895 int64_t Val = MCE->getValue();
1896 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1897 Operands.push_back(MipsOperand::CreateImm(
1898 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
1899 return MatchOperand_Success;
1902 MipsAsmParser::OperandMatchResultTy
1903 MipsAsmParser::ParseLSAImm(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1904 switch (getLexer().getKind()) {
1906 return MatchOperand_NoMatch;
1907 case AsmToken::LParen:
1908 case AsmToken::Plus:
1909 case AsmToken::Minus:
1910 case AsmToken::Integer:
1915 SMLoc S = Parser.getTok().getLoc();
1917 if (getParser().parseExpression(Expr))
1918 return MatchOperand_ParseFail;
1921 if (!Expr->EvaluateAsAbsolute(Val)) {
1922 Error(S, "expected immediate value");
1923 return MatchOperand_ParseFail;
1926 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
1927 // and because the CPU always adds one to the immediate field, the allowed
1928 // range becomes 1..4. We'll only check the range here and will deal
1929 // with the addition/subtraction when actually decoding/encoding
1931 if (Val < 1 || Val > 4) {
1932 Error(S, "immediate not in range (1..4)");
1933 return MatchOperand_ParseFail;
1937 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
1938 return MatchOperand_Success;
1941 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1943 MCSymbolRefExpr::VariantKind VK =
1944 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1945 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1946 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1947 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1948 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1949 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1950 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1951 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1952 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1953 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1954 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1955 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1956 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1957 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1958 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1959 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
1960 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1961 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1962 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
1963 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
1964 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
1965 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
1966 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
1967 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
1968 .Default(MCSymbolRefExpr::VK_None);
1970 assert(VK != MCSymbolRefExpr::VK_None);
1975 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
1977 /// ::= '(', register, ')'
1978 /// handle it before we iterate so we don't get tripped up by the lack of
1980 bool MipsAsmParser::ParseParenSuffix(
1981 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1982 if (getLexer().is(AsmToken::LParen)) {
1984 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
1986 if (ParseOperand(Operands, Name)) {
1987 SMLoc Loc = getLexer().getLoc();
1988 Parser.eatToEndOfStatement();
1989 return Error(Loc, "unexpected token in argument list");
1991 if (Parser.getTok().isNot(AsmToken::RParen)) {
1992 SMLoc Loc = getLexer().getLoc();
1993 Parser.eatToEndOfStatement();
1994 return Error(Loc, "unexpected token, expected ')'");
1997 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2003 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2004 /// either one of these.
2005 /// ::= '[', register, ']'
2006 /// ::= '[', integer, ']'
2007 /// handle it before we iterate so we don't get tripped up by the lack of
2009 bool MipsAsmParser::ParseBracketSuffix(
2010 StringRef Name, SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2011 if (getLexer().is(AsmToken::LBrac)) {
2013 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2015 if (ParseOperand(Operands, Name)) {
2016 SMLoc Loc = getLexer().getLoc();
2017 Parser.eatToEndOfStatement();
2018 return Error(Loc, "unexpected token in argument list");
2020 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2021 SMLoc Loc = getLexer().getLoc();
2022 Parser.eatToEndOfStatement();
2023 return Error(Loc, "unexpected token, expected ']'");
2026 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2032 bool MipsAsmParser::ParseInstruction(
2033 ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2034 SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2035 DEBUG(dbgs() << "ParseInstruction\n");
2036 // Check if we have valid mnemonic
2037 if (!mnemonicIsValid(Name, 0)) {
2038 Parser.eatToEndOfStatement();
2039 return Error(NameLoc, "Unknown instruction");
2041 // First operand in MCInst is instruction mnemonic.
2042 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2044 // Read the remaining operands.
2045 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2046 // Read the first operand.
2047 if (ParseOperand(Operands, Name)) {
2048 SMLoc Loc = getLexer().getLoc();
2049 Parser.eatToEndOfStatement();
2050 return Error(Loc, "unexpected token in argument list");
2052 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2054 // AFAIK, parenthesis suffixes are never on the first operand
2056 while (getLexer().is(AsmToken::Comma)) {
2057 Parser.Lex(); // Eat the comma.
2058 // Parse and remember the operand.
2059 if (ParseOperand(Operands, Name)) {
2060 SMLoc Loc = getLexer().getLoc();
2061 Parser.eatToEndOfStatement();
2062 return Error(Loc, "unexpected token in argument list");
2064 // Parse bracket and parenthesis suffixes before we iterate
2065 if (getLexer().is(AsmToken::LBrac)) {
2066 if (ParseBracketSuffix(Name, Operands))
2068 } else if (getLexer().is(AsmToken::LParen) &&
2069 ParseParenSuffix(Name, Operands))
2073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2074 SMLoc Loc = getLexer().getLoc();
2075 Parser.eatToEndOfStatement();
2076 return Error(Loc, "unexpected token in argument list");
2078 Parser.Lex(); // Consume the EndOfStatement.
2082 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2083 SMLoc Loc = getLexer().getLoc();
2084 Parser.eatToEndOfStatement();
2085 return Error(Loc, ErrorMsg);
2088 bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) {
2089 return Error(Loc, ErrorMsg);
2092 bool MipsAsmParser::parseSetNoAtDirective() {
2093 // Line should look like: ".set noat".
2095 Options.setATReg(0);
2098 // If this is not the end of the statement, report an error.
2099 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2100 reportParseError("unexpected token in statement");
2103 Parser.Lex(); // Consume the EndOfStatement.
2107 bool MipsAsmParser::parseSetAtDirective() {
2108 // Line can be .set at - defaults to $1
2112 if (getLexer().is(AsmToken::EndOfStatement)) {
2113 Options.setATReg(1);
2114 Parser.Lex(); // Consume the EndOfStatement.
2116 } else if (getLexer().is(AsmToken::Equal)) {
2117 getParser().Lex(); // Eat the '='.
2118 if (getLexer().isNot(AsmToken::Dollar)) {
2119 reportParseError("unexpected token in statement");
2122 Parser.Lex(); // Eat the '$'.
2123 const AsmToken &Reg = Parser.getTok();
2124 if (Reg.is(AsmToken::Identifier)) {
2125 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2126 } else if (Reg.is(AsmToken::Integer)) {
2127 AtRegNo = Reg.getIntVal();
2129 reportParseError("unexpected token in statement");
2133 if (AtRegNo < 0 || AtRegNo > 31) {
2134 reportParseError("unexpected token in statement");
2138 if (!Options.setATReg(AtRegNo)) {
2139 reportParseError("unexpected token in statement");
2142 getParser().Lex(); // Eat the register.
2144 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2145 reportParseError("unexpected token in statement");
2148 Parser.Lex(); // Consume the EndOfStatement.
2151 reportParseError("unexpected token in statement");
2156 bool MipsAsmParser::parseSetReorderDirective() {
2158 // If this is not the end of the statement, report an error.
2159 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2160 reportParseError("unexpected token in statement");
2163 Options.setReorder();
2164 getTargetStreamer().emitDirectiveSetReorder();
2165 Parser.Lex(); // Consume the EndOfStatement.
2169 bool MipsAsmParser::parseSetNoReorderDirective() {
2171 // If this is not the end of the statement, report an error.
2172 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2173 reportParseError("unexpected token in statement");
2176 Options.setNoreorder();
2177 getTargetStreamer().emitDirectiveSetNoReorder();
2178 Parser.Lex(); // Consume the EndOfStatement.
2182 bool MipsAsmParser::parseSetMacroDirective() {
2184 // If this is not the end of the statement, report an error.
2185 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2186 reportParseError("unexpected token in statement");
2190 Parser.Lex(); // Consume the EndOfStatement.
2194 bool MipsAsmParser::parseSetNoMacroDirective() {
2196 // If this is not the end of the statement, report an error.
2197 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2198 reportParseError("`noreorder' must be set before `nomacro'");
2201 if (Options.isReorder()) {
2202 reportParseError("`noreorder' must be set before `nomacro'");
2205 Options.setNomacro();
2206 Parser.Lex(); // Consume the EndOfStatement.
2210 bool MipsAsmParser::parseSetNoMips16Directive() {
2212 // If this is not the end of the statement, report an error.
2213 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2214 reportParseError("unexpected token in statement");
2217 // For now do nothing.
2218 Parser.Lex(); // Consume the EndOfStatement.
2222 bool MipsAsmParser::parseSetAssignment() {
2224 const MCExpr *Value;
2226 if (Parser.parseIdentifier(Name))
2227 reportParseError("expected identifier after .set");
2229 if (getLexer().isNot(AsmToken::Comma))
2230 return reportParseError("unexpected token in .set directive");
2233 if (Parser.parseExpression(Value))
2234 return reportParseError("expected valid expression after comma");
2236 // Check if the Name already exists as a symbol.
2237 MCSymbol *Sym = getContext().LookupSymbol(Name);
2239 return reportParseError("symbol already defined");
2240 Sym = getContext().GetOrCreateSymbol(Name);
2241 Sym->setVariableValue(Value);
2246 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2248 if (getLexer().isNot(AsmToken::EndOfStatement))
2249 return reportParseError("unexpected token in .set directive");
2253 llvm_unreachable("Unimplemented feature");
2254 case Mips::FeatureDSP:
2255 setFeatureBits(Mips::FeatureDSP, "dsp");
2256 getTargetStreamer().emitDirectiveSetDsp();
2258 case Mips::FeatureMicroMips:
2259 getTargetStreamer().emitDirectiveSetMicroMips();
2261 case Mips::FeatureMips16:
2262 getTargetStreamer().emitDirectiveSetMips16();
2264 case Mips::FeatureMips32r2:
2265 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2266 getTargetStreamer().emitDirectiveSetMips32R2();
2268 case Mips::FeatureMips64:
2269 setFeatureBits(Mips::FeatureMips64, "mips64");
2270 getTargetStreamer().emitDirectiveSetMips64();
2272 case Mips::FeatureMips64r2:
2273 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2274 getTargetStreamer().emitDirectiveSetMips64R2();
2280 bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2281 if (!getLexer().is(AsmToken::Dollar))
2286 const AsmToken &Reg = Parser.getTok();
2287 if (Reg.is(AsmToken::Identifier)) {
2288 RegNum = matchCPURegisterName(Reg.getIdentifier());
2289 } else if (Reg.is(AsmToken::Integer)) {
2290 RegNum = Reg.getIntVal();
2299 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2300 if (getLexer().isNot(AsmToken::Comma)) {
2301 SMLoc Loc = getLexer().getLoc();
2302 Parser.eatToEndOfStatement();
2303 return Error(Loc, ErrorStr);
2306 Parser.Lex(); // Eat the comma.
2310 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2311 if (Options.isReorder())
2312 Warning(Loc, ".cpload in reorder section");
2314 // FIXME: Warn if cpload is used in Mips16 mode.
2316 SmallVector<MCParsedAsmOperand *, 1> Reg;
2317 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2318 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2319 reportParseError("expected register containing function address");
2323 MipsOperand *RegOpnd = static_cast<MipsOperand *>(Reg[0]);
2324 if (!RegOpnd->isGPRAsmReg()) {
2325 reportParseError(RegOpnd->getStartLoc(), "invalid register");
2329 getTargetStreamer().emitDirectiveCpload(RegOpnd->getGPR32Reg());
2334 bool MipsAsmParser::parseDirectiveCPSetup() {
2337 bool SaveIsReg = true;
2339 if (!parseRegister(FuncReg))
2340 return reportParseError("expected register containing function address");
2341 FuncReg = getGPR(FuncReg);
2343 if (!eatComma("expected comma parsing directive"))
2346 if (!parseRegister(Save)) {
2347 const AsmToken &Tok = Parser.getTok();
2348 if (Tok.is(AsmToken::Integer)) {
2349 Save = Tok.getIntVal();
2353 return reportParseError("expected save register or stack offset");
2355 Save = getGPR(Save);
2357 if (!eatComma("expected comma parsing directive"))
2361 if (Parser.parseIdentifier(Name))
2362 reportParseError("expected identifier");
2363 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2365 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2369 bool MipsAsmParser::parseDirectiveNaN() {
2370 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2371 const AsmToken &Tok = Parser.getTok();
2373 if (Tok.getString() == "2008") {
2375 getTargetStreamer().emitDirectiveNaN2008();
2377 } else if (Tok.getString() == "legacy") {
2379 getTargetStreamer().emitDirectiveNaNLegacy();
2383 // If we don't recognize the option passed to the .nan
2384 // directive (e.g. no option or unknown option), emit an error.
2385 reportParseError("invalid option in .nan directive");
2389 bool MipsAsmParser::parseDirectiveSet() {
2391 // Get the next token.
2392 const AsmToken &Tok = Parser.getTok();
2394 if (Tok.getString() == "noat") {
2395 return parseSetNoAtDirective();
2396 } else if (Tok.getString() == "at") {
2397 return parseSetAtDirective();
2398 } else if (Tok.getString() == "reorder") {
2399 return parseSetReorderDirective();
2400 } else if (Tok.getString() == "noreorder") {
2401 return parseSetNoReorderDirective();
2402 } else if (Tok.getString() == "macro") {
2403 return parseSetMacroDirective();
2404 } else if (Tok.getString() == "nomacro") {
2405 return parseSetNoMacroDirective();
2406 } else if (Tok.getString() == "mips16") {
2407 return parseSetFeature(Mips::FeatureMips16);
2408 } else if (Tok.getString() == "nomips16") {
2409 return parseSetNoMips16Directive();
2410 } else if (Tok.getString() == "nomicromips") {
2411 getTargetStreamer().emitDirectiveSetNoMicroMips();
2412 Parser.eatToEndOfStatement();
2414 } else if (Tok.getString() == "micromips") {
2415 return parseSetFeature(Mips::FeatureMicroMips);
2416 } else if (Tok.getString() == "mips32r2") {
2417 return parseSetFeature(Mips::FeatureMips32r2);
2418 } else if (Tok.getString() == "mips64") {
2419 return parseSetFeature(Mips::FeatureMips64);
2420 } else if (Tok.getString() == "mips64r2") {
2421 return parseSetFeature(Mips::FeatureMips64r2);
2422 } else if (Tok.getString() == "dsp") {
2423 return parseSetFeature(Mips::FeatureDSP);
2425 // It is just an identifier, look for an assignment.
2426 parseSetAssignment();
2433 /// parseDataDirective
2434 /// ::= .word [ expression (, expression)* ]
2435 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2436 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2438 const MCExpr *Value;
2439 if (getParser().parseExpression(Value))
2442 getParser().getStreamer().EmitValue(Value, Size);
2444 if (getLexer().is(AsmToken::EndOfStatement))
2447 // FIXME: Improve diagnostic.
2448 if (getLexer().isNot(AsmToken::Comma))
2449 return Error(L, "unexpected token in directive");
2458 /// parseDirectiveGpWord
2459 /// ::= .gpword local_sym
2460 bool MipsAsmParser::parseDirectiveGpWord() {
2461 const MCExpr *Value;
2462 // EmitGPRel32Value requires an expression, so we are using base class
2463 // method to evaluate the expression.
2464 if (getParser().parseExpression(Value))
2466 getParser().getStreamer().EmitGPRel32Value(Value);
2468 if (getLexer().isNot(AsmToken::EndOfStatement))
2469 return Error(getLexer().getLoc(), "unexpected token in directive");
2470 Parser.Lex(); // Eat EndOfStatement token.
2474 /// parseDirectiveGpDWord
2475 /// ::= .gpdword local_sym
2476 bool MipsAsmParser::parseDirectiveGpDWord() {
2477 const MCExpr *Value;
2478 // EmitGPRel64Value requires an expression, so we are using base class
2479 // method to evaluate the expression.
2480 if (getParser().parseExpression(Value))
2482 getParser().getStreamer().EmitGPRel64Value(Value);
2484 if (getLexer().isNot(AsmToken::EndOfStatement))
2485 return Error(getLexer().getLoc(), "unexpected token in directive");
2486 Parser.Lex(); // Eat EndOfStatement token.
2490 bool MipsAsmParser::parseDirectiveOption() {
2491 // Get the option token.
2492 AsmToken Tok = Parser.getTok();
2493 // At the moment only identifiers are supported.
2494 if (Tok.isNot(AsmToken::Identifier)) {
2495 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2496 Parser.eatToEndOfStatement();
2500 StringRef Option = Tok.getIdentifier();
2502 if (Option == "pic0") {
2503 getTargetStreamer().emitDirectiveOptionPic0();
2505 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2506 Error(Parser.getTok().getLoc(),
2507 "unexpected token in .option pic0 directive");
2508 Parser.eatToEndOfStatement();
2513 if (Option == "pic2") {
2514 getTargetStreamer().emitDirectiveOptionPic2();
2516 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2517 Error(Parser.getTok().getLoc(),
2518 "unexpected token in .option pic2 directive");
2519 Parser.eatToEndOfStatement();
2525 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2526 Parser.eatToEndOfStatement();
2530 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2531 StringRef IDVal = DirectiveID.getString();
2533 if (IDVal == ".cpload")
2534 return parseDirectiveCPLoad(DirectiveID.getLoc());
2535 if (IDVal == ".dword") {
2536 parseDataDirective(8, DirectiveID.getLoc());
2540 if (IDVal == ".ent") {
2541 // Ignore this directive for now.
2546 if (IDVal == ".end") {
2547 // Ignore this directive for now.
2552 if (IDVal == ".frame") {
2553 // Ignore this directive for now.
2554 Parser.eatToEndOfStatement();
2558 if (IDVal == ".set") {
2559 return parseDirectiveSet();
2562 if (IDVal == ".fmask") {
2563 // Ignore this directive for now.
2564 Parser.eatToEndOfStatement();
2568 if (IDVal == ".mask") {
2569 // Ignore this directive for now.
2570 Parser.eatToEndOfStatement();
2574 if (IDVal == ".nan")
2575 return parseDirectiveNaN();
2577 if (IDVal == ".gpword") {
2578 parseDirectiveGpWord();
2582 if (IDVal == ".gpdword") {
2583 parseDirectiveGpDWord();
2587 if (IDVal == ".word") {
2588 parseDataDirective(4, DirectiveID.getLoc());
2592 if (IDVal == ".option")
2593 return parseDirectiveOption();
2595 if (IDVal == ".abicalls") {
2596 getTargetStreamer().emitDirectiveAbiCalls();
2597 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2598 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2600 Parser.eatToEndOfStatement();
2605 if (IDVal == ".cpsetup")
2606 return parseDirectiveCPSetup();
2611 extern "C" void LLVMInitializeMipsAsmParser() {
2612 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2613 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2614 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2615 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2618 #define GET_REGISTER_MATCHER
2619 #define GET_MATCHER_IMPLEMENTATION
2620 #include "MipsGenAsmMatcher.inc"