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 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
77 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
78 OperandVector &Operands, MCStreamer &Out,
80 bool MatchingInlineAsm) override;
82 /// Parse a register as used in CFI directives
83 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
85 bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
87 bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
89 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
90 SMLoc NameLoc, OperandVector &Operands) override;
92 bool ParseDirective(AsmToken DirectiveID) override;
94 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
96 MipsAsmParser::OperandMatchResultTy
97 MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
98 StringRef Identifier, SMLoc S);
100 MipsAsmParser::OperandMatchResultTy
101 MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
103 MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
105 MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
107 MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
109 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
111 MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
113 bool searchSymbolAlias(OperandVector &Operands);
115 bool ParseOperand(OperandVector &, StringRef Mnemonic);
117 bool needsExpansion(MCInst &Inst);
119 void expandInstruction(MCInst &Inst, SMLoc IDLoc,
120 SmallVectorImpl<MCInst> &Instructions);
121 void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
122 SmallVectorImpl<MCInst> &Instructions);
123 void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
124 SmallVectorImpl<MCInst> &Instructions);
125 void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
126 SmallVectorImpl<MCInst> &Instructions);
127 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
128 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
130 bool reportParseError(StringRef ErrorMsg);
131 bool reportParseError(SMLoc Loc, StringRef ErrorMsg);
133 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
134 bool parseRelocOperand(const MCExpr *&Res);
136 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
138 bool isEvaluated(const MCExpr *Expr);
139 bool parseSetFeature(uint64_t Feature);
140 bool parseDirectiveCPLoad(SMLoc Loc);
141 bool parseDirectiveCPSetup();
142 bool parseDirectiveNaN();
143 bool parseDirectiveSet();
144 bool parseDirectiveOption();
146 bool parseSetAtDirective();
147 bool parseSetNoAtDirective();
148 bool parseSetMacroDirective();
149 bool parseSetNoMacroDirective();
150 bool parseSetReorderDirective();
151 bool parseSetNoReorderDirective();
152 bool parseSetNoMips16Directive();
154 bool parseSetAssignment();
156 bool parseDataDirective(unsigned Size, SMLoc L);
157 bool parseDirectiveGpWord();
158 bool parseDirectiveGpDWord();
160 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
162 bool isGP64() const {
163 return (STI.getFeatureBits() & Mips::FeatureGP64Bit) != 0;
166 bool isFP64() const {
167 return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
170 bool isN32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
171 bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
173 bool isMicroMips() const {
174 return STI.getFeatureBits() & Mips::FeatureMicroMips;
177 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
178 bool hasMips32() const { return STI.getFeatureBits() & Mips::FeatureMips32; }
180 bool parseRegister(unsigned &RegNum);
182 bool eatComma(StringRef ErrorStr);
184 int matchCPURegisterName(StringRef Symbol);
186 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
188 int matchFPURegisterName(StringRef Name);
190 int matchFCCRegisterName(StringRef Name);
192 int matchACRegisterName(StringRef Name);
194 int matchMSA128RegisterName(StringRef Name);
196 int matchMSA128CtrlRegisterName(StringRef Name);
198 unsigned getReg(int RC, int RegNo);
200 unsigned getGPR(int RegNo);
204 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
205 SmallVectorImpl<MCInst> &Instructions);
207 // Helper function that checks if the value of a vector index is within the
208 // boundaries of accepted values for each RegisterKind
209 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
210 bool validateMSAIndex(int Val, int RegKind);
212 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
213 if (!(STI.getFeatureBits() & Feature)) {
214 setAvailableFeatures(
215 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
219 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
220 if (STI.getFeatureBits() & Feature) {
221 setAvailableFeatures(
222 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
227 enum MipsMatchResultTy {
228 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
229 #define GET_OPERAND_DIAGNOSTIC_TYPES
230 #include "MipsGenAsmMatcher.inc"
231 #undef GET_OPERAND_DIAGNOSTIC_TYPES
235 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
236 const MCInstrInfo &MII,
237 const MCTargetOptions &Options)
238 : MCTargetAsmParser(), STI(sti), Parser(parser) {
239 // Initialize the set of available features.
240 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
242 // Assert exactly one ABI was chosen.
243 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
244 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
245 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
246 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
249 MCAsmParser &getParser() const { return Parser; }
250 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
252 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
253 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
255 /// Warn if RegNo is the current assembler temporary.
256 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
262 /// MipsOperand - Instances of this class represent a parsed Mips machine
264 class MipsOperand : public MCParsedAsmOperand {
266 /// Broad categories of register classes
267 /// The exact class is finalized by the render method.
269 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64())
270 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
272 RegKind_FCC = 4, /// FCC
273 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
274 RegKind_MSACtrl = 16, /// MSA control registers
275 RegKind_COP2 = 32, /// COP2
276 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
278 RegKind_CCR = 128, /// CCR
279 RegKind_HWRegs = 256, /// HWRegs
280 RegKind_COP3 = 512, /// COP3
282 /// Potentially any (e.g. $1)
283 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
284 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
285 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
290 k_Immediate, /// An immediate (possibly involving symbol references)
291 k_Memory, /// Base + Offset Memory Address
292 k_PhysRegister, /// A physical register from the Mips namespace
293 k_RegisterIndex, /// A register index in one or more RegKind.
294 k_Token /// A simple token
298 MipsOperand(KindTy K, MipsAsmParser &Parser)
299 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
302 /// For diagnostics, and checking the assembler temporary
303 MipsAsmParser &AsmParser;
311 unsigned Num; /// Register Number
315 unsigned Index; /// Index into the register class
316 RegKind Kind; /// Bitfield of the kinds it could possibly be
317 const MCRegisterInfo *RegInfo;
331 struct PhysRegOp PhysReg;
332 struct RegIdxOp RegIdx;
337 SMLoc StartLoc, EndLoc;
339 /// Internal constructor for register kinds
340 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
341 const MCRegisterInfo *RegInfo,
343 MipsAsmParser &Parser) {
344 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
345 Op->RegIdx.Index = Index;
346 Op->RegIdx.RegInfo = RegInfo;
347 Op->RegIdx.Kind = RegKind;
354 /// Coerce the register to GPR32 and return the real register for the current
356 unsigned getGPR32Reg() const {
357 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
358 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
359 unsigned ClassID = Mips::GPR32RegClassID;
360 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
363 /// Coerce the register to GPR64 and return the real register for the current
365 unsigned getGPR64Reg() const {
366 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
367 unsigned ClassID = Mips::GPR64RegClassID;
368 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
372 /// Coerce the register to AFGR64 and return the real register for the current
374 unsigned getAFGR64Reg() const {
375 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
376 if (RegIdx.Index % 2 != 0)
377 AsmParser.Warning(StartLoc, "Float register should be even.");
378 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
379 .getRegister(RegIdx.Index / 2);
382 /// Coerce the register to FGR64 and return the real register for the current
384 unsigned getFGR64Reg() const {
385 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
386 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
387 .getRegister(RegIdx.Index);
390 /// Coerce the register to FGR32 and return the real register for the current
392 unsigned getFGR32Reg() const {
393 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
394 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
395 .getRegister(RegIdx.Index);
398 /// Coerce the register to FGRH32 and return the real register for the current
400 unsigned getFGRH32Reg() const {
401 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
402 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
403 .getRegister(RegIdx.Index);
406 /// Coerce the register to FCC and return the real register for the current
408 unsigned getFCCReg() const {
409 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
410 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
411 .getRegister(RegIdx.Index);
414 /// Coerce the register to MSA128 and return the real register for the current
416 unsigned getMSA128Reg() const {
417 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
418 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
420 unsigned ClassID = Mips::MSA128BRegClassID;
421 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
424 /// Coerce the register to MSACtrl and return the real register for the
426 unsigned getMSACtrlReg() const {
427 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
428 unsigned ClassID = Mips::MSACtrlRegClassID;
429 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
432 /// Coerce the register to COP2 and return the real register for the
434 unsigned getCOP2Reg() const {
435 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
436 unsigned ClassID = Mips::COP2RegClassID;
437 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
440 /// Coerce the register to COP3 and return the real register for the
442 unsigned getCOP3Reg() const {
443 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
444 unsigned ClassID = Mips::COP3RegClassID;
445 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
448 /// Coerce the register to ACC64DSP and return the real register for the
450 unsigned getACC64DSPReg() const {
451 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
452 unsigned ClassID = Mips::ACC64DSPRegClassID;
453 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
456 /// Coerce the register to HI32DSP and return the real register for the
458 unsigned getHI32DSPReg() const {
459 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
460 unsigned ClassID = Mips::HI32DSPRegClassID;
461 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
464 /// Coerce the register to LO32DSP and return the real register for the
466 unsigned getLO32DSPReg() const {
467 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
468 unsigned ClassID = Mips::LO32DSPRegClassID;
469 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
472 /// Coerce the register to CCR and return the real register for the
474 unsigned getCCRReg() const {
475 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
476 unsigned ClassID = Mips::CCRRegClassID;
477 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
480 /// Coerce the register to HWRegs and return the real register for the
482 unsigned getHWRegsReg() const {
483 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
484 unsigned ClassID = Mips::HWRegsRegClassID;
485 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
489 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
490 // Add as immediate when possible. Null MCExpr = 0.
492 Inst.addOperand(MCOperand::CreateImm(0));
493 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
494 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
496 Inst.addOperand(MCOperand::CreateExpr(Expr));
499 void addRegOperands(MCInst &Inst, unsigned N) const {
500 llvm_unreachable("Use a custom parser instead");
503 /// Render the operand to an MCInst as a GPR32
504 /// Asserts if the wrong number of operands are requested, or the operand
505 /// is not a k_RegisterIndex compatible with RegKind_GPR
506 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
507 assert(N == 1 && "Invalid number of operands!");
508 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
511 /// Render the operand to an MCInst as a GPR64
512 /// Asserts if the wrong number of operands are requested, or the operand
513 /// is not a k_RegisterIndex compatible with RegKind_GPR
514 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
515 assert(N == 1 && "Invalid number of operands!");
516 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
519 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
520 assert(N == 1 && "Invalid number of operands!");
521 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
524 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
525 assert(N == 1 && "Invalid number of operands!");
526 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
529 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
530 assert(N == 1 && "Invalid number of operands!");
531 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
534 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
535 assert(N == 1 && "Invalid number of operands!");
536 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
539 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
540 assert(N == 1 && "Invalid number of operands!");
541 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
544 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
545 assert(N == 1 && "Invalid number of operands!");
546 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
549 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
550 assert(N == 1 && "Invalid number of operands!");
551 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
554 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
555 assert(N == 1 && "Invalid number of operands!");
556 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
559 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
560 assert(N == 1 && "Invalid number of operands!");
561 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
564 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
565 assert(N == 1 && "Invalid number of operands!");
566 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
569 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
570 assert(N == 1 && "Invalid number of operands!");
571 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
574 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
575 assert(N == 1 && "Invalid number of operands!");
576 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
579 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
580 assert(N == 1 && "Invalid number of operands!");
581 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
584 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
585 assert(N == 1 && "Invalid number of operands!");
586 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
589 void addImmOperands(MCInst &Inst, unsigned N) const {
590 assert(N == 1 && "Invalid number of operands!");
591 const MCExpr *Expr = getImm();
595 void addMemOperands(MCInst &Inst, unsigned N) const {
596 assert(N == 2 && "Invalid number of operands!");
598 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
600 const MCExpr *Expr = getMemOff();
604 bool isReg() const override {
605 // As a special case until we sort out the definition of div/divu, pretend
606 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
607 if (isGPRAsmReg() && RegIdx.Index == 0)
610 return Kind == k_PhysRegister;
612 bool isRegIdx() const { return Kind == k_RegisterIndex; }
613 bool isImm() const override { return Kind == k_Immediate; }
614 bool isConstantImm() const {
615 return isImm() && dyn_cast<MCConstantExpr>(getImm());
617 bool isToken() const override {
618 // Note: It's not possible to pretend that other operand kinds are tokens.
619 // The matcher emitter checks tokens first.
620 return Kind == k_Token;
622 bool isMem() const override { return Kind == k_Memory; }
623 bool isInvNum() const { return Kind == k_Immediate; }
624 bool isLSAImm() const {
625 if (!isConstantImm())
627 int64_t Val = getConstantImm();
628 return 1 <= Val && Val <= 4;
631 StringRef getToken() const {
632 assert(Kind == k_Token && "Invalid access!");
633 return StringRef(Tok.Data, Tok.Length);
636 unsigned getReg() const override {
637 // As a special case until we sort out the definition of div/divu, pretend
638 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
639 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
640 RegIdx.Kind & RegKind_GPR)
641 return getGPR32Reg(); // FIXME: GPR64 too
643 assert(Kind == k_PhysRegister && "Invalid access!");
647 const MCExpr *getImm() const {
648 assert((Kind == k_Immediate) && "Invalid access!");
652 int64_t getConstantImm() const {
653 const MCExpr *Val = getImm();
654 return static_cast<const MCConstantExpr *>(Val)->getValue();
657 MipsOperand *getMemBase() const {
658 assert((Kind == k_Memory) && "Invalid access!");
662 const MCExpr *getMemOff() const {
663 assert((Kind == k_Memory) && "Invalid access!");
667 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
668 MipsAsmParser &Parser) {
669 auto Op = make_unique<MipsOperand>(k_Token, Parser);
670 Op->Tok.Data = Str.data();
671 Op->Tok.Length = Str.size();
677 /// Create a numeric register (e.g. $1). The exact register remains
678 /// unresolved until an instruction successfully matches
679 static std::unique_ptr<MipsOperand>
680 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
681 SMLoc E, MipsAsmParser &Parser) {
682 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
683 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
686 /// Create a register that is definitely a GPR.
687 /// This is typically only used for named registers such as $gp.
688 static std::unique_ptr<MipsOperand>
689 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
690 MipsAsmParser &Parser) {
691 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
694 /// Create a register that is definitely a FGR.
695 /// This is typically only used for named registers such as $f0.
696 static std::unique_ptr<MipsOperand>
697 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
698 MipsAsmParser &Parser) {
699 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
702 /// Create a register that is definitely an FCC.
703 /// This is typically only used for named registers such as $fcc0.
704 static std::unique_ptr<MipsOperand>
705 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
706 MipsAsmParser &Parser) {
707 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
710 /// Create a register that is definitely an ACC.
711 /// This is typically only used for named registers such as $ac0.
712 static std::unique_ptr<MipsOperand>
713 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
714 MipsAsmParser &Parser) {
715 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
718 /// Create a register that is definitely an MSA128.
719 /// This is typically only used for named registers such as $w0.
720 static std::unique_ptr<MipsOperand>
721 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
722 SMLoc E, MipsAsmParser &Parser) {
723 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
726 /// Create a register that is definitely an MSACtrl.
727 /// This is typically only used for named registers such as $msaaccess.
728 static std::unique_ptr<MipsOperand>
729 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
730 SMLoc E, MipsAsmParser &Parser) {
731 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
734 static std::unique_ptr<MipsOperand>
735 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
736 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
743 static std::unique_ptr<MipsOperand>
744 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
745 SMLoc E, MipsAsmParser &Parser) {
746 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
747 Op->Mem.Base = Base.release();
754 bool isGPRAsmReg() const {
755 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
757 bool isFGRAsmReg() const {
758 // AFGR64 is $0-$15 but we handle this in getAFGR64()
759 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
761 bool isHWRegsAsmReg() const {
762 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
764 bool isCCRAsmReg() const {
765 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
767 bool isFCCAsmReg() const {
768 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
770 if (!AsmParser.hasEightFccRegisters())
771 return RegIdx.Index == 0;
772 return RegIdx.Index <= 7;
774 bool isACCAsmReg() const {
775 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
777 bool isCOP2AsmReg() const {
778 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
780 bool isCOP3AsmReg() const {
781 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
783 bool isMSA128AsmReg() const {
784 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
786 bool isMSACtrlAsmReg() const {
787 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
790 /// getStartLoc - Get the location of the first token of this operand.
791 SMLoc getStartLoc() const override { return StartLoc; }
792 /// getEndLoc - Get the location of the last token of this operand.
793 SMLoc getEndLoc() const override { return EndLoc; }
795 virtual ~MipsOperand() {
803 case k_RegisterIndex:
809 void print(raw_ostream &OS) const override {
824 OS << "PhysReg<" << PhysReg.Num << ">";
826 case k_RegisterIndex:
827 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
834 }; // class MipsOperand
838 extern const MCInstrDesc MipsInsts[];
840 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
841 return MipsInsts[Opcode];
844 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
845 SmallVectorImpl<MCInst> &Instructions) {
846 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
850 if (MCID.isBranch() || MCID.isCall()) {
851 const unsigned Opcode = Inst.getOpcode();
861 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
862 Offset = Inst.getOperand(2);
864 break; // We'll deal with this situation later on when applying fixups.
865 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
866 return Error(IDLoc, "branch target out of range");
867 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
868 return Error(IDLoc, "branch to misaligned address");
882 case Mips::BGEZAL_MM:
883 case Mips::BLTZAL_MM:
886 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
887 Offset = Inst.getOperand(1);
889 break; // We'll deal with this situation later on when applying fixups.
890 if (!isIntN(isMicroMips() ? 17 : 18, Offset.getImm()))
891 return Error(IDLoc, "branch target out of range");
892 if (OffsetToAlignment(Offset.getImm(), 1LL << (isMicroMips() ? 1 : 2)))
893 return Error(IDLoc, "branch to misaligned address");
898 if (MCID.hasDelaySlot() && Options.isReorder()) {
899 // If this instruction has a delay slot and .set reorder is active,
900 // emit a NOP after it.
901 Instructions.push_back(Inst);
903 NopInst.setOpcode(Mips::SLL);
904 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
905 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
906 NopInst.addOperand(MCOperand::CreateImm(0));
907 Instructions.push_back(NopInst);
911 if (MCID.mayLoad() || MCID.mayStore()) {
912 // Check the offset of memory operand, if it is a symbol
913 // reference or immediate we may have to expand instructions.
914 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
915 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
916 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
917 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
918 MCOperand &Op = Inst.getOperand(i);
920 int MemOffset = Op.getImm();
921 if (MemOffset < -32768 || MemOffset > 32767) {
922 // Offset can't exceed 16bit value.
923 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
926 } else if (Op.isExpr()) {
927 const MCExpr *Expr = Op.getExpr();
928 if (Expr->getKind() == MCExpr::SymbolRef) {
929 const MCSymbolRefExpr *SR =
930 static_cast<const MCSymbolRefExpr *>(Expr);
931 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
933 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
936 } else if (!isEvaluated(Expr)) {
937 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
945 if (needsExpansion(Inst))
946 expandInstruction(Inst, IDLoc, Instructions);
948 Instructions.push_back(Inst);
953 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
955 switch (Inst.getOpcode()) {
956 case Mips::LoadImm32Reg:
957 case Mips::LoadAddr32Imm:
958 case Mips::LoadAddr32Reg:
965 void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
966 SmallVectorImpl<MCInst> &Instructions) {
967 switch (Inst.getOpcode()) {
968 case Mips::LoadImm32Reg:
969 return expandLoadImm(Inst, IDLoc, Instructions);
970 case Mips::LoadAddr32Imm:
971 return expandLoadAddressImm(Inst, IDLoc, Instructions);
972 case Mips::LoadAddr32Reg:
973 return expandLoadAddressReg(Inst, IDLoc, Instructions);
977 void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
978 SmallVectorImpl<MCInst> &Instructions) {
980 const MCOperand &ImmOp = Inst.getOperand(1);
981 assert(ImmOp.isImm() && "expected immediate operand kind");
982 const MCOperand &RegOp = Inst.getOperand(0);
983 assert(RegOp.isReg() && "expected register operand kind");
985 int ImmValue = ImmOp.getImm();
986 tmpInst.setLoc(IDLoc);
987 if (0 <= ImmValue && ImmValue <= 65535) {
988 // For 0 <= j <= 65535.
989 // li d,j => ori d,$zero,j
990 tmpInst.setOpcode(Mips::ORi);
991 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
992 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
993 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
994 Instructions.push_back(tmpInst);
995 } else if (ImmValue < 0 && ImmValue >= -32768) {
996 // For -32768 <= j < 0.
997 // li d,j => addiu d,$zero,j
998 tmpInst.setOpcode(Mips::ADDiu);
999 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1000 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1001 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1002 Instructions.push_back(tmpInst);
1004 // For any other value of j that is representable as a 32-bit integer.
1005 // li d,j => lui d,hi16(j)
1007 tmpInst.setOpcode(Mips::LUi);
1008 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1009 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1010 Instructions.push_back(tmpInst);
1012 tmpInst.setOpcode(Mips::ORi);
1013 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1014 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1015 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1016 tmpInst.setLoc(IDLoc);
1017 Instructions.push_back(tmpInst);
1022 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1023 SmallVectorImpl<MCInst> &Instructions) {
1025 const MCOperand &ImmOp = Inst.getOperand(2);
1026 assert(ImmOp.isImm() && "expected immediate operand kind");
1027 const MCOperand &SrcRegOp = Inst.getOperand(1);
1028 assert(SrcRegOp.isReg() && "expected register operand kind");
1029 const MCOperand &DstRegOp = Inst.getOperand(0);
1030 assert(DstRegOp.isReg() && "expected register operand kind");
1031 int ImmValue = ImmOp.getImm();
1032 if (-32768 <= ImmValue && ImmValue <= 65535) {
1033 // For -32768 <= j <= 65535.
1034 // la d,j(s) => addiu d,s,j
1035 tmpInst.setOpcode(Mips::ADDiu);
1036 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1037 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1038 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1039 Instructions.push_back(tmpInst);
1041 // For any other value of j that is representable as a 32-bit integer.
1042 // la d,j(s) => lui d,hi16(j)
1045 tmpInst.setOpcode(Mips::LUi);
1046 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1047 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1048 Instructions.push_back(tmpInst);
1050 tmpInst.setOpcode(Mips::ORi);
1051 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1052 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1053 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1054 Instructions.push_back(tmpInst);
1056 tmpInst.setOpcode(Mips::ADDu);
1057 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1058 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1059 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1060 Instructions.push_back(tmpInst);
1065 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1066 SmallVectorImpl<MCInst> &Instructions) {
1068 const MCOperand &ImmOp = Inst.getOperand(1);
1069 assert(ImmOp.isImm() && "expected immediate operand kind");
1070 const MCOperand &RegOp = Inst.getOperand(0);
1071 assert(RegOp.isReg() && "expected register operand kind");
1072 int ImmValue = ImmOp.getImm();
1073 if (-32768 <= ImmValue && ImmValue <= 65535) {
1074 // For -32768 <= j <= 65535.
1075 // la d,j => addiu d,$zero,j
1076 tmpInst.setOpcode(Mips::ADDiu);
1077 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1078 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1079 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1080 Instructions.push_back(tmpInst);
1082 // For any other value of j that is representable as a 32-bit integer.
1083 // la d,j => lui d,hi16(j)
1085 tmpInst.setOpcode(Mips::LUi);
1086 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1087 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1088 Instructions.push_back(tmpInst);
1090 tmpInst.setOpcode(Mips::ORi);
1091 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1092 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1093 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1094 Instructions.push_back(tmpInst);
1098 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1099 SmallVectorImpl<MCInst> &Instructions,
1100 bool isLoad, bool isImmOpnd) {
1101 const MCSymbolRefExpr *SR;
1103 unsigned ImmOffset, HiOffset, LoOffset;
1104 const MCExpr *ExprOffset;
1106 unsigned AtRegNum = getReg(
1107 (isGP64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
1108 // 1st operand is either the source or destination register.
1109 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1110 unsigned RegOpNum = Inst.getOperand(0).getReg();
1111 // 2nd operand is the base register.
1112 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1113 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1114 // 3rd operand is either an immediate or expression.
1116 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1117 ImmOffset = Inst.getOperand(2).getImm();
1118 LoOffset = ImmOffset & 0x0000ffff;
1119 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1120 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1121 if (LoOffset & 0x8000)
1124 ExprOffset = Inst.getOperand(2).getExpr();
1125 // All instructions will have the same location.
1126 TempInst.setLoc(IDLoc);
1127 // 1st instruction in expansion is LUi. For load instruction we can use
1128 // the dst register as a temporary if base and dst are different,
1129 // but for stores we must use $at.
1130 TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
1131 TempInst.setOpcode(Mips::LUi);
1132 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1134 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1136 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1137 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1138 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1139 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1141 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1143 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1144 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1147 // Add the instruction to the list.
1148 Instructions.push_back(TempInst);
1149 // Prepare TempInst for next instruction.
1151 // Add temp register to base.
1152 TempInst.setOpcode(Mips::ADDu);
1153 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1154 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1155 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1156 Instructions.push_back(TempInst);
1158 // And finally, create original instruction with low part
1159 // of offset and new base.
1160 TempInst.setOpcode(Inst.getOpcode());
1161 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1162 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1164 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1166 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1167 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1168 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1170 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1172 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1173 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1176 Instructions.push_back(TempInst);
1180 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1181 // As described by the Mips32r2 spec, the registers Rd and Rs for
1182 // jalr.hb must be different.
1183 unsigned Opcode = Inst.getOpcode();
1185 if (Opcode == Mips::JALR_HB &&
1186 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1187 return Match_RequiresDifferentSrcAndDst;
1189 return Match_Success;
1192 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1193 OperandVector &Operands,
1195 unsigned &ErrorInfo,
1196 bool MatchingInlineAsm) {
1199 SmallVector<MCInst, 8> Instructions;
1200 unsigned MatchResult =
1201 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1203 switch (MatchResult) {
1206 case Match_Success: {
1207 if (processInstruction(Inst, IDLoc, Instructions))
1209 for (unsigned i = 0; i < Instructions.size(); i++)
1210 Out.EmitInstruction(Instructions[i], STI);
1213 case Match_MissingFeature:
1214 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1216 case Match_InvalidOperand: {
1217 SMLoc ErrorLoc = IDLoc;
1218 if (ErrorInfo != ~0U) {
1219 if (ErrorInfo >= Operands.size())
1220 return Error(IDLoc, "too few operands for instruction");
1222 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1223 if (ErrorLoc == SMLoc())
1227 return Error(ErrorLoc, "invalid operand for instruction");
1229 case Match_MnemonicFail:
1230 return Error(IDLoc, "invalid instruction");
1231 case Match_RequiresDifferentSrcAndDst:
1232 return Error(IDLoc, "source and destination must be different");
1237 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1238 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1240 Warning(Loc, "Used $at without \".set noat\"");
1242 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1243 Twine(RegIndex) + "\"");
1247 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1250 CC = StringSwitch<unsigned>(Name)
1286 if (isN32() || isN64()) {
1287 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1288 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1289 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1290 if (8 <= CC && CC <= 11)
1294 CC = StringSwitch<unsigned>(Name)
1307 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1309 if (Name[0] == 'f') {
1310 StringRef NumString = Name.substr(1);
1312 if (NumString.getAsInteger(10, IntVal))
1313 return -1; // This is not an integer.
1314 if (IntVal > 31) // Maximum index for fpu register.
1321 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1323 if (Name.startswith("fcc")) {
1324 StringRef NumString = Name.substr(3);
1326 if (NumString.getAsInteger(10, IntVal))
1327 return -1; // This is not an integer.
1328 if (IntVal > 7) // There are only 8 fcc registers.
1335 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1337 if (Name.startswith("ac")) {
1338 StringRef NumString = Name.substr(2);
1340 if (NumString.getAsInteger(10, IntVal))
1341 return -1; // This is not an integer.
1342 if (IntVal > 3) // There are only 3 acc registers.
1349 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1352 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1361 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1364 CC = StringSwitch<unsigned>(Name)
1367 .Case("msaaccess", 2)
1369 .Case("msamodify", 4)
1370 .Case("msarequest", 5)
1372 .Case("msaunmap", 7)
1378 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1386 int MipsAsmParser::getATReg() {
1387 int AT = Options.getATRegNum();
1389 TokError("Pseudo instruction requires $at, which is not available");
1393 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1394 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1397 unsigned MipsAsmParser::getGPR(int RegNo) {
1398 return getReg(isGP64() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1402 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1404 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1407 return getReg(RegClass, RegNum);
1410 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1411 DEBUG(dbgs() << "ParseOperand\n");
1413 // Check if the current operand has a custom associated parser, if so, try to
1414 // custom parse the operand, or fallback to the general approach.
1415 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1416 if (ResTy == MatchOperand_Success)
1418 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1419 // there was a match, but an error occurred, in which case, just return that
1420 // the operand parsing failed.
1421 if (ResTy == MatchOperand_ParseFail)
1424 DEBUG(dbgs() << ".. Generic Parser\n");
1426 switch (getLexer().getKind()) {
1428 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1430 case AsmToken::Dollar: {
1431 // Parse the register.
1432 SMLoc S = Parser.getTok().getLoc();
1434 // Almost all registers have been parsed by custom parsers. There is only
1435 // one exception to this. $zero (and it's alias $0) will reach this point
1436 // for div, divu, and similar instructions because it is not an operand
1437 // to the instruction definition but an explicit register. Special case
1438 // this situation for now.
1439 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1442 // Maybe it is a symbol reference.
1443 StringRef Identifier;
1444 if (Parser.parseIdentifier(Identifier))
1447 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1448 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1449 // Otherwise create a symbol reference.
1451 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1453 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1456 // Else drop to expression parsing.
1457 case AsmToken::LParen:
1458 case AsmToken::Minus:
1459 case AsmToken::Plus:
1460 case AsmToken::Integer:
1461 case AsmToken::String: {
1462 DEBUG(dbgs() << ".. generic integer\n");
1463 OperandMatchResultTy ResTy = ParseImm(Operands);
1464 return ResTy != MatchOperand_Success;
1466 case AsmToken::Percent: {
1467 // It is a symbol reference or constant expression.
1468 const MCExpr *IdVal;
1469 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1470 if (parseRelocOperand(IdVal))
1473 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1475 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1477 } // case AsmToken::Percent
1478 } // switch(getLexer().getKind())
1482 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1483 StringRef RelocStr) {
1485 // Check the type of the expression.
1486 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1487 // It's a constant, evaluate reloc value.
1489 switch (getVariantKind(RelocStr)) {
1490 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1491 // Get the 1st 16-bits.
1492 Val = MCE->getValue() & 0xffff;
1494 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1495 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1496 // 16 bits being negative.
1497 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1499 case MCSymbolRefExpr::VK_Mips_HIGHER:
1500 // Get the 3rd 16-bits.
1501 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1503 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1504 // Get the 4th 16-bits.
1505 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1508 report_fatal_error("Unsupported reloc value!");
1510 return MCConstantExpr::Create(Val, getContext());
1513 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1514 // It's a symbol, create a symbolic expression from the symbol.
1515 StringRef Symbol = MSRE->getSymbol().getName();
1516 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1517 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1521 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1522 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1524 // Try to create target expression.
1525 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1526 return MipsMCExpr::Create(VK, Expr, getContext());
1528 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1529 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1530 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1534 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1535 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1536 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1539 // Just return the original expression.
1543 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1545 switch (Expr->getKind()) {
1546 case MCExpr::Constant:
1548 case MCExpr::SymbolRef:
1549 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1550 case MCExpr::Binary:
1551 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1552 if (!isEvaluated(BE->getLHS()))
1554 return isEvaluated(BE->getRHS());
1557 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1558 case MCExpr::Target:
1564 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1565 Parser.Lex(); // Eat the % token.
1566 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1567 if (Tok.isNot(AsmToken::Identifier))
1570 std::string Str = Tok.getIdentifier().str();
1572 Parser.Lex(); // Eat the identifier.
1573 // Now make an expression from the rest of the operand.
1574 const MCExpr *IdVal;
1577 if (getLexer().getKind() == AsmToken::LParen) {
1579 Parser.Lex(); // Eat the '(' token.
1580 if (getLexer().getKind() == AsmToken::Percent) {
1581 Parser.Lex(); // Eat the % token.
1582 const AsmToken &nextTok = Parser.getTok();
1583 if (nextTok.isNot(AsmToken::Identifier))
1586 Str += nextTok.getIdentifier();
1587 Parser.Lex(); // Eat the identifier.
1588 if (getLexer().getKind() != AsmToken::LParen)
1593 if (getParser().parseParenExpression(IdVal, EndLoc))
1596 while (getLexer().getKind() == AsmToken::RParen)
1597 Parser.Lex(); // Eat the ')' token.
1600 return true; // Parenthesis must follow the relocation operand.
1602 Res = evaluateRelocExpr(IdVal, Str);
1606 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1608 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1609 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1610 if (ResTy == MatchOperand_Success) {
1611 assert(Operands.size() == 1);
1612 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1613 StartLoc = Operand.getStartLoc();
1614 EndLoc = Operand.getEndLoc();
1616 // AFAIK, we only support numeric registers and named GPR's in CFI
1618 // Don't worry about eating tokens before failing. Using an unrecognised
1619 // register is a parse error.
1620 if (Operand.isGPRAsmReg()) {
1621 // Resolve to GPR32 or GPR64 appropriately.
1622 RegNo = isGP64() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1625 return (RegNo == (unsigned)-1);
1628 assert(Operands.size() == 0);
1629 return (RegNo == (unsigned)-1);
1632 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1636 while (getLexer().getKind() == AsmToken::LParen)
1639 switch (getLexer().getKind()) {
1642 case AsmToken::Identifier:
1643 case AsmToken::LParen:
1644 case AsmToken::Integer:
1645 case AsmToken::Minus:
1646 case AsmToken::Plus:
1648 Result = getParser().parseParenExpression(Res, S);
1650 Result = (getParser().parseExpression(Res));
1651 while (getLexer().getKind() == AsmToken::RParen)
1654 case AsmToken::Percent:
1655 Result = parseRelocOperand(Res);
1660 MipsAsmParser::OperandMatchResultTy
1661 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1662 DEBUG(dbgs() << "parseMemOperand\n");
1663 const MCExpr *IdVal = nullptr;
1665 bool isParenExpr = false;
1666 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1667 // First operand is the offset.
1668 S = Parser.getTok().getLoc();
1670 if (getLexer().getKind() == AsmToken::LParen) {
1675 if (getLexer().getKind() != AsmToken::Dollar) {
1676 if (parseMemOffset(IdVal, isParenExpr))
1677 return MatchOperand_ParseFail;
1679 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1680 if (Tok.isNot(AsmToken::LParen)) {
1681 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
1682 if (Mnemonic.getToken() == "la") {
1684 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1685 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1686 return MatchOperand_Success;
1688 if (Tok.is(AsmToken::EndOfStatement)) {
1690 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1692 // Zero register assumed, add a memory operand with ZERO as its base.
1693 // "Base" will be managed by k_Memory.
1694 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
1697 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
1698 return MatchOperand_Success;
1700 Error(Parser.getTok().getLoc(), "'(' expected");
1701 return MatchOperand_ParseFail;
1704 Parser.Lex(); // Eat the '(' token.
1707 Res = ParseAnyRegister(Operands);
1708 if (Res != MatchOperand_Success)
1711 if (Parser.getTok().isNot(AsmToken::RParen)) {
1712 Error(Parser.getTok().getLoc(), "')' expected");
1713 return MatchOperand_ParseFail;
1716 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1718 Parser.Lex(); // Eat the ')' token.
1721 IdVal = MCConstantExpr::Create(0, getContext());
1723 // Replace the register operand with the memory operand.
1724 std::unique_ptr<MipsOperand> op(
1725 static_cast<MipsOperand *>(Operands.back().release()));
1726 // Remove the register from the operands.
1727 // "op" will be managed by k_Memory.
1728 Operands.pop_back();
1729 // Add the memory operand.
1730 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1732 if (IdVal->EvaluateAsAbsolute(Imm))
1733 IdVal = MCConstantExpr::Create(Imm, getContext());
1734 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1735 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1739 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
1740 return MatchOperand_Success;
1743 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
1745 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1747 SMLoc S = Parser.getTok().getLoc();
1749 if (Sym->isVariable())
1750 Expr = Sym->getVariableValue();
1753 if (Expr->getKind() == MCExpr::SymbolRef) {
1754 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1755 const StringRef DefSymbol = Ref->getSymbol().getName();
1756 if (DefSymbol.startswith("$")) {
1757 OperandMatchResultTy ResTy =
1758 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
1759 if (ResTy == MatchOperand_Success) {
1762 } else if (ResTy == MatchOperand_ParseFail)
1763 llvm_unreachable("Should never ParseFail");
1766 } else if (Expr->getKind() == MCExpr::Constant) {
1768 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1770 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
1777 MipsAsmParser::OperandMatchResultTy
1778 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
1779 StringRef Identifier,
1781 int Index = matchCPURegisterName(Identifier);
1783 Operands.push_back(MipsOperand::CreateGPRReg(
1784 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1785 return MatchOperand_Success;
1788 Index = matchFPURegisterName(Identifier);
1790 Operands.push_back(MipsOperand::CreateFGRReg(
1791 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1792 return MatchOperand_Success;
1795 Index = matchFCCRegisterName(Identifier);
1797 Operands.push_back(MipsOperand::CreateFCCReg(
1798 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1799 return MatchOperand_Success;
1802 Index = matchACRegisterName(Identifier);
1804 Operands.push_back(MipsOperand::CreateACCReg(
1805 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1806 return MatchOperand_Success;
1809 Index = matchMSA128RegisterName(Identifier);
1811 Operands.push_back(MipsOperand::CreateMSA128Reg(
1812 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1813 return MatchOperand_Success;
1816 Index = matchMSA128CtrlRegisterName(Identifier);
1818 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1819 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1820 return MatchOperand_Success;
1823 return MatchOperand_NoMatch;
1826 MipsAsmParser::OperandMatchResultTy
1827 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
1828 auto Token = Parser.getLexer().peekTok(false);
1830 if (Token.is(AsmToken::Identifier)) {
1831 DEBUG(dbgs() << ".. identifier\n");
1832 StringRef Identifier = Token.getIdentifier();
1833 OperandMatchResultTy ResTy =
1834 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
1836 } else if (Token.is(AsmToken::Integer)) {
1837 DEBUG(dbgs() << ".. integer\n");
1838 Operands.push_back(MipsOperand::CreateNumericReg(
1839 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
1841 return MatchOperand_Success;
1844 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
1846 return MatchOperand_NoMatch;
1849 MipsAsmParser::OperandMatchResultTy
1850 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
1851 DEBUG(dbgs() << "ParseAnyRegister\n");
1853 auto Token = Parser.getTok();
1855 SMLoc S = Token.getLoc();
1857 if (Token.isNot(AsmToken::Dollar)) {
1858 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
1859 if (Token.is(AsmToken::Identifier)) {
1860 if (searchSymbolAlias(Operands))
1861 return MatchOperand_Success;
1863 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
1864 return MatchOperand_NoMatch;
1866 DEBUG(dbgs() << ".. $\n");
1868 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
1869 if (ResTy == MatchOperand_Success) {
1871 Parser.Lex(); // identifier
1876 MipsAsmParser::OperandMatchResultTy
1877 MipsAsmParser::ParseImm(OperandVector &Operands) {
1878 switch (getLexer().getKind()) {
1880 return MatchOperand_NoMatch;
1881 case AsmToken::LParen:
1882 case AsmToken::Minus:
1883 case AsmToken::Plus:
1884 case AsmToken::Integer:
1885 case AsmToken::String:
1889 const MCExpr *IdVal;
1890 SMLoc S = Parser.getTok().getLoc();
1891 if (getParser().parseExpression(IdVal))
1892 return MatchOperand_ParseFail;
1894 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1895 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1896 return MatchOperand_Success;
1899 MipsAsmParser::OperandMatchResultTy
1900 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
1901 DEBUG(dbgs() << "ParseJumpTarget\n");
1903 SMLoc S = getLexer().getLoc();
1905 // Integers and expressions are acceptable
1906 OperandMatchResultTy ResTy = ParseImm(Operands);
1907 if (ResTy != MatchOperand_NoMatch)
1910 // Registers are a valid target and have priority over symbols.
1911 ResTy = ParseAnyRegister(Operands);
1912 if (ResTy != MatchOperand_NoMatch)
1915 const MCExpr *Expr = nullptr;
1916 if (Parser.parseExpression(Expr)) {
1917 // We have no way of knowing if a symbol was consumed so we must ParseFail
1918 return MatchOperand_ParseFail;
1921 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
1922 return MatchOperand_Success;
1925 MipsAsmParser::OperandMatchResultTy
1926 MipsAsmParser::parseInvNum(OperandVector &Operands) {
1927 const MCExpr *IdVal;
1928 // If the first token is '$' we may have register operand.
1929 if (Parser.getTok().is(AsmToken::Dollar))
1930 return MatchOperand_NoMatch;
1931 SMLoc S = Parser.getTok().getLoc();
1932 if (getParser().parseExpression(IdVal))
1933 return MatchOperand_ParseFail;
1934 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
1935 assert(MCE && "Unexpected MCExpr type.");
1936 int64_t Val = MCE->getValue();
1937 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1938 Operands.push_back(MipsOperand::CreateImm(
1939 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
1940 return MatchOperand_Success;
1943 MipsAsmParser::OperandMatchResultTy
1944 MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
1945 switch (getLexer().getKind()) {
1947 return MatchOperand_NoMatch;
1948 case AsmToken::LParen:
1949 case AsmToken::Plus:
1950 case AsmToken::Minus:
1951 case AsmToken::Integer:
1956 SMLoc S = Parser.getTok().getLoc();
1958 if (getParser().parseExpression(Expr))
1959 return MatchOperand_ParseFail;
1962 if (!Expr->EvaluateAsAbsolute(Val)) {
1963 Error(S, "expected immediate value");
1964 return MatchOperand_ParseFail;
1967 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
1968 // and because the CPU always adds one to the immediate field, the allowed
1969 // range becomes 1..4. We'll only check the range here and will deal
1970 // with the addition/subtraction when actually decoding/encoding
1972 if (Val < 1 || Val > 4) {
1973 Error(S, "immediate not in range (1..4)");
1974 return MatchOperand_ParseFail;
1978 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
1979 return MatchOperand_Success;
1982 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1984 MCSymbolRefExpr::VariantKind VK =
1985 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1986 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
1987 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
1988 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
1989 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
1990 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
1991 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
1992 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
1993 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1994 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1995 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
1996 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
1997 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
1998 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
1999 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2000 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2001 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2002 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2003 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2004 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2005 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2006 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2007 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2008 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2009 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2010 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2011 .Default(MCSymbolRefExpr::VK_None);
2013 assert(VK != MCSymbolRefExpr::VK_None);
2018 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2020 /// ::= '(', register, ')'
2021 /// handle it before we iterate so we don't get tripped up by the lack of
2023 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2024 if (getLexer().is(AsmToken::LParen)) {
2026 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2028 if (ParseOperand(Operands, Name)) {
2029 SMLoc Loc = getLexer().getLoc();
2030 Parser.eatToEndOfStatement();
2031 return Error(Loc, "unexpected token in argument list");
2033 if (Parser.getTok().isNot(AsmToken::RParen)) {
2034 SMLoc Loc = getLexer().getLoc();
2035 Parser.eatToEndOfStatement();
2036 return Error(Loc, "unexpected token, expected ')'");
2039 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2045 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2046 /// either one of these.
2047 /// ::= '[', register, ']'
2048 /// ::= '[', integer, ']'
2049 /// handle it before we iterate so we don't get tripped up by the lack of
2051 bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2052 OperandVector &Operands) {
2053 if (getLexer().is(AsmToken::LBrac)) {
2055 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2057 if (ParseOperand(Operands, Name)) {
2058 SMLoc Loc = getLexer().getLoc();
2059 Parser.eatToEndOfStatement();
2060 return Error(Loc, "unexpected token in argument list");
2062 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2063 SMLoc Loc = getLexer().getLoc();
2064 Parser.eatToEndOfStatement();
2065 return Error(Loc, "unexpected token, expected ']'");
2068 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2074 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2075 SMLoc NameLoc, OperandVector &Operands) {
2076 DEBUG(dbgs() << "ParseInstruction\n");
2077 // Check if we have valid mnemonic
2078 if (!mnemonicIsValid(Name, 0)) {
2079 Parser.eatToEndOfStatement();
2080 return Error(NameLoc, "Unknown instruction");
2082 // First operand in MCInst is instruction mnemonic.
2083 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2085 // Read the remaining operands.
2086 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2087 // Read the first operand.
2088 if (ParseOperand(Operands, Name)) {
2089 SMLoc Loc = getLexer().getLoc();
2090 Parser.eatToEndOfStatement();
2091 return Error(Loc, "unexpected token in argument list");
2093 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2095 // AFAIK, parenthesis suffixes are never on the first operand
2097 while (getLexer().is(AsmToken::Comma)) {
2098 Parser.Lex(); // Eat the comma.
2099 // Parse and remember the operand.
2100 if (ParseOperand(Operands, Name)) {
2101 SMLoc Loc = getLexer().getLoc();
2102 Parser.eatToEndOfStatement();
2103 return Error(Loc, "unexpected token in argument list");
2105 // Parse bracket and parenthesis suffixes before we iterate
2106 if (getLexer().is(AsmToken::LBrac)) {
2107 if (ParseBracketSuffix(Name, Operands))
2109 } else if (getLexer().is(AsmToken::LParen) &&
2110 ParseParenSuffix(Name, Operands))
2114 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2115 SMLoc Loc = getLexer().getLoc();
2116 Parser.eatToEndOfStatement();
2117 return Error(Loc, "unexpected token in argument list");
2119 Parser.Lex(); // Consume the EndOfStatement.
2123 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2124 SMLoc Loc = getLexer().getLoc();
2125 Parser.eatToEndOfStatement();
2126 return Error(Loc, ErrorMsg);
2129 bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) {
2130 return Error(Loc, ErrorMsg);
2133 bool MipsAsmParser::parseSetNoAtDirective() {
2134 // Line should look like: ".set noat".
2136 Options.setATReg(0);
2139 // If this is not the end of the statement, report an error.
2140 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2141 reportParseError("unexpected token in statement");
2144 Parser.Lex(); // Consume the EndOfStatement.
2148 bool MipsAsmParser::parseSetAtDirective() {
2149 // Line can be .set at - defaults to $1
2153 if (getLexer().is(AsmToken::EndOfStatement)) {
2154 Options.setATReg(1);
2155 Parser.Lex(); // Consume the EndOfStatement.
2157 } else if (getLexer().is(AsmToken::Equal)) {
2158 getParser().Lex(); // Eat the '='.
2159 if (getLexer().isNot(AsmToken::Dollar)) {
2160 reportParseError("unexpected token in statement");
2163 Parser.Lex(); // Eat the '$'.
2164 const AsmToken &Reg = Parser.getTok();
2165 if (Reg.is(AsmToken::Identifier)) {
2166 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2167 } else if (Reg.is(AsmToken::Integer)) {
2168 AtRegNo = Reg.getIntVal();
2170 reportParseError("unexpected token in statement");
2174 if (AtRegNo < 0 || AtRegNo > 31) {
2175 reportParseError("unexpected token in statement");
2179 if (!Options.setATReg(AtRegNo)) {
2180 reportParseError("unexpected token in statement");
2183 getParser().Lex(); // Eat the register.
2185 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2186 reportParseError("unexpected token in statement");
2189 Parser.Lex(); // Consume the EndOfStatement.
2192 reportParseError("unexpected token in statement");
2197 bool MipsAsmParser::parseSetReorderDirective() {
2199 // If this is not the end of the statement, report an error.
2200 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2201 reportParseError("unexpected token in statement");
2204 Options.setReorder();
2205 getTargetStreamer().emitDirectiveSetReorder();
2206 Parser.Lex(); // Consume the EndOfStatement.
2210 bool MipsAsmParser::parseSetNoReorderDirective() {
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 Options.setNoreorder();
2218 getTargetStreamer().emitDirectiveSetNoReorder();
2219 Parser.Lex(); // Consume the EndOfStatement.
2223 bool MipsAsmParser::parseSetMacroDirective() {
2225 // If this is not the end of the statement, report an error.
2226 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2227 reportParseError("unexpected token in statement");
2231 Parser.Lex(); // Consume the EndOfStatement.
2235 bool MipsAsmParser::parseSetNoMacroDirective() {
2237 // If this is not the end of the statement, report an error.
2238 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2239 reportParseError("`noreorder' must be set before `nomacro'");
2242 if (Options.isReorder()) {
2243 reportParseError("`noreorder' must be set before `nomacro'");
2246 Options.setNomacro();
2247 Parser.Lex(); // Consume the EndOfStatement.
2251 bool MipsAsmParser::parseSetNoMips16Directive() {
2253 // If this is not the end of the statement, report an error.
2254 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2255 reportParseError("unexpected token in statement");
2258 // For now do nothing.
2259 Parser.Lex(); // Consume the EndOfStatement.
2263 bool MipsAsmParser::parseSetAssignment() {
2265 const MCExpr *Value;
2267 if (Parser.parseIdentifier(Name))
2268 reportParseError("expected identifier after .set");
2270 if (getLexer().isNot(AsmToken::Comma))
2271 return reportParseError("unexpected token in .set directive");
2274 if (Parser.parseExpression(Value))
2275 return reportParseError("expected valid expression after comma");
2277 // Check if the Name already exists as a symbol.
2278 MCSymbol *Sym = getContext().LookupSymbol(Name);
2280 return reportParseError("symbol already defined");
2281 Sym = getContext().GetOrCreateSymbol(Name);
2282 Sym->setVariableValue(Value);
2287 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2289 if (getLexer().isNot(AsmToken::EndOfStatement))
2290 return reportParseError("unexpected token in .set directive");
2294 llvm_unreachable("Unimplemented feature");
2295 case Mips::FeatureDSP:
2296 setFeatureBits(Mips::FeatureDSP, "dsp");
2297 getTargetStreamer().emitDirectiveSetDsp();
2299 case Mips::FeatureMicroMips:
2300 getTargetStreamer().emitDirectiveSetMicroMips();
2302 case Mips::FeatureMips16:
2303 getTargetStreamer().emitDirectiveSetMips16();
2305 case Mips::FeatureMips32r2:
2306 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2307 getTargetStreamer().emitDirectiveSetMips32R2();
2309 case Mips::FeatureMips64:
2310 setFeatureBits(Mips::FeatureMips64, "mips64");
2311 getTargetStreamer().emitDirectiveSetMips64();
2313 case Mips::FeatureMips64r2:
2314 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2315 getTargetStreamer().emitDirectiveSetMips64R2();
2321 bool MipsAsmParser::parseRegister(unsigned &RegNum) {
2322 if (!getLexer().is(AsmToken::Dollar))
2327 const AsmToken &Reg = Parser.getTok();
2328 if (Reg.is(AsmToken::Identifier)) {
2329 RegNum = matchCPURegisterName(Reg.getIdentifier());
2330 } else if (Reg.is(AsmToken::Integer)) {
2331 RegNum = Reg.getIntVal();
2340 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2341 if (getLexer().isNot(AsmToken::Comma)) {
2342 SMLoc Loc = getLexer().getLoc();
2343 Parser.eatToEndOfStatement();
2344 return Error(Loc, ErrorStr);
2347 Parser.Lex(); // Eat the comma.
2351 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2352 if (Options.isReorder())
2353 Warning(Loc, ".cpload in reorder section");
2355 // FIXME: Warn if cpload is used in Mips16 mode.
2357 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2358 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2359 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2360 reportParseError("expected register containing function address");
2364 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2365 if (!RegOpnd.isGPRAsmReg()) {
2366 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2370 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2374 bool MipsAsmParser::parseDirectiveCPSetup() {
2377 bool SaveIsReg = true;
2379 if (!parseRegister(FuncReg))
2380 return reportParseError("expected register containing function address");
2381 FuncReg = getGPR(FuncReg);
2383 if (!eatComma("expected comma parsing directive"))
2386 if (!parseRegister(Save)) {
2387 const AsmToken &Tok = Parser.getTok();
2388 if (Tok.is(AsmToken::Integer)) {
2389 Save = Tok.getIntVal();
2393 return reportParseError("expected save register or stack offset");
2395 Save = getGPR(Save);
2397 if (!eatComma("expected comma parsing directive"))
2401 if (Parser.parseIdentifier(Name))
2402 reportParseError("expected identifier");
2403 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2405 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2409 bool MipsAsmParser::parseDirectiveNaN() {
2410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2411 const AsmToken &Tok = Parser.getTok();
2413 if (Tok.getString() == "2008") {
2415 getTargetStreamer().emitDirectiveNaN2008();
2417 } else if (Tok.getString() == "legacy") {
2419 getTargetStreamer().emitDirectiveNaNLegacy();
2423 // If we don't recognize the option passed to the .nan
2424 // directive (e.g. no option or unknown option), emit an error.
2425 reportParseError("invalid option in .nan directive");
2429 bool MipsAsmParser::parseDirectiveSet() {
2431 // Get the next token.
2432 const AsmToken &Tok = Parser.getTok();
2434 if (Tok.getString() == "noat") {
2435 return parseSetNoAtDirective();
2436 } else if (Tok.getString() == "at") {
2437 return parseSetAtDirective();
2438 } else if (Tok.getString() == "reorder") {
2439 return parseSetReorderDirective();
2440 } else if (Tok.getString() == "noreorder") {
2441 return parseSetNoReorderDirective();
2442 } else if (Tok.getString() == "macro") {
2443 return parseSetMacroDirective();
2444 } else if (Tok.getString() == "nomacro") {
2445 return parseSetNoMacroDirective();
2446 } else if (Tok.getString() == "mips16") {
2447 return parseSetFeature(Mips::FeatureMips16);
2448 } else if (Tok.getString() == "nomips16") {
2449 return parseSetNoMips16Directive();
2450 } else if (Tok.getString() == "nomicromips") {
2451 getTargetStreamer().emitDirectiveSetNoMicroMips();
2452 Parser.eatToEndOfStatement();
2454 } else if (Tok.getString() == "micromips") {
2455 return parseSetFeature(Mips::FeatureMicroMips);
2456 } else if (Tok.getString() == "mips32r2") {
2457 return parseSetFeature(Mips::FeatureMips32r2);
2458 } else if (Tok.getString() == "mips64") {
2459 return parseSetFeature(Mips::FeatureMips64);
2460 } else if (Tok.getString() == "mips64r2") {
2461 return parseSetFeature(Mips::FeatureMips64r2);
2462 } else if (Tok.getString() == "dsp") {
2463 return parseSetFeature(Mips::FeatureDSP);
2465 // It is just an identifier, look for an assignment.
2466 parseSetAssignment();
2473 /// parseDataDirective
2474 /// ::= .word [ expression (, expression)* ]
2475 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2476 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2478 const MCExpr *Value;
2479 if (getParser().parseExpression(Value))
2482 getParser().getStreamer().EmitValue(Value, Size);
2484 if (getLexer().is(AsmToken::EndOfStatement))
2487 // FIXME: Improve diagnostic.
2488 if (getLexer().isNot(AsmToken::Comma))
2489 return Error(L, "unexpected token in directive");
2498 /// parseDirectiveGpWord
2499 /// ::= .gpword local_sym
2500 bool MipsAsmParser::parseDirectiveGpWord() {
2501 const MCExpr *Value;
2502 // EmitGPRel32Value requires an expression, so we are using base class
2503 // method to evaluate the expression.
2504 if (getParser().parseExpression(Value))
2506 getParser().getStreamer().EmitGPRel32Value(Value);
2508 if (getLexer().isNot(AsmToken::EndOfStatement))
2509 return Error(getLexer().getLoc(), "unexpected token in directive");
2510 Parser.Lex(); // Eat EndOfStatement token.
2514 /// parseDirectiveGpDWord
2515 /// ::= .gpdword local_sym
2516 bool MipsAsmParser::parseDirectiveGpDWord() {
2517 const MCExpr *Value;
2518 // EmitGPRel64Value requires an expression, so we are using base class
2519 // method to evaluate the expression.
2520 if (getParser().parseExpression(Value))
2522 getParser().getStreamer().EmitGPRel64Value(Value);
2524 if (getLexer().isNot(AsmToken::EndOfStatement))
2525 return Error(getLexer().getLoc(), "unexpected token in directive");
2526 Parser.Lex(); // Eat EndOfStatement token.
2530 bool MipsAsmParser::parseDirectiveOption() {
2531 // Get the option token.
2532 AsmToken Tok = Parser.getTok();
2533 // At the moment only identifiers are supported.
2534 if (Tok.isNot(AsmToken::Identifier)) {
2535 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2536 Parser.eatToEndOfStatement();
2540 StringRef Option = Tok.getIdentifier();
2542 if (Option == "pic0") {
2543 getTargetStreamer().emitDirectiveOptionPic0();
2545 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2546 Error(Parser.getTok().getLoc(),
2547 "unexpected token in .option pic0 directive");
2548 Parser.eatToEndOfStatement();
2553 if (Option == "pic2") {
2554 getTargetStreamer().emitDirectiveOptionPic2();
2556 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2557 Error(Parser.getTok().getLoc(),
2558 "unexpected token in .option pic2 directive");
2559 Parser.eatToEndOfStatement();
2565 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2566 Parser.eatToEndOfStatement();
2570 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2571 StringRef IDVal = DirectiveID.getString();
2573 if (IDVal == ".cpload")
2574 return parseDirectiveCPLoad(DirectiveID.getLoc());
2575 if (IDVal == ".dword") {
2576 parseDataDirective(8, DirectiveID.getLoc());
2580 if (IDVal == ".ent") {
2581 // Ignore this directive for now.
2586 if (IDVal == ".end") {
2587 // Ignore this directive for now.
2592 if (IDVal == ".frame") {
2593 // Ignore this directive for now.
2594 Parser.eatToEndOfStatement();
2598 if (IDVal == ".set") {
2599 return parseDirectiveSet();
2602 if (IDVal == ".fmask") {
2603 // Ignore this directive for now.
2604 Parser.eatToEndOfStatement();
2608 if (IDVal == ".mask") {
2609 // Ignore this directive for now.
2610 Parser.eatToEndOfStatement();
2614 if (IDVal == ".nan")
2615 return parseDirectiveNaN();
2617 if (IDVal == ".gpword") {
2618 parseDirectiveGpWord();
2622 if (IDVal == ".gpdword") {
2623 parseDirectiveGpDWord();
2627 if (IDVal == ".word") {
2628 parseDataDirective(4, DirectiveID.getLoc());
2632 if (IDVal == ".option")
2633 return parseDirectiveOption();
2635 if (IDVal == ".abicalls") {
2636 getTargetStreamer().emitDirectiveAbiCalls();
2637 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2638 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2640 Parser.eatToEndOfStatement();
2645 if (IDVal == ".cpsetup")
2646 return parseDirectiveCPSetup();
2651 extern "C" void LLVMInitializeMipsAsmParser() {
2652 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2653 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2654 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2655 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2658 #define GET_REGISTER_MATCHER
2659 #define GET_MATCHER_IMPLEMENTATION
2660 #include "MipsGenAsmMatcher.inc"