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), fpAbiMode(0) {}
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; }
49 void setFpAbiMode(int Mode) { fpAbiMode = Mode; }
51 bool isMacro() { return macro; }
52 void setMacro() { macro = true; }
53 void setNomacro() { macro = false; }
54 int getFpAbiMode() { return fpAbiMode; }
65 class MipsAsmParser : public MCTargetAsmParser {
66 MipsTargetStreamer &getTargetStreamer() {
67 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
68 return static_cast<MipsTargetStreamer &>(TS);
73 MipsAssemblerOptions Options;
75 #define GET_ASSEMBLER_HEADER
76 #include "MipsGenAsmMatcher.inc"
78 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
80 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
81 OperandVector &Operands, MCStreamer &Out,
83 bool MatchingInlineAsm) override;
85 /// Parse a register as used in CFI directives
86 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
88 bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
90 bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
92 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
93 SMLoc NameLoc, OperandVector &Operands) override;
95 bool ParseDirective(AsmToken DirectiveID) override;
97 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
99 MipsAsmParser::OperandMatchResultTy
100 MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
101 StringRef Identifier, SMLoc S);
103 MipsAsmParser::OperandMatchResultTy
104 MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
106 MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
108 MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
110 MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
112 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
114 MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
116 bool searchSymbolAlias(OperandVector &Operands);
118 bool ParseOperand(OperandVector &, StringRef Mnemonic);
120 bool needsExpansion(MCInst &Inst);
122 // Expands assembly pseudo instructions.
123 // Returns false on success, true otherwise.
124 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
125 SmallVectorImpl<MCInst> &Instructions);
127 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
128 SmallVectorImpl<MCInst> &Instructions);
130 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
131 SmallVectorImpl<MCInst> &Instructions);
133 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
134 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();
162 bool parseSetFpDirective();
164 bool parseSetAssignment();
166 bool parseDataDirective(unsigned Size, SMLoc L);
167 bool parseDirectiveGpWord();
168 bool parseDirectiveGpDWord();
169 bool parseDirectiveModule();
171 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
173 bool eatComma(StringRef ErrorStr);
175 int matchCPURegisterName(StringRef Symbol);
177 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
179 int matchFPURegisterName(StringRef Name);
181 int matchFCCRegisterName(StringRef Name);
183 int matchACRegisterName(StringRef Name);
185 int matchMSA128RegisterName(StringRef Name);
187 int matchMSA128CtrlRegisterName(StringRef Name);
189 unsigned getReg(int RC, int RegNo);
191 unsigned getGPR(int RegNo);
193 int getATReg(SMLoc Loc);
195 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
196 SmallVectorImpl<MCInst> &Instructions);
198 // Helper function that checks if the value of a vector index is within the
199 // boundaries of accepted values for each RegisterKind
200 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
201 bool validateMSAIndex(int Val, int RegKind);
203 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
204 if (!(STI.getFeatureBits() & Feature)) {
205 setAvailableFeatures(
206 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
210 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
211 if (STI.getFeatureBits() & Feature) {
212 setAvailableFeatures(
213 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
218 enum MipsMatchResultTy {
219 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
220 #define GET_OPERAND_DIAGNOSTIC_TYPES
221 #include "MipsGenAsmMatcher.inc"
222 #undef GET_OPERAND_DIAGNOSTIC_TYPES
226 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
227 const MCInstrInfo &MII, const MCTargetOptions &Options)
228 : MCTargetAsmParser(), STI(sti), Parser(parser) {
229 // Initialize the set of available features.
230 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
232 getTargetStreamer().updateABIInfo(*this);
234 // Assert exactly one ABI was chosen.
235 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
236 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
237 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
238 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
241 MCAsmParser &getParser() const { return Parser; }
242 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
244 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
245 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
247 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
248 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
249 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
250 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
251 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
252 bool isABI_FPXX() const { return false; } // TODO: add check for FeatureXX
254 bool inMicroMipsMode() const {
255 return STI.getFeatureBits() & Mips::FeatureMicroMips;
257 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
258 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
259 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
260 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
261 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
262 bool hasMips32() const {
263 return (STI.getFeatureBits() & Mips::FeatureMips32);
265 bool hasMips64() const {
266 return (STI.getFeatureBits() & Mips::FeatureMips64);
268 bool hasMips32r2() const {
269 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
271 bool hasMips64r2() const {
272 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
274 bool hasMips32r6() const {
275 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
277 bool hasMips64r6() const {
278 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
280 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
281 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
282 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
284 bool inMips16Mode() const {
285 return STI.getFeatureBits() & Mips::FeatureMips16;
287 // TODO: see how can we get this info.
288 bool mipsSEUsesSoftFloat() const { return false; }
290 /// Warn if RegNo is the current assembler temporary.
291 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
297 /// MipsOperand - Instances of this class represent a parsed Mips machine
299 class MipsOperand : public MCParsedAsmOperand {
301 /// Broad categories of register classes
302 /// The exact class is finalized by the render method.
304 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
305 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
307 RegKind_FCC = 4, /// FCC
308 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
309 RegKind_MSACtrl = 16, /// MSA control registers
310 RegKind_COP2 = 32, /// COP2
311 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
313 RegKind_CCR = 128, /// CCR
314 RegKind_HWRegs = 256, /// HWRegs
315 RegKind_COP3 = 512, /// COP3
317 /// Potentially any (e.g. $1)
318 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
319 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
320 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
325 k_Immediate, /// An immediate (possibly involving symbol references)
326 k_Memory, /// Base + Offset Memory Address
327 k_PhysRegister, /// A physical register from the Mips namespace
328 k_RegisterIndex, /// A register index in one or more RegKind.
329 k_Token /// A simple token
333 MipsOperand(KindTy K, MipsAsmParser &Parser)
334 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
337 /// For diagnostics, and checking the assembler temporary
338 MipsAsmParser &AsmParser;
346 unsigned Num; /// Register Number
350 unsigned Index; /// Index into the register class
351 RegKind Kind; /// Bitfield of the kinds it could possibly be
352 const MCRegisterInfo *RegInfo;
366 struct PhysRegOp PhysReg;
367 struct RegIdxOp RegIdx;
372 SMLoc StartLoc, EndLoc;
374 /// Internal constructor for register kinds
375 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
376 const MCRegisterInfo *RegInfo,
378 MipsAsmParser &Parser) {
379 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
380 Op->RegIdx.Index = Index;
381 Op->RegIdx.RegInfo = RegInfo;
382 Op->RegIdx.Kind = RegKind;
389 /// Coerce the register to GPR32 and return the real register for the current
391 unsigned getGPR32Reg() const {
392 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
393 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
394 unsigned ClassID = Mips::GPR32RegClassID;
395 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
398 /// Coerce the register to GPR64 and return the real register for the current
400 unsigned getGPR64Reg() const {
401 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
402 unsigned ClassID = Mips::GPR64RegClassID;
403 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
407 /// Coerce the register to AFGR64 and return the real register for the current
409 unsigned getAFGR64Reg() const {
410 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
411 if (RegIdx.Index % 2 != 0)
412 AsmParser.Warning(StartLoc, "Float register should be even.");
413 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
414 .getRegister(RegIdx.Index / 2);
417 /// Coerce the register to FGR64 and return the real register for the current
419 unsigned getFGR64Reg() const {
420 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
421 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
422 .getRegister(RegIdx.Index);
425 /// Coerce the register to FGR32 and return the real register for the current
427 unsigned getFGR32Reg() const {
428 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
429 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
430 .getRegister(RegIdx.Index);
433 /// Coerce the register to FGRH32 and return the real register for the current
435 unsigned getFGRH32Reg() const {
436 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
437 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
438 .getRegister(RegIdx.Index);
441 /// Coerce the register to FCC and return the real register for the current
443 unsigned getFCCReg() const {
444 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
445 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
446 .getRegister(RegIdx.Index);
449 /// Coerce the register to MSA128 and return the real register for the current
451 unsigned getMSA128Reg() const {
452 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
453 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
455 unsigned ClassID = Mips::MSA128BRegClassID;
456 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
459 /// Coerce the register to MSACtrl and return the real register for the
461 unsigned getMSACtrlReg() const {
462 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
463 unsigned ClassID = Mips::MSACtrlRegClassID;
464 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
467 /// Coerce the register to COP2 and return the real register for the
469 unsigned getCOP2Reg() const {
470 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
471 unsigned ClassID = Mips::COP2RegClassID;
472 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
475 /// Coerce the register to COP3 and return the real register for the
477 unsigned getCOP3Reg() const {
478 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
479 unsigned ClassID = Mips::COP3RegClassID;
480 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
483 /// Coerce the register to ACC64DSP and return the real register for the
485 unsigned getACC64DSPReg() const {
486 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
487 unsigned ClassID = Mips::ACC64DSPRegClassID;
488 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
491 /// Coerce the register to HI32DSP and return the real register for the
493 unsigned getHI32DSPReg() const {
494 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
495 unsigned ClassID = Mips::HI32DSPRegClassID;
496 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
499 /// Coerce the register to LO32DSP and return the real register for the
501 unsigned getLO32DSPReg() const {
502 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
503 unsigned ClassID = Mips::LO32DSPRegClassID;
504 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
507 /// Coerce the register to CCR and return the real register for the
509 unsigned getCCRReg() const {
510 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
511 unsigned ClassID = Mips::CCRRegClassID;
512 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
515 /// Coerce the register to HWRegs and return the real register for the
517 unsigned getHWRegsReg() const {
518 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
519 unsigned ClassID = Mips::HWRegsRegClassID;
520 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
524 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
525 // Add as immediate when possible. Null MCExpr = 0.
527 Inst.addOperand(MCOperand::CreateImm(0));
528 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
529 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
531 Inst.addOperand(MCOperand::CreateExpr(Expr));
534 void addRegOperands(MCInst &Inst, unsigned N) const {
535 llvm_unreachable("Use a custom parser instead");
538 /// Render the operand to an MCInst as a GPR32
539 /// Asserts if the wrong number of operands are requested, or the operand
540 /// is not a k_RegisterIndex compatible with RegKind_GPR
541 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
542 assert(N == 1 && "Invalid number of operands!");
543 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
546 /// Render the operand to an MCInst as a GPR64
547 /// Asserts if the wrong number of operands are requested, or the operand
548 /// is not a k_RegisterIndex compatible with RegKind_GPR
549 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
550 assert(N == 1 && "Invalid number of operands!");
551 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
554 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
555 assert(N == 1 && "Invalid number of operands!");
556 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
559 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
560 assert(N == 1 && "Invalid number of operands!");
561 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
564 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
565 assert(N == 1 && "Invalid number of operands!");
566 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
569 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
570 assert(N == 1 && "Invalid number of operands!");
571 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
574 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
575 assert(N == 1 && "Invalid number of operands!");
576 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
579 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
580 assert(N == 1 && "Invalid number of operands!");
581 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
584 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
585 assert(N == 1 && "Invalid number of operands!");
586 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
589 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
590 assert(N == 1 && "Invalid number of operands!");
591 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
594 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
595 assert(N == 1 && "Invalid number of operands!");
596 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
599 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
600 assert(N == 1 && "Invalid number of operands!");
601 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
604 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
605 assert(N == 1 && "Invalid number of operands!");
606 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
609 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
610 assert(N == 1 && "Invalid number of operands!");
611 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
614 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
615 assert(N == 1 && "Invalid number of operands!");
616 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
619 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
620 assert(N == 1 && "Invalid number of operands!");
621 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
624 void addImmOperands(MCInst &Inst, unsigned N) const {
625 assert(N == 1 && "Invalid number of operands!");
626 const MCExpr *Expr = getImm();
630 void addMemOperands(MCInst &Inst, unsigned N) const {
631 assert(N == 2 && "Invalid number of operands!");
633 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
635 const MCExpr *Expr = getMemOff();
639 bool isReg() const override {
640 // As a special case until we sort out the definition of div/divu, pretend
641 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
642 if (isGPRAsmReg() && RegIdx.Index == 0)
645 return Kind == k_PhysRegister;
647 bool isRegIdx() const { return Kind == k_RegisterIndex; }
648 bool isImm() const override { return Kind == k_Immediate; }
649 bool isConstantImm() const {
650 return isImm() && dyn_cast<MCConstantExpr>(getImm());
652 bool isToken() const override {
653 // Note: It's not possible to pretend that other operand kinds are tokens.
654 // The matcher emitter checks tokens first.
655 return Kind == k_Token;
657 bool isMem() const override { return Kind == k_Memory; }
658 bool isConstantMemOff() const {
659 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
661 template <unsigned Bits> bool isMemWithSimmOffset() const {
662 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
664 bool isInvNum() const { return Kind == k_Immediate; }
665 bool isLSAImm() const {
666 if (!isConstantImm())
668 int64_t Val = getConstantImm();
669 return 1 <= Val && Val <= 4;
672 StringRef getToken() const {
673 assert(Kind == k_Token && "Invalid access!");
674 return StringRef(Tok.Data, Tok.Length);
677 unsigned getReg() const override {
678 // As a special case until we sort out the definition of div/divu, pretend
679 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
680 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
681 RegIdx.Kind & RegKind_GPR)
682 return getGPR32Reg(); // FIXME: GPR64 too
684 assert(Kind == k_PhysRegister && "Invalid access!");
688 const MCExpr *getImm() const {
689 assert((Kind == k_Immediate) && "Invalid access!");
693 int64_t getConstantImm() const {
694 const MCExpr *Val = getImm();
695 return static_cast<const MCConstantExpr *>(Val)->getValue();
698 MipsOperand *getMemBase() const {
699 assert((Kind == k_Memory) && "Invalid access!");
703 const MCExpr *getMemOff() const {
704 assert((Kind == k_Memory) && "Invalid access!");
708 int64_t getConstantMemOff() const {
709 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
712 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
713 MipsAsmParser &Parser) {
714 auto Op = make_unique<MipsOperand>(k_Token, Parser);
715 Op->Tok.Data = Str.data();
716 Op->Tok.Length = Str.size();
722 /// Create a numeric register (e.g. $1). The exact register remains
723 /// unresolved until an instruction successfully matches
724 static std::unique_ptr<MipsOperand>
725 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
726 SMLoc E, MipsAsmParser &Parser) {
727 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
728 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
731 /// Create a register that is definitely a GPR.
732 /// This is typically only used for named registers such as $gp.
733 static std::unique_ptr<MipsOperand>
734 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
735 MipsAsmParser &Parser) {
736 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
739 /// Create a register that is definitely a FGR.
740 /// This is typically only used for named registers such as $f0.
741 static std::unique_ptr<MipsOperand>
742 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
743 MipsAsmParser &Parser) {
744 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
747 /// Create a register that is definitely an FCC.
748 /// This is typically only used for named registers such as $fcc0.
749 static std::unique_ptr<MipsOperand>
750 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
751 MipsAsmParser &Parser) {
752 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
755 /// Create a register that is definitely an ACC.
756 /// This is typically only used for named registers such as $ac0.
757 static std::unique_ptr<MipsOperand>
758 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
759 MipsAsmParser &Parser) {
760 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
763 /// Create a register that is definitely an MSA128.
764 /// This is typically only used for named registers such as $w0.
765 static std::unique_ptr<MipsOperand>
766 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
767 SMLoc E, MipsAsmParser &Parser) {
768 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
771 /// Create a register that is definitely an MSACtrl.
772 /// This is typically only used for named registers such as $msaaccess.
773 static std::unique_ptr<MipsOperand>
774 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
775 SMLoc E, MipsAsmParser &Parser) {
776 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
779 static std::unique_ptr<MipsOperand>
780 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
781 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
788 static std::unique_ptr<MipsOperand>
789 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
790 SMLoc E, MipsAsmParser &Parser) {
791 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
792 Op->Mem.Base = Base.release();
799 bool isGPRAsmReg() const {
800 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
802 bool isFGRAsmReg() const {
803 // AFGR64 is $0-$15 but we handle this in getAFGR64()
804 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
806 bool isHWRegsAsmReg() const {
807 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
809 bool isCCRAsmReg() const {
810 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
812 bool isFCCAsmReg() const {
813 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
815 if (!AsmParser.hasEightFccRegisters())
816 return RegIdx.Index == 0;
817 return RegIdx.Index <= 7;
819 bool isACCAsmReg() const {
820 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
822 bool isCOP2AsmReg() const {
823 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
825 bool isCOP3AsmReg() const {
826 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
828 bool isMSA128AsmReg() const {
829 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
831 bool isMSACtrlAsmReg() const {
832 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
835 /// getStartLoc - Get the location of the first token of this operand.
836 SMLoc getStartLoc() const override { return StartLoc; }
837 /// getEndLoc - Get the location of the last token of this operand.
838 SMLoc getEndLoc() const override { return EndLoc; }
840 virtual ~MipsOperand() {
848 case k_RegisterIndex:
854 void print(raw_ostream &OS) const override {
869 OS << "PhysReg<" << PhysReg.Num << ">";
871 case k_RegisterIndex:
872 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
879 }; // class MipsOperand
883 extern const MCInstrDesc MipsInsts[];
885 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
886 return MipsInsts[Opcode];
889 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
890 SmallVectorImpl<MCInst> &Instructions) {
891 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
895 if (MCID.isBranch() || MCID.isCall()) {
896 const unsigned Opcode = Inst.getOpcode();
906 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
907 Offset = Inst.getOperand(2);
909 break; // We'll deal with this situation later on when applying fixups.
910 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
911 return Error(IDLoc, "branch target out of range");
912 if (OffsetToAlignment(Offset.getImm(),
913 1LL << (inMicroMipsMode() ? 1 : 2)))
914 return Error(IDLoc, "branch to misaligned address");
928 case Mips::BGEZAL_MM:
929 case Mips::BLTZAL_MM:
932 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
933 Offset = Inst.getOperand(1);
935 break; // We'll deal with this situation later on when applying fixups.
936 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
937 return Error(IDLoc, "branch target out of range");
938 if (OffsetToAlignment(Offset.getImm(),
939 1LL << (inMicroMipsMode() ? 1 : 2)))
940 return Error(IDLoc, "branch to misaligned address");
945 // SSNOP is deprecated on MIPS32r6/MIPS64r6
946 // We still accept it but it is a normal nop.
947 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
948 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
949 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
953 if (MCID.hasDelaySlot() && Options.isReorder()) {
954 // If this instruction has a delay slot and .set reorder is active,
955 // emit a NOP after it.
956 Instructions.push_back(Inst);
958 NopInst.setOpcode(Mips::SLL);
959 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
960 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
961 NopInst.addOperand(MCOperand::CreateImm(0));
962 Instructions.push_back(NopInst);
966 if (MCID.mayLoad() || MCID.mayStore()) {
967 // Check the offset of memory operand, if it is a symbol
968 // reference or immediate we may have to expand instructions.
969 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
970 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
971 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
972 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
973 MCOperand &Op = Inst.getOperand(i);
975 int MemOffset = Op.getImm();
976 if (MemOffset < -32768 || MemOffset > 32767) {
977 // Offset can't exceed 16bit value.
978 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
981 } else if (Op.isExpr()) {
982 const MCExpr *Expr = Op.getExpr();
983 if (Expr->getKind() == MCExpr::SymbolRef) {
984 const MCSymbolRefExpr *SR =
985 static_cast<const MCSymbolRefExpr *>(Expr);
986 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
988 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
991 } else if (!isEvaluated(Expr)) {
992 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1000 if (needsExpansion(Inst))
1001 return expandInstruction(Inst, IDLoc, Instructions);
1003 Instructions.push_back(Inst);
1008 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1010 switch (Inst.getOpcode()) {
1011 case Mips::LoadImm32Reg:
1012 case Mips::LoadAddr32Imm:
1013 case Mips::LoadAddr32Reg:
1014 case Mips::LoadImm64Reg:
1021 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1022 SmallVectorImpl<MCInst> &Instructions) {
1023 switch (Inst.getOpcode()) {
1025 assert(0 && "unimplemented expansion");
1027 case Mips::LoadImm32Reg:
1028 return expandLoadImm(Inst, IDLoc, Instructions);
1029 case Mips::LoadImm64Reg:
1031 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1034 return expandLoadImm(Inst, IDLoc, Instructions);
1035 case Mips::LoadAddr32Imm:
1036 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1037 case Mips::LoadAddr32Reg:
1038 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1043 template <int Shift, bool PerformShift>
1044 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1045 SmallVectorImpl<MCInst> &Instructions) {
1048 tmpInst.setOpcode(Mips::DSLL);
1049 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1050 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1051 tmpInst.addOperand(MCOperand::CreateImm(16));
1052 tmpInst.setLoc(IDLoc);
1053 Instructions.push_back(tmpInst);
1056 tmpInst.setOpcode(Mips::ORi);
1057 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1058 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1060 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)));
1061 tmpInst.setLoc(IDLoc);
1062 Instructions.push_back(tmpInst);
1066 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1067 SmallVectorImpl<MCInst> &Instructions) {
1069 const MCOperand &ImmOp = Inst.getOperand(1);
1070 assert(ImmOp.isImm() && "expected immediate operand kind");
1071 const MCOperand &RegOp = Inst.getOperand(0);
1072 assert(RegOp.isReg() && "expected register operand kind");
1074 int64_t ImmValue = ImmOp.getImm();
1075 tmpInst.setLoc(IDLoc);
1076 // FIXME: gas has a special case for values that are 000...1111, which
1077 // becomes a li -1 and then a dsrl
1078 if (0 <= ImmValue && ImmValue <= 65535) {
1079 // For 0 <= j <= 65535.
1080 // li d,j => ori d,$zero,j
1081 tmpInst.setOpcode(Mips::ORi);
1082 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1083 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1084 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1085 Instructions.push_back(tmpInst);
1086 } else if (ImmValue < 0 && ImmValue >= -32768) {
1087 // For -32768 <= j < 0.
1088 // li d,j => addiu d,$zero,j
1089 tmpInst.setOpcode(Mips::ADDiu);
1090 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1091 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1092 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1093 Instructions.push_back(tmpInst);
1094 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1095 // For any value of j that is representable as a 32-bit integer, create
1097 // li d,j => lui d,hi16(j)
1099 tmpInst.setOpcode(Mips::LUi);
1100 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1101 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1102 Instructions.push_back(tmpInst);
1103 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1104 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1106 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1110 // <------- lo32 ------>
1111 // <------- hi32 ------>
1112 // <- hi16 -> <- lo16 ->
1113 // _________________________________
1115 // | 16-bytes | 16-bytes | 16-bytes |
1116 // |__________|__________|__________|
1118 // For any value of j that is representable as a 48-bit integer, create
1120 // li d,j => lui d,hi16(j)
1121 // ori d,d,hi16(lo32(j))
1123 // ori d,d,lo16(lo32(j))
1124 tmpInst.setOpcode(Mips::LUi);
1125 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1127 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1128 Instructions.push_back(tmpInst);
1129 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1130 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1133 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1137 // <------- hi32 ------> <------- lo32 ------>
1138 // <- hi16 -> <- lo16 ->
1139 // ___________________________________________
1141 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1142 // |__________|__________|__________|__________|
1144 // For any value of j that isn't representable as a 48-bit integer.
1145 // li d,j => lui d,hi16(j)
1146 // ori d,d,lo16(hi32(j))
1148 // ori d,d,hi16(lo32(j))
1150 // ori d,d,lo16(lo32(j))
1151 tmpInst.setOpcode(Mips::LUi);
1152 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1154 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1155 Instructions.push_back(tmpInst);
1156 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1157 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1158 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1164 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1165 SmallVectorImpl<MCInst> &Instructions) {
1167 const MCOperand &ImmOp = Inst.getOperand(2);
1168 assert(ImmOp.isImm() && "expected immediate operand kind");
1169 const MCOperand &SrcRegOp = Inst.getOperand(1);
1170 assert(SrcRegOp.isReg() && "expected register operand kind");
1171 const MCOperand &DstRegOp = Inst.getOperand(0);
1172 assert(DstRegOp.isReg() && "expected register operand kind");
1173 int ImmValue = ImmOp.getImm();
1174 if (-32768 <= ImmValue && ImmValue <= 65535) {
1175 // For -32768 <= j <= 65535.
1176 // la d,j(s) => addiu d,s,j
1177 tmpInst.setOpcode(Mips::ADDiu);
1178 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1179 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1180 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1181 Instructions.push_back(tmpInst);
1183 // For any other value of j that is representable as a 32-bit integer.
1184 // la d,j(s) => lui d,hi16(j)
1187 tmpInst.setOpcode(Mips::LUi);
1188 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1189 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1190 Instructions.push_back(tmpInst);
1192 tmpInst.setOpcode(Mips::ORi);
1193 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1194 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1195 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1196 Instructions.push_back(tmpInst);
1198 tmpInst.setOpcode(Mips::ADDu);
1199 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1200 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1201 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1202 Instructions.push_back(tmpInst);
1208 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1209 SmallVectorImpl<MCInst> &Instructions) {
1211 const MCOperand &ImmOp = Inst.getOperand(1);
1212 assert(ImmOp.isImm() && "expected immediate operand kind");
1213 const MCOperand &RegOp = Inst.getOperand(0);
1214 assert(RegOp.isReg() && "expected register operand kind");
1215 int ImmValue = ImmOp.getImm();
1216 if (-32768 <= ImmValue && ImmValue <= 65535) {
1217 // For -32768 <= j <= 65535.
1218 // la d,j => addiu d,$zero,j
1219 tmpInst.setOpcode(Mips::ADDiu);
1220 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1221 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1222 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1223 Instructions.push_back(tmpInst);
1225 // For any other value of j that is representable as a 32-bit integer.
1226 // la d,j => lui d,hi16(j)
1228 tmpInst.setOpcode(Mips::LUi);
1229 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1230 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1231 Instructions.push_back(tmpInst);
1233 tmpInst.setOpcode(Mips::ORi);
1234 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1235 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1236 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1237 Instructions.push_back(tmpInst);
1242 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1243 SmallVectorImpl<MCInst> &Instructions,
1244 bool isLoad, bool isImmOpnd) {
1245 const MCSymbolRefExpr *SR;
1247 unsigned ImmOffset, HiOffset, LoOffset;
1248 const MCExpr *ExprOffset;
1250 // 1st operand is either the source or destination register.
1251 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1252 unsigned RegOpNum = Inst.getOperand(0).getReg();
1253 // 2nd operand is the base register.
1254 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1255 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1256 // 3rd operand is either an immediate or expression.
1258 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1259 ImmOffset = Inst.getOperand(2).getImm();
1260 LoOffset = ImmOffset & 0x0000ffff;
1261 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1262 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1263 if (LoOffset & 0x8000)
1266 ExprOffset = Inst.getOperand(2).getExpr();
1267 // All instructions will have the same location.
1268 TempInst.setLoc(IDLoc);
1269 // These are some of the types of expansions we perform here:
1270 // 1) lw $8, sym => lui $8, %hi(sym)
1271 // lw $8, %lo(sym)($8)
1272 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1274 // lw $8, %lo(offset)($9)
1275 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1277 // lw $8, %lo(offset)($at)
1278 // 4) sw $8, sym => lui $at, %hi(sym)
1279 // sw $8, %lo(sym)($at)
1280 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1282 // sw $8, %lo(offset)($at)
1283 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1284 // ldc1 $f0, %lo(sym)($at)
1286 // For load instructions we can use the destination register as a temporary
1287 // if base and dst are different (examples 1 and 2) and if the base register
1288 // is general purpose otherwise we must use $at (example 6) and error if it's
1289 // not available. For stores we must use $at (examples 4 and 5) because we
1290 // must not clobber the source register setting up the offset.
1291 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1292 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1293 unsigned RegClassIDOp0 =
1294 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1295 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1296 (RegClassIDOp0 == Mips::GPR64RegClassID);
1297 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1298 TmpRegNum = RegOpNum;
1300 int AT = getATReg(IDLoc);
1301 // At this point we need AT to perform the expansions and we exit if it is
1306 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1309 TempInst.setOpcode(Mips::LUi);
1310 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1312 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1314 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1315 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1316 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1317 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1319 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1321 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1322 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1325 // Add the instruction to the list.
1326 Instructions.push_back(TempInst);
1327 // Prepare TempInst for next instruction.
1329 // Add temp register to base.
1330 TempInst.setOpcode(Mips::ADDu);
1331 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1332 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1333 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1334 Instructions.push_back(TempInst);
1336 // And finally, create original instruction with low part
1337 // of offset and new base.
1338 TempInst.setOpcode(Inst.getOpcode());
1339 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1340 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1342 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1344 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1345 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1346 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1348 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1350 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1351 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1354 Instructions.push_back(TempInst);
1358 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1359 // As described by the Mips32r2 spec, the registers Rd and Rs for
1360 // jalr.hb must be different.
1361 unsigned Opcode = Inst.getOpcode();
1363 if (Opcode == Mips::JALR_HB &&
1364 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1365 return Match_RequiresDifferentSrcAndDst;
1367 return Match_Success;
1370 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1371 OperandVector &Operands,
1373 unsigned &ErrorInfo,
1374 bool MatchingInlineAsm) {
1377 SmallVector<MCInst, 8> Instructions;
1378 unsigned MatchResult =
1379 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1381 switch (MatchResult) {
1384 case Match_Success: {
1385 if (processInstruction(Inst, IDLoc, Instructions))
1387 for (unsigned i = 0; i < Instructions.size(); i++)
1388 Out.EmitInstruction(Instructions[i], STI);
1391 case Match_MissingFeature:
1392 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1394 case Match_InvalidOperand: {
1395 SMLoc ErrorLoc = IDLoc;
1396 if (ErrorInfo != ~0U) {
1397 if (ErrorInfo >= Operands.size())
1398 return Error(IDLoc, "too few operands for instruction");
1400 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1401 if (ErrorLoc == SMLoc())
1405 return Error(ErrorLoc, "invalid operand for instruction");
1407 case Match_MnemonicFail:
1408 return Error(IDLoc, "invalid instruction");
1409 case Match_RequiresDifferentSrcAndDst:
1410 return Error(IDLoc, "source and destination must be different");
1415 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1416 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1418 Warning(Loc, "Used $at without \".set noat\"");
1420 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1421 Twine(RegIndex) + "\"");
1425 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1428 CC = StringSwitch<unsigned>(Name)
1464 if (isABI_N32() || isABI_N64()) {
1465 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1466 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1467 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1468 if (8 <= CC && CC <= 11)
1472 CC = StringSwitch<unsigned>(Name)
1485 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1487 if (Name[0] == 'f') {
1488 StringRef NumString = Name.substr(1);
1490 if (NumString.getAsInteger(10, IntVal))
1491 return -1; // This is not an integer.
1492 if (IntVal > 31) // Maximum index for fpu register.
1499 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1501 if (Name.startswith("fcc")) {
1502 StringRef NumString = Name.substr(3);
1504 if (NumString.getAsInteger(10, IntVal))
1505 return -1; // This is not an integer.
1506 if (IntVal > 7) // There are only 8 fcc registers.
1513 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1515 if (Name.startswith("ac")) {
1516 StringRef NumString = Name.substr(2);
1518 if (NumString.getAsInteger(10, IntVal))
1519 return -1; // This is not an integer.
1520 if (IntVal > 3) // There are only 3 acc registers.
1527 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1530 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1539 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1542 CC = StringSwitch<unsigned>(Name)
1545 .Case("msaaccess", 2)
1547 .Case("msamodify", 4)
1548 .Case("msarequest", 5)
1550 .Case("msaunmap", 7)
1556 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1564 int MipsAsmParser::getATReg(SMLoc Loc) {
1565 int AT = Options.getATRegNum();
1567 reportParseError(Loc,
1568 "Pseudo instruction requires $at, which is not available");
1572 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1573 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1576 unsigned MipsAsmParser::getGPR(int RegNo) {
1577 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1581 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1583 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1586 return getReg(RegClass, RegNum);
1589 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1590 DEBUG(dbgs() << "ParseOperand\n");
1592 // Check if the current operand has a custom associated parser, if so, try to
1593 // custom parse the operand, or fallback to the general approach.
1594 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1595 if (ResTy == MatchOperand_Success)
1597 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1598 // there was a match, but an error occurred, in which case, just return that
1599 // the operand parsing failed.
1600 if (ResTy == MatchOperand_ParseFail)
1603 DEBUG(dbgs() << ".. Generic Parser\n");
1605 switch (getLexer().getKind()) {
1607 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1609 case AsmToken::Dollar: {
1610 // Parse the register.
1611 SMLoc S = Parser.getTok().getLoc();
1613 // Almost all registers have been parsed by custom parsers. There is only
1614 // one exception to this. $zero (and it's alias $0) will reach this point
1615 // for div, divu, and similar instructions because it is not an operand
1616 // to the instruction definition but an explicit register. Special case
1617 // this situation for now.
1618 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1621 // Maybe it is a symbol reference.
1622 StringRef Identifier;
1623 if (Parser.parseIdentifier(Identifier))
1626 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1627 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1628 // Otherwise create a symbol reference.
1630 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1632 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1635 // Else drop to expression parsing.
1636 case AsmToken::LParen:
1637 case AsmToken::Minus:
1638 case AsmToken::Plus:
1639 case AsmToken::Integer:
1640 case AsmToken::Tilde:
1641 case AsmToken::String: {
1642 DEBUG(dbgs() << ".. generic integer\n");
1643 OperandMatchResultTy ResTy = ParseImm(Operands);
1644 return ResTy != MatchOperand_Success;
1646 case AsmToken::Percent: {
1647 // It is a symbol reference or constant expression.
1648 const MCExpr *IdVal;
1649 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1650 if (parseRelocOperand(IdVal))
1653 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1655 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1657 } // case AsmToken::Percent
1658 } // switch(getLexer().getKind())
1662 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1663 StringRef RelocStr) {
1665 // Check the type of the expression.
1666 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1667 // It's a constant, evaluate reloc value.
1669 switch (getVariantKind(RelocStr)) {
1670 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1671 // Get the 1st 16-bits.
1672 Val = MCE->getValue() & 0xffff;
1674 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1675 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1676 // 16 bits being negative.
1677 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1679 case MCSymbolRefExpr::VK_Mips_HIGHER:
1680 // Get the 3rd 16-bits.
1681 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1683 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1684 // Get the 4th 16-bits.
1685 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1688 report_fatal_error("Unsupported reloc value!");
1690 return MCConstantExpr::Create(Val, getContext());
1693 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1694 // It's a symbol, create a symbolic expression from the symbol.
1695 StringRef Symbol = MSRE->getSymbol().getName();
1696 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1697 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1701 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1702 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1704 // Try to create target expression.
1705 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1706 return MipsMCExpr::Create(VK, Expr, getContext());
1708 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1709 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1710 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1714 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1715 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1716 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1719 // Just return the original expression.
1723 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1725 switch (Expr->getKind()) {
1726 case MCExpr::Constant:
1728 case MCExpr::SymbolRef:
1729 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1730 case MCExpr::Binary:
1731 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1732 if (!isEvaluated(BE->getLHS()))
1734 return isEvaluated(BE->getRHS());
1737 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1738 case MCExpr::Target:
1744 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1745 Parser.Lex(); // Eat the % token.
1746 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1747 if (Tok.isNot(AsmToken::Identifier))
1750 std::string Str = Tok.getIdentifier().str();
1752 Parser.Lex(); // Eat the identifier.
1753 // Now make an expression from the rest of the operand.
1754 const MCExpr *IdVal;
1757 if (getLexer().getKind() == AsmToken::LParen) {
1759 Parser.Lex(); // Eat the '(' token.
1760 if (getLexer().getKind() == AsmToken::Percent) {
1761 Parser.Lex(); // Eat the % token.
1762 const AsmToken &nextTok = Parser.getTok();
1763 if (nextTok.isNot(AsmToken::Identifier))
1766 Str += nextTok.getIdentifier();
1767 Parser.Lex(); // Eat the identifier.
1768 if (getLexer().getKind() != AsmToken::LParen)
1773 if (getParser().parseParenExpression(IdVal, EndLoc))
1776 while (getLexer().getKind() == AsmToken::RParen)
1777 Parser.Lex(); // Eat the ')' token.
1780 return true; // Parenthesis must follow the relocation operand.
1782 Res = evaluateRelocExpr(IdVal, Str);
1786 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1788 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1789 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1790 if (ResTy == MatchOperand_Success) {
1791 assert(Operands.size() == 1);
1792 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1793 StartLoc = Operand.getStartLoc();
1794 EndLoc = Operand.getEndLoc();
1796 // AFAIK, we only support numeric registers and named GPR's in CFI
1798 // Don't worry about eating tokens before failing. Using an unrecognised
1799 // register is a parse error.
1800 if (Operand.isGPRAsmReg()) {
1801 // Resolve to GPR32 or GPR64 appropriately.
1802 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1805 return (RegNo == (unsigned)-1);
1808 assert(Operands.size() == 0);
1809 return (RegNo == (unsigned)-1);
1812 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1816 while (getLexer().getKind() == AsmToken::LParen)
1819 switch (getLexer().getKind()) {
1822 case AsmToken::Identifier:
1823 case AsmToken::LParen:
1824 case AsmToken::Integer:
1825 case AsmToken::Minus:
1826 case AsmToken::Plus:
1828 Result = getParser().parseParenExpression(Res, S);
1830 Result = (getParser().parseExpression(Res));
1831 while (getLexer().getKind() == AsmToken::RParen)
1834 case AsmToken::Percent:
1835 Result = parseRelocOperand(Res);
1840 MipsAsmParser::OperandMatchResultTy
1841 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1842 DEBUG(dbgs() << "parseMemOperand\n");
1843 const MCExpr *IdVal = nullptr;
1845 bool isParenExpr = false;
1846 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1847 // First operand is the offset.
1848 S = Parser.getTok().getLoc();
1850 if (getLexer().getKind() == AsmToken::LParen) {
1855 if (getLexer().getKind() != AsmToken::Dollar) {
1856 if (parseMemOffset(IdVal, isParenExpr))
1857 return MatchOperand_ParseFail;
1859 const AsmToken &Tok = Parser.getTok(); // Get the next token.
1860 if (Tok.isNot(AsmToken::LParen)) {
1861 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
1862 if (Mnemonic.getToken() == "la") {
1864 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1865 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1866 return MatchOperand_Success;
1868 if (Tok.is(AsmToken::EndOfStatement)) {
1870 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1872 // Zero register assumed, add a memory operand with ZERO as its base.
1873 // "Base" will be managed by k_Memory.
1874 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
1877 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
1878 return MatchOperand_Success;
1880 Error(Parser.getTok().getLoc(), "'(' expected");
1881 return MatchOperand_ParseFail;
1884 Parser.Lex(); // Eat the '(' token.
1887 Res = ParseAnyRegister(Operands);
1888 if (Res != MatchOperand_Success)
1891 if (Parser.getTok().isNot(AsmToken::RParen)) {
1892 Error(Parser.getTok().getLoc(), "')' expected");
1893 return MatchOperand_ParseFail;
1896 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1898 Parser.Lex(); // Eat the ')' token.
1901 IdVal = MCConstantExpr::Create(0, getContext());
1903 // Replace the register operand with the memory operand.
1904 std::unique_ptr<MipsOperand> op(
1905 static_cast<MipsOperand *>(Operands.back().release()));
1906 // Remove the register from the operands.
1907 // "op" will be managed by k_Memory.
1908 Operands.pop_back();
1909 // Add the memory operand.
1910 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1912 if (IdVal->EvaluateAsAbsolute(Imm))
1913 IdVal = MCConstantExpr::Create(Imm, getContext());
1914 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1915 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1919 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
1920 return MatchOperand_Success;
1923 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
1925 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1927 SMLoc S = Parser.getTok().getLoc();
1929 if (Sym->isVariable())
1930 Expr = Sym->getVariableValue();
1933 if (Expr->getKind() == MCExpr::SymbolRef) {
1934 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1935 const StringRef DefSymbol = Ref->getSymbol().getName();
1936 if (DefSymbol.startswith("$")) {
1937 OperandMatchResultTy ResTy =
1938 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
1939 if (ResTy == MatchOperand_Success) {
1942 } else if (ResTy == MatchOperand_ParseFail)
1943 llvm_unreachable("Should never ParseFail");
1946 } else if (Expr->getKind() == MCExpr::Constant) {
1948 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1950 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
1957 MipsAsmParser::OperandMatchResultTy
1958 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
1959 StringRef Identifier,
1961 int Index = matchCPURegisterName(Identifier);
1963 Operands.push_back(MipsOperand::CreateGPRReg(
1964 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1965 return MatchOperand_Success;
1968 Index = matchFPURegisterName(Identifier);
1970 Operands.push_back(MipsOperand::CreateFGRReg(
1971 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1972 return MatchOperand_Success;
1975 Index = matchFCCRegisterName(Identifier);
1977 Operands.push_back(MipsOperand::CreateFCCReg(
1978 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1979 return MatchOperand_Success;
1982 Index = matchACRegisterName(Identifier);
1984 Operands.push_back(MipsOperand::CreateACCReg(
1985 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1986 return MatchOperand_Success;
1989 Index = matchMSA128RegisterName(Identifier);
1991 Operands.push_back(MipsOperand::CreateMSA128Reg(
1992 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1993 return MatchOperand_Success;
1996 Index = matchMSA128CtrlRegisterName(Identifier);
1998 Operands.push_back(MipsOperand::CreateMSACtrlReg(
1999 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2000 return MatchOperand_Success;
2003 return MatchOperand_NoMatch;
2006 MipsAsmParser::OperandMatchResultTy
2007 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2008 auto Token = Parser.getLexer().peekTok(false);
2010 if (Token.is(AsmToken::Identifier)) {
2011 DEBUG(dbgs() << ".. identifier\n");
2012 StringRef Identifier = Token.getIdentifier();
2013 OperandMatchResultTy ResTy =
2014 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2016 } else if (Token.is(AsmToken::Integer)) {
2017 DEBUG(dbgs() << ".. integer\n");
2018 Operands.push_back(MipsOperand::CreateNumericReg(
2019 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2021 return MatchOperand_Success;
2024 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2026 return MatchOperand_NoMatch;
2029 MipsAsmParser::OperandMatchResultTy
2030 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
2031 DEBUG(dbgs() << "ParseAnyRegister\n");
2033 auto Token = Parser.getTok();
2035 SMLoc S = Token.getLoc();
2037 if (Token.isNot(AsmToken::Dollar)) {
2038 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2039 if (Token.is(AsmToken::Identifier)) {
2040 if (searchSymbolAlias(Operands))
2041 return MatchOperand_Success;
2043 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2044 return MatchOperand_NoMatch;
2046 DEBUG(dbgs() << ".. $\n");
2048 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
2049 if (ResTy == MatchOperand_Success) {
2051 Parser.Lex(); // identifier
2056 MipsAsmParser::OperandMatchResultTy
2057 MipsAsmParser::ParseImm(OperandVector &Operands) {
2058 switch (getLexer().getKind()) {
2060 return MatchOperand_NoMatch;
2061 case AsmToken::LParen:
2062 case AsmToken::Minus:
2063 case AsmToken::Plus:
2064 case AsmToken::Integer:
2065 case AsmToken::Tilde:
2066 case AsmToken::String:
2070 const MCExpr *IdVal;
2071 SMLoc S = Parser.getTok().getLoc();
2072 if (getParser().parseExpression(IdVal))
2073 return MatchOperand_ParseFail;
2075 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2076 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2077 return MatchOperand_Success;
2080 MipsAsmParser::OperandMatchResultTy
2081 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
2082 DEBUG(dbgs() << "ParseJumpTarget\n");
2084 SMLoc S = getLexer().getLoc();
2086 // Integers and expressions are acceptable
2087 OperandMatchResultTy ResTy = ParseImm(Operands);
2088 if (ResTy != MatchOperand_NoMatch)
2091 // Registers are a valid target and have priority over symbols.
2092 ResTy = ParseAnyRegister(Operands);
2093 if (ResTy != MatchOperand_NoMatch)
2096 const MCExpr *Expr = nullptr;
2097 if (Parser.parseExpression(Expr)) {
2098 // We have no way of knowing if a symbol was consumed so we must ParseFail
2099 return MatchOperand_ParseFail;
2102 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2103 return MatchOperand_Success;
2106 MipsAsmParser::OperandMatchResultTy
2107 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2108 const MCExpr *IdVal;
2109 // If the first token is '$' we may have register operand.
2110 if (Parser.getTok().is(AsmToken::Dollar))
2111 return MatchOperand_NoMatch;
2112 SMLoc S = Parser.getTok().getLoc();
2113 if (getParser().parseExpression(IdVal))
2114 return MatchOperand_ParseFail;
2115 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2116 assert(MCE && "Unexpected MCExpr type.");
2117 int64_t Val = MCE->getValue();
2118 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2119 Operands.push_back(MipsOperand::CreateImm(
2120 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2121 return MatchOperand_Success;
2124 MipsAsmParser::OperandMatchResultTy
2125 MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
2126 switch (getLexer().getKind()) {
2128 return MatchOperand_NoMatch;
2129 case AsmToken::LParen:
2130 case AsmToken::Plus:
2131 case AsmToken::Minus:
2132 case AsmToken::Integer:
2137 SMLoc S = Parser.getTok().getLoc();
2139 if (getParser().parseExpression(Expr))
2140 return MatchOperand_ParseFail;
2143 if (!Expr->EvaluateAsAbsolute(Val)) {
2144 Error(S, "expected immediate value");
2145 return MatchOperand_ParseFail;
2148 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2149 // and because the CPU always adds one to the immediate field, the allowed
2150 // range becomes 1..4. We'll only check the range here and will deal
2151 // with the addition/subtraction when actually decoding/encoding
2153 if (Val < 1 || Val > 4) {
2154 Error(S, "immediate not in range (1..4)");
2155 return MatchOperand_ParseFail;
2159 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2160 return MatchOperand_Success;
2163 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2165 MCSymbolRefExpr::VariantKind VK =
2166 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2167 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2168 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2169 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2170 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2171 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2172 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2173 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2174 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2175 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2176 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2177 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2178 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2179 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2180 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2181 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2182 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2183 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2184 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2185 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2186 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2187 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2188 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2189 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2190 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2191 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2192 .Default(MCSymbolRefExpr::VK_None);
2194 assert(VK != MCSymbolRefExpr::VK_None);
2199 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2201 /// ::= '(', register, ')'
2202 /// handle it before we iterate so we don't get tripped up by the lack of
2204 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2205 if (getLexer().is(AsmToken::LParen)) {
2207 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2209 if (ParseOperand(Operands, Name)) {
2210 SMLoc Loc = getLexer().getLoc();
2211 Parser.eatToEndOfStatement();
2212 return Error(Loc, "unexpected token in argument list");
2214 if (Parser.getTok().isNot(AsmToken::RParen)) {
2215 SMLoc Loc = getLexer().getLoc();
2216 Parser.eatToEndOfStatement();
2217 return Error(Loc, "unexpected token, expected ')'");
2220 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2226 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2227 /// either one of these.
2228 /// ::= '[', register, ']'
2229 /// ::= '[', integer, ']'
2230 /// handle it before we iterate so we don't get tripped up by the lack of
2232 bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2233 OperandVector &Operands) {
2234 if (getLexer().is(AsmToken::LBrac)) {
2236 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2238 if (ParseOperand(Operands, Name)) {
2239 SMLoc Loc = getLexer().getLoc();
2240 Parser.eatToEndOfStatement();
2241 return Error(Loc, "unexpected token in argument list");
2243 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2244 SMLoc Loc = getLexer().getLoc();
2245 Parser.eatToEndOfStatement();
2246 return Error(Loc, "unexpected token, expected ']'");
2249 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2255 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2256 SMLoc NameLoc, OperandVector &Operands) {
2257 DEBUG(dbgs() << "ParseInstruction\n");
2258 // We have reached first instruction, module directive after
2259 // this is forbidden.
2260 getTargetStreamer().setCanHaveModuleDir(false);
2261 // Check if we have valid mnemonic
2262 if (!mnemonicIsValid(Name, 0)) {
2263 Parser.eatToEndOfStatement();
2264 return Error(NameLoc, "Unknown instruction");
2266 // First operand in MCInst is instruction mnemonic.
2267 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2269 // Read the remaining operands.
2270 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2271 // Read the first operand.
2272 if (ParseOperand(Operands, Name)) {
2273 SMLoc Loc = getLexer().getLoc();
2274 Parser.eatToEndOfStatement();
2275 return Error(Loc, "unexpected token in argument list");
2277 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2279 // AFAIK, parenthesis suffixes are never on the first operand
2281 while (getLexer().is(AsmToken::Comma)) {
2282 Parser.Lex(); // Eat the comma.
2283 // Parse and remember the operand.
2284 if (ParseOperand(Operands, Name)) {
2285 SMLoc Loc = getLexer().getLoc();
2286 Parser.eatToEndOfStatement();
2287 return Error(Loc, "unexpected token in argument list");
2289 // Parse bracket and parenthesis suffixes before we iterate
2290 if (getLexer().is(AsmToken::LBrac)) {
2291 if (ParseBracketSuffix(Name, Operands))
2293 } else if (getLexer().is(AsmToken::LParen) &&
2294 ParseParenSuffix(Name, Operands))
2298 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2299 SMLoc Loc = getLexer().getLoc();
2300 Parser.eatToEndOfStatement();
2301 return Error(Loc, "unexpected token in argument list");
2303 Parser.Lex(); // Consume the EndOfStatement.
2307 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2308 SMLoc Loc = getLexer().getLoc();
2309 Parser.eatToEndOfStatement();
2310 return Error(Loc, ErrorMsg);
2313 bool MipsAsmParser::reportParseError(SMLoc Loc, StringRef ErrorMsg) {
2314 return Error(Loc, ErrorMsg);
2317 bool MipsAsmParser::parseSetNoAtDirective() {
2318 // Line should look like: ".set noat".
2320 Options.setATReg(0);
2323 // If this is not the end of the statement, report an error.
2324 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2325 reportParseError("unexpected token in statement");
2328 Parser.Lex(); // Consume the EndOfStatement.
2332 bool MipsAsmParser::parseSetAtDirective() {
2333 // Line can be .set at - defaults to $1
2337 if (getLexer().is(AsmToken::EndOfStatement)) {
2338 Options.setATReg(1);
2339 Parser.Lex(); // Consume the EndOfStatement.
2341 } else if (getLexer().is(AsmToken::Equal)) {
2342 getParser().Lex(); // Eat the '='.
2343 if (getLexer().isNot(AsmToken::Dollar)) {
2344 reportParseError("unexpected token in statement");
2347 Parser.Lex(); // Eat the '$'.
2348 const AsmToken &Reg = Parser.getTok();
2349 if (Reg.is(AsmToken::Identifier)) {
2350 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2351 } else if (Reg.is(AsmToken::Integer)) {
2352 AtRegNo = Reg.getIntVal();
2354 reportParseError("unexpected token in statement");
2358 if (AtRegNo < 0 || AtRegNo > 31) {
2359 reportParseError("unexpected token in statement");
2363 if (!Options.setATReg(AtRegNo)) {
2364 reportParseError("unexpected token in statement");
2367 getParser().Lex(); // Eat the register.
2369 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2370 reportParseError("unexpected token in statement");
2373 Parser.Lex(); // Consume the EndOfStatement.
2376 reportParseError("unexpected token in statement");
2381 bool MipsAsmParser::parseSetReorderDirective() {
2383 // If this is not the end of the statement, report an error.
2384 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2385 reportParseError("unexpected token in statement");
2388 Options.setReorder();
2389 getTargetStreamer().emitDirectiveSetReorder();
2390 Parser.Lex(); // Consume the EndOfStatement.
2394 bool MipsAsmParser::parseSetNoReorderDirective() {
2396 // If this is not the end of the statement, report an error.
2397 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2398 reportParseError("unexpected token in statement");
2401 Options.setNoreorder();
2402 getTargetStreamer().emitDirectiveSetNoReorder();
2403 Parser.Lex(); // Consume the EndOfStatement.
2407 bool MipsAsmParser::parseSetMacroDirective() {
2409 // If this is not the end of the statement, report an error.
2410 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2411 reportParseError("unexpected token in statement");
2415 Parser.Lex(); // Consume the EndOfStatement.
2419 bool MipsAsmParser::parseSetNoMacroDirective() {
2421 // If this is not the end of the statement, report an error.
2422 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2423 reportParseError("`noreorder' must be set before `nomacro'");
2426 if (Options.isReorder()) {
2427 reportParseError("`noreorder' must be set before `nomacro'");
2430 Options.setNomacro();
2431 Parser.Lex(); // Consume the EndOfStatement.
2435 bool MipsAsmParser::parseSetNoMips16Directive() {
2437 // If this is not the end of the statement, report an error.
2438 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2439 reportParseError("unexpected token in statement");
2442 // For now do nothing.
2443 Parser.Lex(); // Consume the EndOfStatement.
2447 bool MipsAsmParser::parseSetFpDirective() {
2449 // Line can be: .set fp=32
2452 Parser.Lex(); // Eat fp token
2453 AsmToken Tok = Parser.getTok();
2454 if (Tok.isNot(AsmToken::Equal)) {
2455 reportParseError("unexpected token in statement");
2458 Parser.Lex(); // Eat '=' token.
2459 Tok = Parser.getTok();
2460 if (Tok.is(AsmToken::Identifier)) {
2461 StringRef XX = Tok.getString();
2463 reportParseError("unsupported option");
2467 reportParseError("'set fp=xx'option requires O32 ABI");
2470 FpAbiMode = Val_GNU_MIPS_ABI_FP_XX;
2471 } else if (Tok.is(AsmToken::Integer)) {
2472 unsigned Value = Tok.getIntVal();
2473 if (Value != 32 && Value != 64) {
2474 reportParseError("unsupported option");
2479 reportParseError("'set fp=32'option requires O32 ABI");
2482 FpAbiMode = Val_GNU_MIPS_ABI_FP_DOUBLE;
2484 if (isABI_N32() || isABI_N64())
2485 FpAbiMode = Val_GNU_MIPS_ABI_FP_DOUBLE;
2486 else if (isABI_O32())
2487 FpAbiMode = Val_GNU_MIPS_ABI_FP_64;
2490 Parser.Lex(); // Eat option token.
2491 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2492 reportParseError("unexpected token in statement");
2495 Options.setFpAbiMode(FpAbiMode);
2496 getTargetStreamer().emitDirectiveSetFp(FpAbiMode, isABI_O32());
2497 Parser.Lex(); // Consume the EndOfStatement.
2501 bool MipsAsmParser::parseSetAssignment() {
2503 const MCExpr *Value;
2505 if (Parser.parseIdentifier(Name))
2506 reportParseError("expected identifier after .set");
2508 if (getLexer().isNot(AsmToken::Comma))
2509 return reportParseError("unexpected token in .set directive");
2512 if (Parser.parseExpression(Value))
2513 return reportParseError("expected valid expression after comma");
2515 // Check if the Name already exists as a symbol.
2516 MCSymbol *Sym = getContext().LookupSymbol(Name);
2518 return reportParseError("symbol already defined");
2519 Sym = getContext().GetOrCreateSymbol(Name);
2520 Sym->setVariableValue(Value);
2525 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2527 if (getLexer().isNot(AsmToken::EndOfStatement))
2528 return reportParseError("unexpected token in .set directive");
2532 llvm_unreachable("Unimplemented feature");
2533 case Mips::FeatureDSP:
2534 setFeatureBits(Mips::FeatureDSP, "dsp");
2535 getTargetStreamer().emitDirectiveSetDsp();
2537 case Mips::FeatureMicroMips:
2538 getTargetStreamer().emitDirectiveSetMicroMips();
2540 case Mips::FeatureMips16:
2541 getTargetStreamer().emitDirectiveSetMips16();
2543 case Mips::FeatureMips32r2:
2544 setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2545 getTargetStreamer().emitDirectiveSetMips32R2();
2547 case Mips::FeatureMips64:
2548 setFeatureBits(Mips::FeatureMips64, "mips64");
2549 getTargetStreamer().emitDirectiveSetMips64();
2551 case Mips::FeatureMips64r2:
2552 setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2553 getTargetStreamer().emitDirectiveSetMips64R2();
2559 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2560 if (getLexer().isNot(AsmToken::Comma)) {
2561 SMLoc Loc = getLexer().getLoc();
2562 Parser.eatToEndOfStatement();
2563 return Error(Loc, ErrorStr);
2566 Parser.Lex(); // Eat the comma.
2570 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2571 if (Options.isReorder())
2572 Warning(Loc, ".cpload in reorder section");
2574 // FIXME: Warn if cpload is used in Mips16 mode.
2576 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2577 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2578 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2579 reportParseError("expected register containing function address");
2583 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2584 if (!RegOpnd.isGPRAsmReg()) {
2585 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2589 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2593 bool MipsAsmParser::parseDirectiveCPSetup() {
2596 bool SaveIsReg = true;
2598 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2599 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2600 if (ResTy == MatchOperand_NoMatch) {
2601 reportParseError("expected register containing function address");
2602 Parser.eatToEndOfStatement();
2606 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2607 if (!FuncRegOpnd.isGPRAsmReg()) {
2608 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2609 Parser.eatToEndOfStatement();
2613 FuncReg = FuncRegOpnd.getGPR32Reg();
2616 if (!eatComma("expected comma parsing directive"))
2619 ResTy = ParseAnyRegister(TmpReg);
2620 if (ResTy == MatchOperand_NoMatch) {
2621 const AsmToken &Tok = Parser.getTok();
2622 if (Tok.is(AsmToken::Integer)) {
2623 Save = Tok.getIntVal();
2627 reportParseError("expected save register or stack offset");
2628 Parser.eatToEndOfStatement();
2632 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2633 if (!SaveOpnd.isGPRAsmReg()) {
2634 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2635 Parser.eatToEndOfStatement();
2638 Save = SaveOpnd.getGPR32Reg();
2641 if (!eatComma("expected comma parsing directive"))
2645 if (Parser.parseIdentifier(Name))
2646 reportParseError("expected identifier");
2647 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2649 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2653 bool MipsAsmParser::parseDirectiveNaN() {
2654 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2655 const AsmToken &Tok = Parser.getTok();
2657 if (Tok.getString() == "2008") {
2659 getTargetStreamer().emitDirectiveNaN2008();
2661 } else if (Tok.getString() == "legacy") {
2663 getTargetStreamer().emitDirectiveNaNLegacy();
2667 // If we don't recognize the option passed to the .nan
2668 // directive (e.g. no option or unknown option), emit an error.
2669 reportParseError("invalid option in .nan directive");
2673 bool MipsAsmParser::parseDirectiveSet() {
2675 // Get the next token.
2676 const AsmToken &Tok = Parser.getTok();
2678 if (Tok.getString() == "noat") {
2679 return parseSetNoAtDirective();
2680 } else if (Tok.getString() == "at") {
2681 return parseSetAtDirective();
2682 } else if (Tok.getString() == "fp") {
2683 return parseSetFpDirective();
2684 } else if (Tok.getString() == "reorder") {
2685 return parseSetReorderDirective();
2686 } else if (Tok.getString() == "noreorder") {
2687 return parseSetNoReorderDirective();
2688 } else if (Tok.getString() == "macro") {
2689 return parseSetMacroDirective();
2690 } else if (Tok.getString() == "nomacro") {
2691 return parseSetNoMacroDirective();
2692 } else if (Tok.getString() == "mips16") {
2693 return parseSetFeature(Mips::FeatureMips16);
2694 } else if (Tok.getString() == "nomips16") {
2695 return parseSetNoMips16Directive();
2696 } else if (Tok.getString() == "nomicromips") {
2697 getTargetStreamer().emitDirectiveSetNoMicroMips();
2698 Parser.eatToEndOfStatement();
2700 } else if (Tok.getString() == "micromips") {
2701 return parseSetFeature(Mips::FeatureMicroMips);
2702 } else if (Tok.getString() == "mips32r2") {
2703 return parseSetFeature(Mips::FeatureMips32r2);
2704 } else if (Tok.getString() == "mips64") {
2705 return parseSetFeature(Mips::FeatureMips64);
2706 } else if (Tok.getString() == "mips64r2") {
2707 return parseSetFeature(Mips::FeatureMips64r2);
2708 } else if (Tok.getString() == "dsp") {
2709 return parseSetFeature(Mips::FeatureDSP);
2711 // It is just an identifier, look for an assignment.
2712 parseSetAssignment();
2719 /// parseDataDirective
2720 /// ::= .word [ expression (, expression)* ]
2721 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2722 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2724 const MCExpr *Value;
2725 if (getParser().parseExpression(Value))
2728 getParser().getStreamer().EmitValue(Value, Size);
2730 if (getLexer().is(AsmToken::EndOfStatement))
2733 // FIXME: Improve diagnostic.
2734 if (getLexer().isNot(AsmToken::Comma))
2735 return Error(L, "unexpected token in directive");
2744 /// parseDirectiveGpWord
2745 /// ::= .gpword local_sym
2746 bool MipsAsmParser::parseDirectiveGpWord() {
2747 const MCExpr *Value;
2748 // EmitGPRel32Value requires an expression, so we are using base class
2749 // method to evaluate the expression.
2750 if (getParser().parseExpression(Value))
2752 getParser().getStreamer().EmitGPRel32Value(Value);
2754 if (getLexer().isNot(AsmToken::EndOfStatement))
2755 return Error(getLexer().getLoc(), "unexpected token in directive");
2756 Parser.Lex(); // Eat EndOfStatement token.
2760 /// parseDirectiveGpDWord
2761 /// ::= .gpdword local_sym
2762 bool MipsAsmParser::parseDirectiveGpDWord() {
2763 const MCExpr *Value;
2764 // EmitGPRel64Value requires an expression, so we are using base class
2765 // method to evaluate the expression.
2766 if (getParser().parseExpression(Value))
2768 getParser().getStreamer().EmitGPRel64Value(Value);
2770 if (getLexer().isNot(AsmToken::EndOfStatement))
2771 return Error(getLexer().getLoc(), "unexpected token in directive");
2772 Parser.Lex(); // Eat EndOfStatement token.
2776 bool MipsAsmParser::parseDirectiveOption() {
2777 // Get the option token.
2778 AsmToken Tok = Parser.getTok();
2779 // At the moment only identifiers are supported.
2780 if (Tok.isNot(AsmToken::Identifier)) {
2781 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2782 Parser.eatToEndOfStatement();
2786 StringRef Option = Tok.getIdentifier();
2788 if (Option == "pic0") {
2789 getTargetStreamer().emitDirectiveOptionPic0();
2791 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2792 Error(Parser.getTok().getLoc(),
2793 "unexpected token in .option pic0 directive");
2794 Parser.eatToEndOfStatement();
2799 if (Option == "pic2") {
2800 getTargetStreamer().emitDirectiveOptionPic2();
2802 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2803 Error(Parser.getTok().getLoc(),
2804 "unexpected token in .option pic2 directive");
2805 Parser.eatToEndOfStatement();
2811 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2812 Parser.eatToEndOfStatement();
2816 bool MipsAsmParser::parseDirectiveModule() {
2817 // Line can be: .module fp=32
2820 unsigned FpAbiVal = 0;
2821 if (!getTargetStreamer().getCanHaveModuleDir()) {
2822 // TODO : get a better message.
2823 reportParseError(".module directive must appear before any code");
2826 AsmToken Tok = Parser.getTok();
2827 if (Tok.isNot(AsmToken::Identifier) && Tok.getString() != "fp") {
2828 reportParseError("unexpected token in .module directive, 'fp' expected");
2831 Parser.Lex(); // Eat fp token
2832 Tok = Parser.getTok();
2833 if (Tok.isNot(AsmToken::Equal)) {
2834 reportParseError("unexpected token in statement");
2837 Parser.Lex(); // Eat '=' token.
2838 Tok = Parser.getTok();
2839 if (Tok.is(AsmToken::Identifier)) {
2840 StringRef XX = Tok.getString();
2842 reportParseError("unsupported option");
2845 FpAbiVal = Val_GNU_MIPS_ABI_FP_XX;
2846 } else if (Tok.is(AsmToken::Integer)) {
2847 unsigned Value = Tok.getIntVal();
2848 if (Value != 32 && Value != 64) {
2849 reportParseError("unsupported value, expected 32 or 64");
2853 if (isABI_N32() || isABI_N64())
2854 FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
2855 else if (isABI_O32())
2856 FpAbiVal = Val_GNU_MIPS_ABI_FP_64;
2857 } else if (isABI_O32())
2858 FpAbiVal = Val_GNU_MIPS_ABI_FP_DOUBLE;
2860 Parser.Lex(); // Eat option token.
2861 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2862 reportParseError("unexpected token in statement");
2865 // Emit appropriate flags.
2866 getTargetStreamer().emitDirectiveModule(FpAbiVal, isABI_O32());
2867 getTargetStreamer().setFpABI(FpAbiVal);
2868 Parser.Lex(); // Consume the EndOfStatement.
2871 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2872 StringRef IDVal = DirectiveID.getString();
2874 if (IDVal == ".cpload")
2875 return parseDirectiveCPLoad(DirectiveID.getLoc());
2876 if (IDVal == ".dword") {
2877 parseDataDirective(8, DirectiveID.getLoc());
2881 if (IDVal == ".ent") {
2882 // Ignore this directive for now.
2887 if (IDVal == ".end") {
2888 // Ignore this directive for now.
2893 if (IDVal == ".frame") {
2894 // Ignore this directive for now.
2895 Parser.eatToEndOfStatement();
2899 if (IDVal == ".set") {
2900 return parseDirectiveSet();
2903 if (IDVal == ".fmask") {
2904 // Ignore this directive for now.
2905 Parser.eatToEndOfStatement();
2909 if (IDVal == ".mask") {
2910 // Ignore this directive for now.
2911 Parser.eatToEndOfStatement();
2915 if (IDVal == ".nan")
2916 return parseDirectiveNaN();
2918 if (IDVal == ".gpword") {
2919 parseDirectiveGpWord();
2923 if (IDVal == ".gpdword") {
2924 parseDirectiveGpDWord();
2928 if (IDVal == ".word") {
2929 parseDataDirective(4, DirectiveID.getLoc());
2933 if (IDVal == ".option")
2934 return parseDirectiveOption();
2936 if (IDVal == ".abicalls") {
2937 getTargetStreamer().emitDirectiveAbiCalls();
2938 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2939 Error(Parser.getTok().getLoc(), "unexpected token in directive");
2941 Parser.eatToEndOfStatement();
2946 if (IDVal == ".cpsetup")
2947 return parseDirectiveCPSetup();
2949 if (IDVal == ".module")
2950 return parseDirectiveModule();
2955 extern "C" void LLVMInitializeMipsAsmParser() {
2956 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2957 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2958 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2959 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2962 #define GET_REGISTER_MATCHER
2963 #define GET_MATCHER_IMPLEMENTATION
2964 #include "MipsGenAsmMatcher.inc"