1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstBuilder.h"
20 #include "llvm/MC/MCParser/MCAsmLexer.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCTargetAsmParser.h"
26 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/MathExtras.h"
28 #include "llvm/Support/TargetRegistry.h"
32 #define DEBUG_TYPE "mips-asm-parser"
39 class MipsAssemblerOptions {
41 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
43 unsigned getATRegNum() { return aTReg; }
44 bool setATReg(unsigned Reg);
46 bool isReorder() { return reorder; }
47 void setReorder() { reorder = true; }
48 void setNoreorder() { reorder = false; }
50 bool isMacro() { return macro; }
51 void setMacro() { macro = true; }
52 void setNomacro() { macro = false; }
54 // Set of features that are either architecture features or referenced
55 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
56 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
57 // The reason we need this mask is explained in the selectArch function.
58 // FIXME: Ideally we would like TableGen to generate this information.
59 static const uint64_t AllArchRelatedMask =
60 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
61 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
62 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
63 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
64 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
65 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
66 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
76 class MipsAsmParser : public MCTargetAsmParser {
77 MipsTargetStreamer &getTargetStreamer() {
78 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
79 return static_cast<MipsTargetStreamer &>(TS);
84 MipsAssemblerOptions Options;
85 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
86 // nullptr, which indicates that no function is currently
87 // selected. This usually happens after an '.end func'
90 #define GET_ASSEMBLER_HEADER
91 #include "MipsGenAsmMatcher.inc"
93 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
95 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
96 OperandVector &Operands, MCStreamer &Out,
98 bool MatchingInlineAsm) override;
100 /// Parse a register as used in CFI directives
101 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
103 bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
105 bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
107 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
108 SMLoc NameLoc, OperandVector &Operands) override;
110 bool ParseDirective(AsmToken DirectiveID) override;
112 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
114 MipsAsmParser::OperandMatchResultTy
115 MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
116 StringRef Identifier, SMLoc S);
118 MipsAsmParser::OperandMatchResultTy
119 MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
121 MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
123 MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
125 MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
127 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
129 MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
131 bool searchSymbolAlias(OperandVector &Operands);
133 bool ParseOperand(OperandVector &, StringRef Mnemonic);
135 bool needsExpansion(MCInst &Inst);
137 // Expands assembly pseudo instructions.
138 // Returns false on success, true otherwise.
139 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
140 SmallVectorImpl<MCInst> &Instructions);
142 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
143 SmallVectorImpl<MCInst> &Instructions);
145 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
146 SmallVectorImpl<MCInst> &Instructions);
148 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
149 SmallVectorImpl<MCInst> &Instructions);
151 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
152 SmallVectorImpl<MCInst> &Instructions);
154 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
155 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
157 bool reportParseError(Twine ErrorMsg);
158 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
160 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
161 bool parseRelocOperand(const MCExpr *&Res);
163 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
165 bool isEvaluated(const MCExpr *Expr);
166 bool parseSetArchDirective();
167 bool parseSetFeature(uint64_t Feature);
168 bool parseDirectiveCPLoad(SMLoc Loc);
169 bool parseDirectiveCPSetup();
170 bool parseDirectiveNaN();
171 bool parseDirectiveSet();
172 bool parseDirectiveOption();
174 bool parseSetAtDirective();
175 bool parseSetNoAtDirective();
176 bool parseSetMacroDirective();
177 bool parseSetNoMacroDirective();
178 bool parseSetMsaDirective();
179 bool parseSetNoMsaDirective();
180 bool parseSetReorderDirective();
181 bool parseSetNoReorderDirective();
182 bool parseSetNoMips16Directive();
183 bool parseSetFpDirective();
185 bool parseSetAssignment();
187 bool parseDataDirective(unsigned Size, SMLoc L);
188 bool parseDirectiveGpWord();
189 bool parseDirectiveGpDWord();
190 bool parseDirectiveModule();
191 bool parseDirectiveModuleFP();
192 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
193 StringRef Directive);
195 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
197 bool eatComma(StringRef ErrorStr);
199 int matchCPURegisterName(StringRef Symbol);
201 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
203 int matchFPURegisterName(StringRef Name);
205 int matchFCCRegisterName(StringRef Name);
207 int matchACRegisterName(StringRef Name);
209 int matchMSA128RegisterName(StringRef Name);
211 int matchMSA128CtrlRegisterName(StringRef Name);
213 unsigned getReg(int RC, int RegNo);
215 unsigned getGPR(int RegNo);
217 int getATReg(SMLoc Loc);
219 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
220 SmallVectorImpl<MCInst> &Instructions);
222 // Helper function that checks if the value of a vector index is within the
223 // boundaries of accepted values for each RegisterKind
224 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
225 bool validateMSAIndex(int Val, int RegKind);
227 // Selects a new architecture by updating the FeatureBits with the necessary
228 // info including implied dependencies.
229 // Internally, it clears all the feature bits related to *any* architecture
230 // and selects the new one using the ToggleFeature functionality of the
231 // MCSubtargetInfo object that handles implied dependencies. The reason we
232 // clear all the arch related bits manually is because ToggleFeature only
233 // clears the features that imply the feature being cleared and not the
234 // features implied by the feature being cleared. This is easier to see
236 // --------------------------------------------------
237 // | Feature | Implies |
238 // | -------------------------------------------------|
239 // | FeatureMips1 | None |
240 // | FeatureMips2 | FeatureMips1 |
241 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
242 // | FeatureMips4 | FeatureMips3 |
244 // --------------------------------------------------
246 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
247 // FeatureMipsGP64 | FeatureMips1)
248 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
249 void selectArch(StringRef ArchFeature) {
250 uint64_t FeatureBits = STI.getFeatureBits();
251 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
252 STI.setFeatureBits(FeatureBits);
253 setAvailableFeatures(
254 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
257 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
258 if (!(STI.getFeatureBits() & Feature)) {
259 setAvailableFeatures(
260 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
264 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
265 if (STI.getFeatureBits() & Feature) {
266 setAvailableFeatures(
267 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
272 enum MipsMatchResultTy {
273 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
274 #define GET_OPERAND_DIAGNOSTIC_TYPES
275 #include "MipsGenAsmMatcher.inc"
276 #undef GET_OPERAND_DIAGNOSTIC_TYPES
280 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
281 const MCInstrInfo &MII, const MCTargetOptions &Options)
282 : MCTargetAsmParser(), STI(sti), Parser(parser) {
283 // Initialize the set of available features.
284 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
286 getTargetStreamer().updateABIInfo(*this);
288 // Assert exactly one ABI was chosen.
289 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
290 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
291 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
292 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
294 if (!isABI_O32() && !useOddSPReg() != 0)
295 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
300 MCAsmParser &getParser() const { return Parser; }
301 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
303 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
304 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
306 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
307 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
308 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
309 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
310 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
311 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
313 bool useOddSPReg() const {
314 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
317 bool inMicroMipsMode() const {
318 return STI.getFeatureBits() & Mips::FeatureMicroMips;
320 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
321 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
322 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
323 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
324 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
325 bool hasMips32() const {
326 return (STI.getFeatureBits() & Mips::FeatureMips32);
328 bool hasMips64() const {
329 return (STI.getFeatureBits() & Mips::FeatureMips64);
331 bool hasMips32r2() const {
332 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
334 bool hasMips64r2() const {
335 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
337 bool hasMips32r6() const {
338 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
340 bool hasMips64r6() const {
341 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
343 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
344 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
345 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
347 bool inMips16Mode() const {
348 return STI.getFeatureBits() & Mips::FeatureMips16;
350 // TODO: see how can we get this info.
351 bool abiUsesSoftFloat() const { return false; }
353 /// Warn if RegNo is the current assembler temporary.
354 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
360 /// MipsOperand - Instances of this class represent a parsed Mips machine
362 class MipsOperand : public MCParsedAsmOperand {
364 /// Broad categories of register classes
365 /// The exact class is finalized by the render method.
367 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
368 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
370 RegKind_FCC = 4, /// FCC
371 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
372 RegKind_MSACtrl = 16, /// MSA control registers
373 RegKind_COP2 = 32, /// COP2
374 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
376 RegKind_CCR = 128, /// CCR
377 RegKind_HWRegs = 256, /// HWRegs
378 RegKind_COP3 = 512, /// COP3
380 /// Potentially any (e.g. $1)
381 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
382 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
383 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
388 k_Immediate, /// An immediate (possibly involving symbol references)
389 k_Memory, /// Base + Offset Memory Address
390 k_PhysRegister, /// A physical register from the Mips namespace
391 k_RegisterIndex, /// A register index in one or more RegKind.
392 k_Token /// A simple token
396 MipsOperand(KindTy K, MipsAsmParser &Parser)
397 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
400 /// For diagnostics, and checking the assembler temporary
401 MipsAsmParser &AsmParser;
409 unsigned Num; /// Register Number
413 unsigned Index; /// Index into the register class
414 RegKind Kind; /// Bitfield of the kinds it could possibly be
415 const MCRegisterInfo *RegInfo;
429 struct PhysRegOp PhysReg;
430 struct RegIdxOp RegIdx;
435 SMLoc StartLoc, EndLoc;
437 /// Internal constructor for register kinds
438 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
439 const MCRegisterInfo *RegInfo,
441 MipsAsmParser &Parser) {
442 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
443 Op->RegIdx.Index = Index;
444 Op->RegIdx.RegInfo = RegInfo;
445 Op->RegIdx.Kind = RegKind;
452 /// Coerce the register to GPR32 and return the real register for the current
454 unsigned getGPR32Reg() const {
455 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
456 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
457 unsigned ClassID = Mips::GPR32RegClassID;
458 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
461 /// Coerce the register to GPR64 and return the real register for the current
463 unsigned getGPR64Reg() const {
464 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
465 unsigned ClassID = Mips::GPR64RegClassID;
466 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
470 /// Coerce the register to AFGR64 and return the real register for the current
472 unsigned getAFGR64Reg() const {
473 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
474 if (RegIdx.Index % 2 != 0)
475 AsmParser.Warning(StartLoc, "Float register should be even.");
476 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
477 .getRegister(RegIdx.Index / 2);
480 /// Coerce the register to FGR64 and return the real register for the current
482 unsigned getFGR64Reg() const {
483 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
484 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
485 .getRegister(RegIdx.Index);
488 /// Coerce the register to FGR32 and return the real register for the current
490 unsigned getFGR32Reg() const {
491 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
492 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
493 .getRegister(RegIdx.Index);
496 /// Coerce the register to FGRH32 and return the real register for the current
498 unsigned getFGRH32Reg() const {
499 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
500 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
501 .getRegister(RegIdx.Index);
504 /// Coerce the register to FCC and return the real register for the current
506 unsigned getFCCReg() const {
507 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
508 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
509 .getRegister(RegIdx.Index);
512 /// Coerce the register to MSA128 and return the real register for the current
514 unsigned getMSA128Reg() const {
515 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
516 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
518 unsigned ClassID = Mips::MSA128BRegClassID;
519 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
522 /// Coerce the register to MSACtrl and return the real register for the
524 unsigned getMSACtrlReg() const {
525 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
526 unsigned ClassID = Mips::MSACtrlRegClassID;
527 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
530 /// Coerce the register to COP2 and return the real register for the
532 unsigned getCOP2Reg() const {
533 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
534 unsigned ClassID = Mips::COP2RegClassID;
535 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
538 /// Coerce the register to COP3 and return the real register for the
540 unsigned getCOP3Reg() const {
541 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
542 unsigned ClassID = Mips::COP3RegClassID;
543 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
546 /// Coerce the register to ACC64DSP and return the real register for the
548 unsigned getACC64DSPReg() const {
549 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
550 unsigned ClassID = Mips::ACC64DSPRegClassID;
551 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
554 /// Coerce the register to HI32DSP and return the real register for the
556 unsigned getHI32DSPReg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
558 unsigned ClassID = Mips::HI32DSPRegClassID;
559 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
562 /// Coerce the register to LO32DSP and return the real register for the
564 unsigned getLO32DSPReg() const {
565 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
566 unsigned ClassID = Mips::LO32DSPRegClassID;
567 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
570 /// Coerce the register to CCR and return the real register for the
572 unsigned getCCRReg() const {
573 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
574 unsigned ClassID = Mips::CCRRegClassID;
575 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
578 /// Coerce the register to HWRegs and return the real register for the
580 unsigned getHWRegsReg() const {
581 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
582 unsigned ClassID = Mips::HWRegsRegClassID;
583 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
587 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
588 // Add as immediate when possible. Null MCExpr = 0.
590 Inst.addOperand(MCOperand::CreateImm(0));
591 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
592 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
594 Inst.addOperand(MCOperand::CreateExpr(Expr));
597 void addRegOperands(MCInst &Inst, unsigned N) const {
598 llvm_unreachable("Use a custom parser instead");
601 /// Render the operand to an MCInst as a GPR32
602 /// Asserts if the wrong number of operands are requested, or the operand
603 /// is not a k_RegisterIndex compatible with RegKind_GPR
604 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
605 assert(N == 1 && "Invalid number of operands!");
606 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
609 /// Render the operand to an MCInst as a GPR64
610 /// Asserts if the wrong number of operands are requested, or the operand
611 /// is not a k_RegisterIndex compatible with RegKind_GPR
612 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
613 assert(N == 1 && "Invalid number of operands!");
614 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
617 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
618 assert(N == 1 && "Invalid number of operands!");
619 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
622 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
623 assert(N == 1 && "Invalid number of operands!");
624 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
627 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
628 assert(N == 1 && "Invalid number of operands!");
629 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
630 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
631 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
632 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
636 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
637 assert(N == 1 && "Invalid number of operands!");
638 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
641 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
642 assert(N == 1 && "Invalid number of operands!");
643 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
646 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
647 assert(N == 1 && "Invalid number of operands!");
648 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
651 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
652 assert(N == 1 && "Invalid number of operands!");
653 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
656 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
661 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
662 assert(N == 1 && "Invalid number of operands!");
663 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
666 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
667 assert(N == 1 && "Invalid number of operands!");
668 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
671 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
672 assert(N == 1 && "Invalid number of operands!");
673 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
676 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
677 assert(N == 1 && "Invalid number of operands!");
678 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
681 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
682 assert(N == 1 && "Invalid number of operands!");
683 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
686 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
687 assert(N == 1 && "Invalid number of operands!");
688 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
691 void addImmOperands(MCInst &Inst, unsigned N) const {
692 assert(N == 1 && "Invalid number of operands!");
693 const MCExpr *Expr = getImm();
697 void addMemOperands(MCInst &Inst, unsigned N) const {
698 assert(N == 2 && "Invalid number of operands!");
700 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
702 const MCExpr *Expr = getMemOff();
706 bool isReg() const override {
707 // As a special case until we sort out the definition of div/divu, pretend
708 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
709 if (isGPRAsmReg() && RegIdx.Index == 0)
712 return Kind == k_PhysRegister;
714 bool isRegIdx() const { return Kind == k_RegisterIndex; }
715 bool isImm() const override { return Kind == k_Immediate; }
716 bool isConstantImm() const {
717 return isImm() && dyn_cast<MCConstantExpr>(getImm());
719 bool isToken() const override {
720 // Note: It's not possible to pretend that other operand kinds are tokens.
721 // The matcher emitter checks tokens first.
722 return Kind == k_Token;
724 bool isMem() const override { return Kind == k_Memory; }
725 bool isConstantMemOff() const {
726 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
728 template <unsigned Bits> bool isMemWithSimmOffset() const {
729 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
731 bool isInvNum() const { return Kind == k_Immediate; }
732 bool isLSAImm() const {
733 if (!isConstantImm())
735 int64_t Val = getConstantImm();
736 return 1 <= Val && Val <= 4;
739 StringRef getToken() const {
740 assert(Kind == k_Token && "Invalid access!");
741 return StringRef(Tok.Data, Tok.Length);
744 unsigned getReg() const override {
745 // As a special case until we sort out the definition of div/divu, pretend
746 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
747 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
748 RegIdx.Kind & RegKind_GPR)
749 return getGPR32Reg(); // FIXME: GPR64 too
751 assert(Kind == k_PhysRegister && "Invalid access!");
755 const MCExpr *getImm() const {
756 assert((Kind == k_Immediate) && "Invalid access!");
760 int64_t getConstantImm() const {
761 const MCExpr *Val = getImm();
762 return static_cast<const MCConstantExpr *>(Val)->getValue();
765 MipsOperand *getMemBase() const {
766 assert((Kind == k_Memory) && "Invalid access!");
770 const MCExpr *getMemOff() const {
771 assert((Kind == k_Memory) && "Invalid access!");
775 int64_t getConstantMemOff() const {
776 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
779 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
780 MipsAsmParser &Parser) {
781 auto Op = make_unique<MipsOperand>(k_Token, Parser);
782 Op->Tok.Data = Str.data();
783 Op->Tok.Length = Str.size();
789 /// Create a numeric register (e.g. $1). The exact register remains
790 /// unresolved until an instruction successfully matches
791 static std::unique_ptr<MipsOperand>
792 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
793 SMLoc E, MipsAsmParser &Parser) {
794 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
795 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
798 /// Create a register that is definitely a GPR.
799 /// This is typically only used for named registers such as $gp.
800 static std::unique_ptr<MipsOperand>
801 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
802 MipsAsmParser &Parser) {
803 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
806 /// Create a register that is definitely a FGR.
807 /// This is typically only used for named registers such as $f0.
808 static std::unique_ptr<MipsOperand>
809 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
810 MipsAsmParser &Parser) {
811 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
814 /// Create a register that is definitely an FCC.
815 /// This is typically only used for named registers such as $fcc0.
816 static std::unique_ptr<MipsOperand>
817 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
818 MipsAsmParser &Parser) {
819 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
822 /// Create a register that is definitely an ACC.
823 /// This is typically only used for named registers such as $ac0.
824 static std::unique_ptr<MipsOperand>
825 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
826 MipsAsmParser &Parser) {
827 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
830 /// Create a register that is definitely an MSA128.
831 /// This is typically only used for named registers such as $w0.
832 static std::unique_ptr<MipsOperand>
833 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
834 SMLoc E, MipsAsmParser &Parser) {
835 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
838 /// Create a register that is definitely an MSACtrl.
839 /// This is typically only used for named registers such as $msaaccess.
840 static std::unique_ptr<MipsOperand>
841 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
842 SMLoc E, MipsAsmParser &Parser) {
843 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
846 static std::unique_ptr<MipsOperand>
847 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
848 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
855 static std::unique_ptr<MipsOperand>
856 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
857 SMLoc E, MipsAsmParser &Parser) {
858 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
859 Op->Mem.Base = Base.release();
866 bool isGPRAsmReg() const {
867 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
869 bool isFGRAsmReg() const {
870 // AFGR64 is $0-$15 but we handle this in getAFGR64()
871 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
873 bool isHWRegsAsmReg() const {
874 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
876 bool isCCRAsmReg() const {
877 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
879 bool isFCCAsmReg() const {
880 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
882 if (!AsmParser.hasEightFccRegisters())
883 return RegIdx.Index == 0;
884 return RegIdx.Index <= 7;
886 bool isACCAsmReg() const {
887 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
889 bool isCOP2AsmReg() const {
890 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
892 bool isCOP3AsmReg() const {
893 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
895 bool isMSA128AsmReg() const {
896 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
898 bool isMSACtrlAsmReg() const {
899 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
902 /// getStartLoc - Get the location of the first token of this operand.
903 SMLoc getStartLoc() const override { return StartLoc; }
904 /// getEndLoc - Get the location of the last token of this operand.
905 SMLoc getEndLoc() const override { return EndLoc; }
907 virtual ~MipsOperand() {
915 case k_RegisterIndex:
921 void print(raw_ostream &OS) const override {
936 OS << "PhysReg<" << PhysReg.Num << ">";
938 case k_RegisterIndex:
939 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
946 }; // class MipsOperand
950 extern const MCInstrDesc MipsInsts[];
952 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
953 return MipsInsts[Opcode];
956 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
957 SmallVectorImpl<MCInst> &Instructions) {
958 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
962 if (MCID.isBranch() || MCID.isCall()) {
963 const unsigned Opcode = Inst.getOpcode();
973 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
974 Offset = Inst.getOperand(2);
976 break; // We'll deal with this situation later on when applying fixups.
977 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
978 return Error(IDLoc, "branch target out of range");
979 if (OffsetToAlignment(Offset.getImm(),
980 1LL << (inMicroMipsMode() ? 1 : 2)))
981 return Error(IDLoc, "branch to misaligned address");
995 case Mips::BGEZAL_MM:
996 case Mips::BLTZAL_MM:
999 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1000 Offset = Inst.getOperand(1);
1001 if (!Offset.isImm())
1002 break; // We'll deal with this situation later on when applying fixups.
1003 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1004 return Error(IDLoc, "branch target out of range");
1005 if (OffsetToAlignment(Offset.getImm(),
1006 1LL << (inMicroMipsMode() ? 1 : 2)))
1007 return Error(IDLoc, "branch to misaligned address");
1012 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1013 // We still accept it but it is a normal nop.
1014 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1015 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1016 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1020 if (MCID.hasDelaySlot() && Options.isReorder()) {
1021 // If this instruction has a delay slot and .set reorder is active,
1022 // emit a NOP after it.
1023 Instructions.push_back(Inst);
1025 NopInst.setOpcode(Mips::SLL);
1026 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1027 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1028 NopInst.addOperand(MCOperand::CreateImm(0));
1029 Instructions.push_back(NopInst);
1033 if (MCID.mayLoad() || MCID.mayStore()) {
1034 // Check the offset of memory operand, if it is a symbol
1035 // reference or immediate we may have to expand instructions.
1036 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1037 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1038 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1039 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1040 MCOperand &Op = Inst.getOperand(i);
1042 int MemOffset = Op.getImm();
1043 if (MemOffset < -32768 || MemOffset > 32767) {
1044 // Offset can't exceed 16bit value.
1045 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1048 } else if (Op.isExpr()) {
1049 const MCExpr *Expr = Op.getExpr();
1050 if (Expr->getKind() == MCExpr::SymbolRef) {
1051 const MCSymbolRefExpr *SR =
1052 static_cast<const MCSymbolRefExpr *>(Expr);
1053 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1055 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1058 } else if (!isEvaluated(Expr)) {
1059 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1067 if (needsExpansion(Inst))
1068 return expandInstruction(Inst, IDLoc, Instructions);
1070 Instructions.push_back(Inst);
1075 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1077 switch (Inst.getOpcode()) {
1078 case Mips::LoadImm32Reg:
1079 case Mips::LoadAddr32Imm:
1080 case Mips::LoadAddr32Reg:
1081 case Mips::LoadImm64Reg:
1088 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1089 SmallVectorImpl<MCInst> &Instructions) {
1090 switch (Inst.getOpcode()) {
1092 assert(0 && "unimplemented expansion");
1094 case Mips::LoadImm32Reg:
1095 return expandLoadImm(Inst, IDLoc, Instructions);
1096 case Mips::LoadImm64Reg:
1098 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1101 return expandLoadImm(Inst, IDLoc, Instructions);
1102 case Mips::LoadAddr32Imm:
1103 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1104 case Mips::LoadAddr32Reg:
1105 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1110 template <bool PerformShift>
1111 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1112 SmallVectorImpl<MCInst> &Instructions) {
1115 tmpInst.setOpcode(Mips::DSLL);
1116 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1117 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1118 tmpInst.addOperand(MCOperand::CreateImm(16));
1119 tmpInst.setLoc(IDLoc);
1120 Instructions.push_back(tmpInst);
1123 tmpInst.setOpcode(Mips::ORi);
1124 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1125 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1126 tmpInst.addOperand(Operand);
1127 tmpInst.setLoc(IDLoc);
1128 Instructions.push_back(tmpInst);
1131 template <int Shift, bool PerformShift>
1132 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1133 SmallVectorImpl<MCInst> &Instructions) {
1134 createShiftOr<PerformShift>(
1135 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1136 IDLoc, Instructions);
1140 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1141 SmallVectorImpl<MCInst> &Instructions) {
1143 const MCOperand &ImmOp = Inst.getOperand(1);
1144 assert(ImmOp.isImm() && "expected immediate operand kind");
1145 const MCOperand &RegOp = Inst.getOperand(0);
1146 assert(RegOp.isReg() && "expected register operand kind");
1148 int64_t ImmValue = ImmOp.getImm();
1149 tmpInst.setLoc(IDLoc);
1150 // FIXME: gas has a special case for values that are 000...1111, which
1151 // becomes a li -1 and then a dsrl
1152 if (0 <= ImmValue && ImmValue <= 65535) {
1153 // For 0 <= j <= 65535.
1154 // li d,j => ori d,$zero,j
1155 tmpInst.setOpcode(Mips::ORi);
1156 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1157 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1158 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1159 Instructions.push_back(tmpInst);
1160 } else if (ImmValue < 0 && ImmValue >= -32768) {
1161 // For -32768 <= j < 0.
1162 // li d,j => addiu d,$zero,j
1163 tmpInst.setOpcode(Mips::ADDiu);
1164 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1165 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1166 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1167 Instructions.push_back(tmpInst);
1168 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1169 // For any value of j that is representable as a 32-bit integer, create
1171 // li d,j => lui d,hi16(j)
1173 tmpInst.setOpcode(Mips::LUi);
1174 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1175 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1176 Instructions.push_back(tmpInst);
1177 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1178 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1180 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1184 // <------- lo32 ------>
1185 // <------- hi32 ------>
1186 // <- hi16 -> <- lo16 ->
1187 // _________________________________
1189 // | 16-bytes | 16-bytes | 16-bytes |
1190 // |__________|__________|__________|
1192 // For any value of j that is representable as a 48-bit integer, create
1194 // li d,j => lui d,hi16(j)
1195 // ori d,d,hi16(lo32(j))
1197 // ori d,d,lo16(lo32(j))
1198 tmpInst.setOpcode(Mips::LUi);
1199 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1201 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1202 Instructions.push_back(tmpInst);
1203 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1204 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1207 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1211 // <------- hi32 ------> <------- lo32 ------>
1212 // <- hi16 -> <- lo16 ->
1213 // ___________________________________________
1215 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1216 // |__________|__________|__________|__________|
1218 // For any value of j that isn't representable as a 48-bit integer.
1219 // li d,j => lui d,hi16(j)
1220 // ori d,d,lo16(hi32(j))
1222 // ori d,d,hi16(lo32(j))
1224 // ori d,d,lo16(lo32(j))
1225 tmpInst.setOpcode(Mips::LUi);
1226 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1228 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1229 Instructions.push_back(tmpInst);
1230 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1231 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1232 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1238 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1239 SmallVectorImpl<MCInst> &Instructions) {
1241 const MCOperand &ImmOp = Inst.getOperand(2);
1242 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1243 "expected immediate operand kind");
1244 if (!ImmOp.isImm()) {
1245 expandLoadAddressSym(Inst, IDLoc, Instructions);
1248 const MCOperand &SrcRegOp = Inst.getOperand(1);
1249 assert(SrcRegOp.isReg() && "expected register operand kind");
1250 const MCOperand &DstRegOp = Inst.getOperand(0);
1251 assert(DstRegOp.isReg() && "expected register operand kind");
1252 int ImmValue = ImmOp.getImm();
1253 if (-32768 <= ImmValue && ImmValue <= 65535) {
1254 // For -32768 <= j <= 65535.
1255 // la d,j(s) => addiu d,s,j
1256 tmpInst.setOpcode(Mips::ADDiu);
1257 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1258 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1259 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1260 Instructions.push_back(tmpInst);
1262 // For any other value of j that is representable as a 32-bit integer.
1263 // la d,j(s) => lui d,hi16(j)
1266 tmpInst.setOpcode(Mips::LUi);
1267 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1268 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1269 Instructions.push_back(tmpInst);
1271 tmpInst.setOpcode(Mips::ORi);
1272 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1273 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1274 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1275 Instructions.push_back(tmpInst);
1277 tmpInst.setOpcode(Mips::ADDu);
1278 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1279 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1280 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1281 Instructions.push_back(tmpInst);
1287 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1288 SmallVectorImpl<MCInst> &Instructions) {
1290 const MCOperand &ImmOp = Inst.getOperand(1);
1291 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1292 "expected immediate operand kind");
1293 if (!ImmOp.isImm()) {
1294 expandLoadAddressSym(Inst, IDLoc, Instructions);
1297 const MCOperand &RegOp = Inst.getOperand(0);
1298 assert(RegOp.isReg() && "expected register operand kind");
1299 int ImmValue = ImmOp.getImm();
1300 if (-32768 <= ImmValue && ImmValue <= 65535) {
1301 // For -32768 <= j <= 65535.
1302 // la d,j => addiu d,$zero,j
1303 tmpInst.setOpcode(Mips::ADDiu);
1304 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1305 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1306 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1307 Instructions.push_back(tmpInst);
1309 // For any other value of j that is representable as a 32-bit integer.
1310 // la d,j => lui d,hi16(j)
1312 tmpInst.setOpcode(Mips::LUi);
1313 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1314 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1315 Instructions.push_back(tmpInst);
1317 tmpInst.setOpcode(Mips::ORi);
1318 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1319 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1320 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1321 Instructions.push_back(tmpInst);
1327 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1328 SmallVectorImpl<MCInst> &Instructions) {
1329 // FIXME: If we do have a valid at register to use, we should generate a
1330 // slightly shorter sequence here.
1332 int ExprOperandNo = 1;
1333 // Sometimes the assembly parser will get the immediate expression as
1334 // a $zero + an immediate.
1335 if (Inst.getNumOperands() == 3) {
1336 assert(Inst.getOperand(1).getReg() ==
1337 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1340 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1341 assert(SymOp.isExpr() && "expected symbol operand kind");
1342 const MCOperand &RegOp = Inst.getOperand(0);
1343 unsigned RegNo = RegOp.getReg();
1344 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1345 const MCSymbolRefExpr *HiExpr =
1346 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1347 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1348 const MCSymbolRefExpr *LoExpr =
1349 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1350 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1352 // If it's a 64-bit architecture, expand to:
1353 // la d,sym => lui d,highest(sym)
1354 // ori d,d,higher(sym)
1356 // ori d,d,hi16(sym)
1358 // ori d,d,lo16(sym)
1359 const MCSymbolRefExpr *HighestExpr =
1360 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1361 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1362 const MCSymbolRefExpr *HigherExpr =
1363 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1364 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1366 tmpInst.setOpcode(Mips::LUi);
1367 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1368 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1369 Instructions.push_back(tmpInst);
1371 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1373 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1375 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1378 // Otherwise, expand to:
1379 // la d,sym => lui d,hi16(sym)
1380 // ori d,d,lo16(sym)
1381 tmpInst.setOpcode(Mips::LUi);
1382 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1383 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1384 Instructions.push_back(tmpInst);
1386 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1391 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1392 SmallVectorImpl<MCInst> &Instructions,
1393 bool isLoad, bool isImmOpnd) {
1394 const MCSymbolRefExpr *SR;
1396 unsigned ImmOffset, HiOffset, LoOffset;
1397 const MCExpr *ExprOffset;
1399 // 1st operand is either the source or destination register.
1400 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1401 unsigned RegOpNum = Inst.getOperand(0).getReg();
1402 // 2nd operand is the base register.
1403 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1404 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1405 // 3rd operand is either an immediate or expression.
1407 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1408 ImmOffset = Inst.getOperand(2).getImm();
1409 LoOffset = ImmOffset & 0x0000ffff;
1410 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1411 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1412 if (LoOffset & 0x8000)
1415 ExprOffset = Inst.getOperand(2).getExpr();
1416 // All instructions will have the same location.
1417 TempInst.setLoc(IDLoc);
1418 // These are some of the types of expansions we perform here:
1419 // 1) lw $8, sym => lui $8, %hi(sym)
1420 // lw $8, %lo(sym)($8)
1421 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1423 // lw $8, %lo(offset)($9)
1424 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1426 // lw $8, %lo(offset)($at)
1427 // 4) sw $8, sym => lui $at, %hi(sym)
1428 // sw $8, %lo(sym)($at)
1429 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1431 // sw $8, %lo(offset)($at)
1432 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1433 // ldc1 $f0, %lo(sym)($at)
1435 // For load instructions we can use the destination register as a temporary
1436 // if base and dst are different (examples 1 and 2) and if the base register
1437 // is general purpose otherwise we must use $at (example 6) and error if it's
1438 // not available. For stores we must use $at (examples 4 and 5) because we
1439 // must not clobber the source register setting up the offset.
1440 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1441 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1442 unsigned RegClassIDOp0 =
1443 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1444 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1445 (RegClassIDOp0 == Mips::GPR64RegClassID);
1446 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1447 TmpRegNum = RegOpNum;
1449 int AT = getATReg(IDLoc);
1450 // At this point we need AT to perform the expansions and we exit if it is
1455 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1458 TempInst.setOpcode(Mips::LUi);
1459 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1461 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1463 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1464 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1465 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1466 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1468 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1470 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1471 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1474 // Add the instruction to the list.
1475 Instructions.push_back(TempInst);
1476 // Prepare TempInst for next instruction.
1478 // Add temp register to base.
1479 TempInst.setOpcode(Mips::ADDu);
1480 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1481 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1482 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1483 Instructions.push_back(TempInst);
1485 // And finally, create original instruction with low part
1486 // of offset and new base.
1487 TempInst.setOpcode(Inst.getOpcode());
1488 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1489 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1491 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1493 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1494 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1495 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1497 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1499 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1500 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1503 Instructions.push_back(TempInst);
1507 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1508 // As described by the Mips32r2 spec, the registers Rd and Rs for
1509 // jalr.hb must be different.
1510 unsigned Opcode = Inst.getOpcode();
1512 if (Opcode == Mips::JALR_HB &&
1513 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1514 return Match_RequiresDifferentSrcAndDst;
1516 return Match_Success;
1519 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1520 OperandVector &Operands,
1522 uint64_t &ErrorInfo,
1523 bool MatchingInlineAsm) {
1526 SmallVector<MCInst, 8> Instructions;
1527 unsigned MatchResult =
1528 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1530 switch (MatchResult) {
1533 case Match_Success: {
1534 if (processInstruction(Inst, IDLoc, Instructions))
1536 for (unsigned i = 0; i < Instructions.size(); i++)
1537 Out.EmitInstruction(Instructions[i], STI);
1540 case Match_MissingFeature:
1541 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1543 case Match_InvalidOperand: {
1544 SMLoc ErrorLoc = IDLoc;
1545 if (ErrorInfo != ~0ULL) {
1546 if (ErrorInfo >= Operands.size())
1547 return Error(IDLoc, "too few operands for instruction");
1549 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1550 if (ErrorLoc == SMLoc())
1554 return Error(ErrorLoc, "invalid operand for instruction");
1556 case Match_MnemonicFail:
1557 return Error(IDLoc, "invalid instruction");
1558 case Match_RequiresDifferentSrcAndDst:
1559 return Error(IDLoc, "source and destination must be different");
1564 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1565 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1567 Warning(Loc, "Used $at without \".set noat\"");
1569 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1570 Twine(RegIndex) + "\"");
1574 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1577 CC = StringSwitch<unsigned>(Name)
1613 if (isABI_N32() || isABI_N64()) {
1614 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1615 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1616 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1617 if (8 <= CC && CC <= 11)
1621 CC = StringSwitch<unsigned>(Name)
1634 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1636 if (Name[0] == 'f') {
1637 StringRef NumString = Name.substr(1);
1639 if (NumString.getAsInteger(10, IntVal))
1640 return -1; // This is not an integer.
1641 if (IntVal > 31) // Maximum index for fpu register.
1648 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1650 if (Name.startswith("fcc")) {
1651 StringRef NumString = Name.substr(3);
1653 if (NumString.getAsInteger(10, IntVal))
1654 return -1; // This is not an integer.
1655 if (IntVal > 7) // There are only 8 fcc registers.
1662 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1664 if (Name.startswith("ac")) {
1665 StringRef NumString = Name.substr(2);
1667 if (NumString.getAsInteger(10, IntVal))
1668 return -1; // This is not an integer.
1669 if (IntVal > 3) // There are only 3 acc registers.
1676 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1679 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1688 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1691 CC = StringSwitch<unsigned>(Name)
1694 .Case("msaaccess", 2)
1696 .Case("msamodify", 4)
1697 .Case("msarequest", 5)
1699 .Case("msaunmap", 7)
1705 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1713 int MipsAsmParser::getATReg(SMLoc Loc) {
1714 int AT = Options.getATRegNum();
1716 reportParseError(Loc,
1717 "Pseudo instruction requires $at, which is not available");
1721 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1722 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1725 unsigned MipsAsmParser::getGPR(int RegNo) {
1726 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1730 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1732 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1735 return getReg(RegClass, RegNum);
1738 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1739 DEBUG(dbgs() << "ParseOperand\n");
1741 // Check if the current operand has a custom associated parser, if so, try to
1742 // custom parse the operand, or fallback to the general approach.
1743 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1744 if (ResTy == MatchOperand_Success)
1746 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1747 // there was a match, but an error occurred, in which case, just return that
1748 // the operand parsing failed.
1749 if (ResTy == MatchOperand_ParseFail)
1752 DEBUG(dbgs() << ".. Generic Parser\n");
1754 switch (getLexer().getKind()) {
1756 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1758 case AsmToken::Dollar: {
1759 // Parse the register.
1760 SMLoc S = Parser.getTok().getLoc();
1762 // Almost all registers have been parsed by custom parsers. There is only
1763 // one exception to this. $zero (and it's alias $0) will reach this point
1764 // for div, divu, and similar instructions because it is not an operand
1765 // to the instruction definition but an explicit register. Special case
1766 // this situation for now.
1767 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1770 // Maybe it is a symbol reference.
1771 StringRef Identifier;
1772 if (Parser.parseIdentifier(Identifier))
1775 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1776 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1777 // Otherwise create a symbol reference.
1779 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1781 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1784 // Else drop to expression parsing.
1785 case AsmToken::LParen:
1786 case AsmToken::Minus:
1787 case AsmToken::Plus:
1788 case AsmToken::Integer:
1789 case AsmToken::Tilde:
1790 case AsmToken::String: {
1791 DEBUG(dbgs() << ".. generic integer\n");
1792 OperandMatchResultTy ResTy = ParseImm(Operands);
1793 return ResTy != MatchOperand_Success;
1795 case AsmToken::Percent: {
1796 // It is a symbol reference or constant expression.
1797 const MCExpr *IdVal;
1798 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1799 if (parseRelocOperand(IdVal))
1802 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1804 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1806 } // case AsmToken::Percent
1807 } // switch(getLexer().getKind())
1811 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1812 StringRef RelocStr) {
1814 // Check the type of the expression.
1815 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1816 // It's a constant, evaluate reloc value.
1818 switch (getVariantKind(RelocStr)) {
1819 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1820 // Get the 1st 16-bits.
1821 Val = MCE->getValue() & 0xffff;
1823 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1824 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1825 // 16 bits being negative.
1826 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1828 case MCSymbolRefExpr::VK_Mips_HIGHER:
1829 // Get the 3rd 16-bits.
1830 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1832 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1833 // Get the 4th 16-bits.
1834 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1837 report_fatal_error("Unsupported reloc value!");
1839 return MCConstantExpr::Create(Val, getContext());
1842 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1843 // It's a symbol, create a symbolic expression from the symbol.
1844 StringRef Symbol = MSRE->getSymbol().getName();
1845 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1846 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1850 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1851 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1853 // Try to create target expression.
1854 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1855 return MipsMCExpr::Create(VK, Expr, getContext());
1857 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1858 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1859 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1863 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1864 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1865 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1868 // Just return the original expression.
1872 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1874 switch (Expr->getKind()) {
1875 case MCExpr::Constant:
1877 case MCExpr::SymbolRef:
1878 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1879 case MCExpr::Binary:
1880 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1881 if (!isEvaluated(BE->getLHS()))
1883 return isEvaluated(BE->getRHS());
1886 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1887 case MCExpr::Target:
1893 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1894 Parser.Lex(); // Eat the % token.
1895 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1896 if (Tok.isNot(AsmToken::Identifier))
1899 std::string Str = Tok.getIdentifier().str();
1901 Parser.Lex(); // Eat the identifier.
1902 // Now make an expression from the rest of the operand.
1903 const MCExpr *IdVal;
1906 if (getLexer().getKind() == AsmToken::LParen) {
1908 Parser.Lex(); // Eat the '(' token.
1909 if (getLexer().getKind() == AsmToken::Percent) {
1910 Parser.Lex(); // Eat the % token.
1911 const AsmToken &nextTok = Parser.getTok();
1912 if (nextTok.isNot(AsmToken::Identifier))
1915 Str += nextTok.getIdentifier();
1916 Parser.Lex(); // Eat the identifier.
1917 if (getLexer().getKind() != AsmToken::LParen)
1922 if (getParser().parseParenExpression(IdVal, EndLoc))
1925 while (getLexer().getKind() == AsmToken::RParen)
1926 Parser.Lex(); // Eat the ')' token.
1929 return true; // Parenthesis must follow the relocation operand.
1931 Res = evaluateRelocExpr(IdVal, Str);
1935 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1937 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1938 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1939 if (ResTy == MatchOperand_Success) {
1940 assert(Operands.size() == 1);
1941 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1942 StartLoc = Operand.getStartLoc();
1943 EndLoc = Operand.getEndLoc();
1945 // AFAIK, we only support numeric registers and named GPR's in CFI
1947 // Don't worry about eating tokens before failing. Using an unrecognised
1948 // register is a parse error.
1949 if (Operand.isGPRAsmReg()) {
1950 // Resolve to GPR32 or GPR64 appropriately.
1951 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1954 return (RegNo == (unsigned)-1);
1957 assert(Operands.size() == 0);
1958 return (RegNo == (unsigned)-1);
1961 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1965 while (getLexer().getKind() == AsmToken::LParen)
1968 switch (getLexer().getKind()) {
1971 case AsmToken::Identifier:
1972 case AsmToken::LParen:
1973 case AsmToken::Integer:
1974 case AsmToken::Minus:
1975 case AsmToken::Plus:
1977 Result = getParser().parseParenExpression(Res, S);
1979 Result = (getParser().parseExpression(Res));
1980 while (getLexer().getKind() == AsmToken::RParen)
1983 case AsmToken::Percent:
1984 Result = parseRelocOperand(Res);
1989 MipsAsmParser::OperandMatchResultTy
1990 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1991 DEBUG(dbgs() << "parseMemOperand\n");
1992 const MCExpr *IdVal = nullptr;
1994 bool isParenExpr = false;
1995 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1996 // First operand is the offset.
1997 S = Parser.getTok().getLoc();
1999 if (getLexer().getKind() == AsmToken::LParen) {
2004 if (getLexer().getKind() != AsmToken::Dollar) {
2005 if (parseMemOffset(IdVal, isParenExpr))
2006 return MatchOperand_ParseFail;
2008 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2009 if (Tok.isNot(AsmToken::LParen)) {
2010 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2011 if (Mnemonic.getToken() == "la") {
2013 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2014 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2015 return MatchOperand_Success;
2017 if (Tok.is(AsmToken::EndOfStatement)) {
2019 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2021 // Zero register assumed, add a memory operand with ZERO as its base.
2022 // "Base" will be managed by k_Memory.
2023 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
2026 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2027 return MatchOperand_Success;
2029 Error(Parser.getTok().getLoc(), "'(' expected");
2030 return MatchOperand_ParseFail;
2033 Parser.Lex(); // Eat the '(' token.
2036 Res = ParseAnyRegister(Operands);
2037 if (Res != MatchOperand_Success)
2040 if (Parser.getTok().isNot(AsmToken::RParen)) {
2041 Error(Parser.getTok().getLoc(), "')' expected");
2042 return MatchOperand_ParseFail;
2045 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2047 Parser.Lex(); // Eat the ')' token.
2050 IdVal = MCConstantExpr::Create(0, getContext());
2052 // Replace the register operand with the memory operand.
2053 std::unique_ptr<MipsOperand> op(
2054 static_cast<MipsOperand *>(Operands.back().release()));
2055 // Remove the register from the operands.
2056 // "op" will be managed by k_Memory.
2057 Operands.pop_back();
2058 // Add the memory operand.
2059 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2061 if (IdVal->EvaluateAsAbsolute(Imm))
2062 IdVal = MCConstantExpr::Create(Imm, getContext());
2063 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2064 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2068 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2069 return MatchOperand_Success;
2072 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2074 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2076 SMLoc S = Parser.getTok().getLoc();
2078 if (Sym->isVariable())
2079 Expr = Sym->getVariableValue();
2082 if (Expr->getKind() == MCExpr::SymbolRef) {
2083 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2084 StringRef DefSymbol = Ref->getSymbol().getName();
2085 if (DefSymbol.startswith("$")) {
2086 OperandMatchResultTy ResTy =
2087 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2088 if (ResTy == MatchOperand_Success) {
2091 } else if (ResTy == MatchOperand_ParseFail)
2092 llvm_unreachable("Should never ParseFail");
2095 } else if (Expr->getKind() == MCExpr::Constant) {
2097 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2099 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2106 MipsAsmParser::OperandMatchResultTy
2107 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2108 StringRef Identifier,
2110 int Index = matchCPURegisterName(Identifier);
2112 Operands.push_back(MipsOperand::CreateGPRReg(
2113 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2114 return MatchOperand_Success;
2117 Index = matchFPURegisterName(Identifier);
2119 Operands.push_back(MipsOperand::CreateFGRReg(
2120 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2121 return MatchOperand_Success;
2124 Index = matchFCCRegisterName(Identifier);
2126 Operands.push_back(MipsOperand::CreateFCCReg(
2127 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2128 return MatchOperand_Success;
2131 Index = matchACRegisterName(Identifier);
2133 Operands.push_back(MipsOperand::CreateACCReg(
2134 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2135 return MatchOperand_Success;
2138 Index = matchMSA128RegisterName(Identifier);
2140 Operands.push_back(MipsOperand::CreateMSA128Reg(
2141 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2142 return MatchOperand_Success;
2145 Index = matchMSA128CtrlRegisterName(Identifier);
2147 Operands.push_back(MipsOperand::CreateMSACtrlReg(
2148 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2149 return MatchOperand_Success;
2152 return MatchOperand_NoMatch;
2155 MipsAsmParser::OperandMatchResultTy
2156 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2157 auto Token = Parser.getLexer().peekTok(false);
2159 if (Token.is(AsmToken::Identifier)) {
2160 DEBUG(dbgs() << ".. identifier\n");
2161 StringRef Identifier = Token.getIdentifier();
2162 OperandMatchResultTy ResTy =
2163 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2165 } else if (Token.is(AsmToken::Integer)) {
2166 DEBUG(dbgs() << ".. integer\n");
2167 Operands.push_back(MipsOperand::CreateNumericReg(
2168 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2170 return MatchOperand_Success;
2173 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2175 return MatchOperand_NoMatch;
2178 MipsAsmParser::OperandMatchResultTy
2179 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
2180 DEBUG(dbgs() << "ParseAnyRegister\n");
2182 auto Token = Parser.getTok();
2184 SMLoc S = Token.getLoc();
2186 if (Token.isNot(AsmToken::Dollar)) {
2187 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2188 if (Token.is(AsmToken::Identifier)) {
2189 if (searchSymbolAlias(Operands))
2190 return MatchOperand_Success;
2192 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2193 return MatchOperand_NoMatch;
2195 DEBUG(dbgs() << ".. $\n");
2197 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
2198 if (ResTy == MatchOperand_Success) {
2200 Parser.Lex(); // identifier
2205 MipsAsmParser::OperandMatchResultTy
2206 MipsAsmParser::ParseImm(OperandVector &Operands) {
2207 switch (getLexer().getKind()) {
2209 return MatchOperand_NoMatch;
2210 case AsmToken::LParen:
2211 case AsmToken::Minus:
2212 case AsmToken::Plus:
2213 case AsmToken::Integer:
2214 case AsmToken::Tilde:
2215 case AsmToken::String:
2219 const MCExpr *IdVal;
2220 SMLoc S = Parser.getTok().getLoc();
2221 if (getParser().parseExpression(IdVal))
2222 return MatchOperand_ParseFail;
2224 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2225 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2226 return MatchOperand_Success;
2229 MipsAsmParser::OperandMatchResultTy
2230 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
2231 DEBUG(dbgs() << "ParseJumpTarget\n");
2233 SMLoc S = getLexer().getLoc();
2235 // Integers and expressions are acceptable
2236 OperandMatchResultTy ResTy = ParseImm(Operands);
2237 if (ResTy != MatchOperand_NoMatch)
2240 // Registers are a valid target and have priority over symbols.
2241 ResTy = ParseAnyRegister(Operands);
2242 if (ResTy != MatchOperand_NoMatch)
2245 const MCExpr *Expr = nullptr;
2246 if (Parser.parseExpression(Expr)) {
2247 // We have no way of knowing if a symbol was consumed so we must ParseFail
2248 return MatchOperand_ParseFail;
2251 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2252 return MatchOperand_Success;
2255 MipsAsmParser::OperandMatchResultTy
2256 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2257 const MCExpr *IdVal;
2258 // If the first token is '$' we may have register operand.
2259 if (Parser.getTok().is(AsmToken::Dollar))
2260 return MatchOperand_NoMatch;
2261 SMLoc S = Parser.getTok().getLoc();
2262 if (getParser().parseExpression(IdVal))
2263 return MatchOperand_ParseFail;
2264 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2265 assert(MCE && "Unexpected MCExpr type.");
2266 int64_t Val = MCE->getValue();
2267 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2268 Operands.push_back(MipsOperand::CreateImm(
2269 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2270 return MatchOperand_Success;
2273 MipsAsmParser::OperandMatchResultTy
2274 MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
2275 switch (getLexer().getKind()) {
2277 return MatchOperand_NoMatch;
2278 case AsmToken::LParen:
2279 case AsmToken::Plus:
2280 case AsmToken::Minus:
2281 case AsmToken::Integer:
2286 SMLoc S = Parser.getTok().getLoc();
2288 if (getParser().parseExpression(Expr))
2289 return MatchOperand_ParseFail;
2292 if (!Expr->EvaluateAsAbsolute(Val)) {
2293 Error(S, "expected immediate value");
2294 return MatchOperand_ParseFail;
2297 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2298 // and because the CPU always adds one to the immediate field, the allowed
2299 // range becomes 1..4. We'll only check the range here and will deal
2300 // with the addition/subtraction when actually decoding/encoding
2302 if (Val < 1 || Val > 4) {
2303 Error(S, "immediate not in range (1..4)");
2304 return MatchOperand_ParseFail;
2308 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2309 return MatchOperand_Success;
2312 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2314 MCSymbolRefExpr::VariantKind VK =
2315 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2316 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2317 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2318 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2319 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2320 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2321 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2322 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2323 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2324 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2325 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2326 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2327 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2328 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2329 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2330 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2331 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2332 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2333 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2334 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2335 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2336 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2337 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2338 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2339 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2340 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2341 .Default(MCSymbolRefExpr::VK_None);
2343 assert(VK != MCSymbolRefExpr::VK_None);
2348 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2350 /// ::= '(', register, ')'
2351 /// handle it before we iterate so we don't get tripped up by the lack of
2353 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2354 if (getLexer().is(AsmToken::LParen)) {
2356 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2358 if (ParseOperand(Operands, Name)) {
2359 SMLoc Loc = getLexer().getLoc();
2360 Parser.eatToEndOfStatement();
2361 return Error(Loc, "unexpected token in argument list");
2363 if (Parser.getTok().isNot(AsmToken::RParen)) {
2364 SMLoc Loc = getLexer().getLoc();
2365 Parser.eatToEndOfStatement();
2366 return Error(Loc, "unexpected token, expected ')'");
2369 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2375 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2376 /// either one of these.
2377 /// ::= '[', register, ']'
2378 /// ::= '[', integer, ']'
2379 /// handle it before we iterate so we don't get tripped up by the lack of
2381 bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2382 OperandVector &Operands) {
2383 if (getLexer().is(AsmToken::LBrac)) {
2385 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2387 if (ParseOperand(Operands, Name)) {
2388 SMLoc Loc = getLexer().getLoc();
2389 Parser.eatToEndOfStatement();
2390 return Error(Loc, "unexpected token in argument list");
2392 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2393 SMLoc Loc = getLexer().getLoc();
2394 Parser.eatToEndOfStatement();
2395 return Error(Loc, "unexpected token, expected ']'");
2398 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2404 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2405 SMLoc NameLoc, OperandVector &Operands) {
2406 DEBUG(dbgs() << "ParseInstruction\n");
2408 // We have reached first instruction, module directive are now forbidden.
2409 getTargetStreamer().forbidModuleDirective();
2411 // Check if we have valid mnemonic
2412 if (!mnemonicIsValid(Name, 0)) {
2413 Parser.eatToEndOfStatement();
2414 return Error(NameLoc, "Unknown instruction");
2416 // First operand in MCInst is instruction mnemonic.
2417 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2419 // Read the remaining operands.
2420 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2421 // Read the first operand.
2422 if (ParseOperand(Operands, Name)) {
2423 SMLoc Loc = getLexer().getLoc();
2424 Parser.eatToEndOfStatement();
2425 return Error(Loc, "unexpected token in argument list");
2427 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2429 // AFAIK, parenthesis suffixes are never on the first operand
2431 while (getLexer().is(AsmToken::Comma)) {
2432 Parser.Lex(); // Eat the comma.
2433 // Parse and remember the operand.
2434 if (ParseOperand(Operands, Name)) {
2435 SMLoc Loc = getLexer().getLoc();
2436 Parser.eatToEndOfStatement();
2437 return Error(Loc, "unexpected token in argument list");
2439 // Parse bracket and parenthesis suffixes before we iterate
2440 if (getLexer().is(AsmToken::LBrac)) {
2441 if (ParseBracketSuffix(Name, Operands))
2443 } else if (getLexer().is(AsmToken::LParen) &&
2444 ParseParenSuffix(Name, Operands))
2448 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2449 SMLoc Loc = getLexer().getLoc();
2450 Parser.eatToEndOfStatement();
2451 return Error(Loc, "unexpected token in argument list");
2453 Parser.Lex(); // Consume the EndOfStatement.
2457 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2458 SMLoc Loc = getLexer().getLoc();
2459 Parser.eatToEndOfStatement();
2460 return Error(Loc, ErrorMsg);
2463 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2464 return Error(Loc, ErrorMsg);
2467 bool MipsAsmParser::parseSetNoAtDirective() {
2468 // Line should look like: ".set noat".
2470 Options.setATReg(0);
2473 // If this is not the end of the statement, report an error.
2474 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2475 reportParseError("unexpected token in statement");
2478 Parser.Lex(); // Consume the EndOfStatement.
2482 bool MipsAsmParser::parseSetAtDirective() {
2483 // Line can be .set at - defaults to $1
2487 if (getLexer().is(AsmToken::EndOfStatement)) {
2488 Options.setATReg(1);
2489 Parser.Lex(); // Consume the EndOfStatement.
2491 } else if (getLexer().is(AsmToken::Equal)) {
2492 getParser().Lex(); // Eat the '='.
2493 if (getLexer().isNot(AsmToken::Dollar)) {
2494 reportParseError("unexpected token in statement");
2497 Parser.Lex(); // Eat the '$'.
2498 const AsmToken &Reg = Parser.getTok();
2499 if (Reg.is(AsmToken::Identifier)) {
2500 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2501 } else if (Reg.is(AsmToken::Integer)) {
2502 AtRegNo = Reg.getIntVal();
2504 reportParseError("unexpected token in statement");
2508 if (AtRegNo < 0 || AtRegNo > 31) {
2509 reportParseError("unexpected token in statement");
2513 if (!Options.setATReg(AtRegNo)) {
2514 reportParseError("unexpected token in statement");
2517 getParser().Lex(); // Eat the register.
2519 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2520 reportParseError("unexpected token in statement");
2523 Parser.Lex(); // Consume the EndOfStatement.
2526 reportParseError("unexpected token in statement");
2531 bool MipsAsmParser::parseSetReorderDirective() {
2533 // If this is not the end of the statement, report an error.
2534 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2535 reportParseError("unexpected token in statement");
2538 Options.setReorder();
2539 getTargetStreamer().emitDirectiveSetReorder();
2540 Parser.Lex(); // Consume the EndOfStatement.
2544 bool MipsAsmParser::parseSetNoReorderDirective() {
2546 // If this is not the end of the statement, report an error.
2547 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2548 reportParseError("unexpected token in statement");
2551 Options.setNoreorder();
2552 getTargetStreamer().emitDirectiveSetNoReorder();
2553 Parser.Lex(); // Consume the EndOfStatement.
2557 bool MipsAsmParser::parseSetMacroDirective() {
2559 // If this is not the end of the statement, report an error.
2560 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2561 reportParseError("unexpected token in statement");
2565 Parser.Lex(); // Consume the EndOfStatement.
2569 bool MipsAsmParser::parseSetNoMacroDirective() {
2571 // If this is not the end of the statement, report an error.
2572 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2573 reportParseError("`noreorder' must be set before `nomacro'");
2576 if (Options.isReorder()) {
2577 reportParseError("`noreorder' must be set before `nomacro'");
2580 Options.setNomacro();
2581 Parser.Lex(); // Consume the EndOfStatement.
2585 bool MipsAsmParser::parseSetMsaDirective() {
2588 // If this is not the end of the statement, report an error.
2589 if (getLexer().isNot(AsmToken::EndOfStatement))
2590 return reportParseError("unexpected token in statement");
2592 setFeatureBits(Mips::FeatureMSA, "msa");
2593 getTargetStreamer().emitDirectiveSetMsa();
2597 bool MipsAsmParser::parseSetNoMsaDirective() {
2600 // If this is not the end of the statement, report an error.
2601 if (getLexer().isNot(AsmToken::EndOfStatement))
2602 return reportParseError("unexpected token in statement");
2604 clearFeatureBits(Mips::FeatureMSA, "msa");
2605 getTargetStreamer().emitDirectiveSetNoMsa();
2609 bool MipsAsmParser::parseSetNoMips16Directive() {
2611 // If this is not the end of the statement, report an error.
2612 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2613 reportParseError("unexpected token in statement");
2616 // For now do nothing.
2617 Parser.Lex(); // Consume the EndOfStatement.
2621 bool MipsAsmParser::parseSetFpDirective() {
2622 MipsABIFlagsSection::FpABIKind FpAbiVal;
2623 // Line can be: .set fp=32
2626 Parser.Lex(); // Eat fp token
2627 AsmToken Tok = Parser.getTok();
2628 if (Tok.isNot(AsmToken::Equal)) {
2629 reportParseError("unexpected token in statement");
2632 Parser.Lex(); // Eat '=' token.
2633 Tok = Parser.getTok();
2635 if (!parseFpABIValue(FpAbiVal, ".set"))
2638 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2639 reportParseError("unexpected token in statement");
2642 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2643 Parser.Lex(); // Consume the EndOfStatement.
2647 bool MipsAsmParser::parseSetAssignment() {
2649 const MCExpr *Value;
2651 if (Parser.parseIdentifier(Name))
2652 reportParseError("expected identifier after .set");
2654 if (getLexer().isNot(AsmToken::Comma))
2655 return reportParseError("unexpected token in .set directive");
2658 if (Parser.parseExpression(Value))
2659 return reportParseError("expected valid expression after comma");
2661 // Check if the Name already exists as a symbol.
2662 MCSymbol *Sym = getContext().LookupSymbol(Name);
2664 return reportParseError("symbol already defined");
2665 Sym = getContext().GetOrCreateSymbol(Name);
2666 Sym->setVariableValue(Value);
2671 bool MipsAsmParser::parseSetArchDirective() {
2673 if (getLexer().isNot(AsmToken::Equal))
2674 return reportParseError("unexpected token, expected equals sign");
2678 if (Parser.parseIdentifier(Arch))
2679 return reportParseError("expected arch identifier");
2681 StringRef ArchFeatureName =
2682 StringSwitch<StringRef>(Arch)
2683 .Case("mips1", "mips1")
2684 .Case("mips2", "mips2")
2685 .Case("mips3", "mips3")
2686 .Case("mips4", "mips4")
2687 .Case("mips5", "mips5")
2688 .Case("mips32", "mips32")
2689 .Case("mips32r2", "mips32r2")
2690 .Case("mips32r6", "mips32r6")
2691 .Case("mips64", "mips64")
2692 .Case("mips64r2", "mips64r2")
2693 .Case("mips64r6", "mips64r6")
2694 .Case("cnmips", "cnmips")
2695 .Case("r4000", "mips3") // This is an implementation of Mips3.
2698 if (ArchFeatureName.empty())
2699 return reportParseError("unsupported architecture");
2701 selectArch(ArchFeatureName);
2702 getTargetStreamer().emitDirectiveSetArch(Arch);
2706 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2708 if (getLexer().isNot(AsmToken::EndOfStatement))
2709 return reportParseError("unexpected token in .set directive");
2713 llvm_unreachable("Unimplemented feature");
2714 case Mips::FeatureDSP:
2715 setFeatureBits(Mips::FeatureDSP, "dsp");
2716 getTargetStreamer().emitDirectiveSetDsp();
2718 case Mips::FeatureMicroMips:
2719 getTargetStreamer().emitDirectiveSetMicroMips();
2721 case Mips::FeatureMips16:
2722 getTargetStreamer().emitDirectiveSetMips16();
2724 case Mips::FeatureMips1:
2725 selectArch("mips1");
2726 getTargetStreamer().emitDirectiveSetMips1();
2728 case Mips::FeatureMips2:
2729 selectArch("mips2");
2730 getTargetStreamer().emitDirectiveSetMips2();
2732 case Mips::FeatureMips3:
2733 selectArch("mips3");
2734 getTargetStreamer().emitDirectiveSetMips3();
2736 case Mips::FeatureMips4:
2737 selectArch("mips4");
2738 getTargetStreamer().emitDirectiveSetMips4();
2740 case Mips::FeatureMips5:
2741 selectArch("mips5");
2742 getTargetStreamer().emitDirectiveSetMips5();
2744 case Mips::FeatureMips32:
2745 selectArch("mips32");
2746 getTargetStreamer().emitDirectiveSetMips32();
2748 case Mips::FeatureMips32r2:
2749 selectArch("mips32r2");
2750 getTargetStreamer().emitDirectiveSetMips32R2();
2752 case Mips::FeatureMips32r6:
2753 selectArch("mips32r6");
2754 getTargetStreamer().emitDirectiveSetMips32R6();
2756 case Mips::FeatureMips64:
2757 selectArch("mips64");
2758 getTargetStreamer().emitDirectiveSetMips64();
2760 case Mips::FeatureMips64r2:
2761 selectArch("mips64r2");
2762 getTargetStreamer().emitDirectiveSetMips64R2();
2764 case Mips::FeatureMips64r6:
2765 selectArch("mips64r6");
2766 getTargetStreamer().emitDirectiveSetMips64R6();
2772 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2773 if (getLexer().isNot(AsmToken::Comma)) {
2774 SMLoc Loc = getLexer().getLoc();
2775 Parser.eatToEndOfStatement();
2776 return Error(Loc, ErrorStr);
2779 Parser.Lex(); // Eat the comma.
2783 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2784 if (Options.isReorder())
2785 Warning(Loc, ".cpload in reorder section");
2787 // FIXME: Warn if cpload is used in Mips16 mode.
2789 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2790 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2791 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2792 reportParseError("expected register containing function address");
2796 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2797 if (!RegOpnd.isGPRAsmReg()) {
2798 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2802 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2806 bool MipsAsmParser::parseDirectiveCPSetup() {
2809 bool SaveIsReg = true;
2811 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2812 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2813 if (ResTy == MatchOperand_NoMatch) {
2814 reportParseError("expected register containing function address");
2815 Parser.eatToEndOfStatement();
2819 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2820 if (!FuncRegOpnd.isGPRAsmReg()) {
2821 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2822 Parser.eatToEndOfStatement();
2826 FuncReg = FuncRegOpnd.getGPR32Reg();
2829 if (!eatComma("expected comma parsing directive"))
2832 ResTy = ParseAnyRegister(TmpReg);
2833 if (ResTy == MatchOperand_NoMatch) {
2834 const AsmToken &Tok = Parser.getTok();
2835 if (Tok.is(AsmToken::Integer)) {
2836 Save = Tok.getIntVal();
2840 reportParseError("expected save register or stack offset");
2841 Parser.eatToEndOfStatement();
2845 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2846 if (!SaveOpnd.isGPRAsmReg()) {
2847 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2848 Parser.eatToEndOfStatement();
2851 Save = SaveOpnd.getGPR32Reg();
2854 if (!eatComma("expected comma parsing directive"))
2858 if (Parser.parseIdentifier(Name))
2859 reportParseError("expected identifier");
2860 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2862 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2866 bool MipsAsmParser::parseDirectiveNaN() {
2867 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2868 const AsmToken &Tok = Parser.getTok();
2870 if (Tok.getString() == "2008") {
2872 getTargetStreamer().emitDirectiveNaN2008();
2874 } else if (Tok.getString() == "legacy") {
2876 getTargetStreamer().emitDirectiveNaNLegacy();
2880 // If we don't recognize the option passed to the .nan
2881 // directive (e.g. no option or unknown option), emit an error.
2882 reportParseError("invalid option in .nan directive");
2886 bool MipsAsmParser::parseDirectiveSet() {
2888 // Get the next token.
2889 const AsmToken &Tok = Parser.getTok();
2891 if (Tok.getString() == "noat") {
2892 return parseSetNoAtDirective();
2893 } else if (Tok.getString() == "at") {
2894 return parseSetAtDirective();
2895 } else if (Tok.getString() == "arch") {
2896 return parseSetArchDirective();
2897 } else if (Tok.getString() == "fp") {
2898 return parseSetFpDirective();
2899 } else if (Tok.getString() == "reorder") {
2900 return parseSetReorderDirective();
2901 } else if (Tok.getString() == "noreorder") {
2902 return parseSetNoReorderDirective();
2903 } else if (Tok.getString() == "macro") {
2904 return parseSetMacroDirective();
2905 } else if (Tok.getString() == "nomacro") {
2906 return parseSetNoMacroDirective();
2907 } else if (Tok.getString() == "mips16") {
2908 return parseSetFeature(Mips::FeatureMips16);
2909 } else if (Tok.getString() == "nomips16") {
2910 return parseSetNoMips16Directive();
2911 } else if (Tok.getString() == "nomicromips") {
2912 getTargetStreamer().emitDirectiveSetNoMicroMips();
2913 Parser.eatToEndOfStatement();
2915 } else if (Tok.getString() == "micromips") {
2916 return parseSetFeature(Mips::FeatureMicroMips);
2917 } else if (Tok.getString() == "mips1") {
2918 return parseSetFeature(Mips::FeatureMips1);
2919 } else if (Tok.getString() == "mips2") {
2920 return parseSetFeature(Mips::FeatureMips2);
2921 } else if (Tok.getString() == "mips3") {
2922 return parseSetFeature(Mips::FeatureMips3);
2923 } else if (Tok.getString() == "mips4") {
2924 return parseSetFeature(Mips::FeatureMips4);
2925 } else if (Tok.getString() == "mips5") {
2926 return parseSetFeature(Mips::FeatureMips5);
2927 } else if (Tok.getString() == "mips32") {
2928 return parseSetFeature(Mips::FeatureMips32);
2929 } else if (Tok.getString() == "mips32r2") {
2930 return parseSetFeature(Mips::FeatureMips32r2);
2931 } else if (Tok.getString() == "mips32r6") {
2932 return parseSetFeature(Mips::FeatureMips32r6);
2933 } else if (Tok.getString() == "mips64") {
2934 return parseSetFeature(Mips::FeatureMips64);
2935 } else if (Tok.getString() == "mips64r2") {
2936 return parseSetFeature(Mips::FeatureMips64r2);
2937 } else if (Tok.getString() == "mips64r6") {
2938 return parseSetFeature(Mips::FeatureMips64r6);
2939 } else if (Tok.getString() == "dsp") {
2940 return parseSetFeature(Mips::FeatureDSP);
2941 } else if (Tok.getString() == "msa") {
2942 return parseSetMsaDirective();
2943 } else if (Tok.getString() == "nomsa") {
2944 return parseSetNoMsaDirective();
2946 // It is just an identifier, look for an assignment.
2947 parseSetAssignment();
2954 /// parseDataDirective
2955 /// ::= .word [ expression (, expression)* ]
2956 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2957 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2959 const MCExpr *Value;
2960 if (getParser().parseExpression(Value))
2963 getParser().getStreamer().EmitValue(Value, Size);
2965 if (getLexer().is(AsmToken::EndOfStatement))
2968 // FIXME: Improve diagnostic.
2969 if (getLexer().isNot(AsmToken::Comma))
2970 return Error(L, "unexpected token in directive");
2979 /// parseDirectiveGpWord
2980 /// ::= .gpword local_sym
2981 bool MipsAsmParser::parseDirectiveGpWord() {
2982 const MCExpr *Value;
2983 // EmitGPRel32Value requires an expression, so we are using base class
2984 // method to evaluate the expression.
2985 if (getParser().parseExpression(Value))
2987 getParser().getStreamer().EmitGPRel32Value(Value);
2989 if (getLexer().isNot(AsmToken::EndOfStatement))
2990 return Error(getLexer().getLoc(), "unexpected token in directive");
2991 Parser.Lex(); // Eat EndOfStatement token.
2995 /// parseDirectiveGpDWord
2996 /// ::= .gpdword local_sym
2997 bool MipsAsmParser::parseDirectiveGpDWord() {
2998 const MCExpr *Value;
2999 // EmitGPRel64Value requires an expression, so we are using base class
3000 // method to evaluate the expression.
3001 if (getParser().parseExpression(Value))
3003 getParser().getStreamer().EmitGPRel64Value(Value);
3005 if (getLexer().isNot(AsmToken::EndOfStatement))
3006 return Error(getLexer().getLoc(), "unexpected token in directive");
3007 Parser.Lex(); // Eat EndOfStatement token.
3011 bool MipsAsmParser::parseDirectiveOption() {
3012 // Get the option token.
3013 AsmToken Tok = Parser.getTok();
3014 // At the moment only identifiers are supported.
3015 if (Tok.isNot(AsmToken::Identifier)) {
3016 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
3017 Parser.eatToEndOfStatement();
3021 StringRef Option = Tok.getIdentifier();
3023 if (Option == "pic0") {
3024 getTargetStreamer().emitDirectiveOptionPic0();
3026 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3027 Error(Parser.getTok().getLoc(),
3028 "unexpected token in .option pic0 directive");
3029 Parser.eatToEndOfStatement();
3034 if (Option == "pic2") {
3035 getTargetStreamer().emitDirectiveOptionPic2();
3037 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3038 Error(Parser.getTok().getLoc(),
3039 "unexpected token in .option pic2 directive");
3040 Parser.eatToEndOfStatement();
3046 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
3047 Parser.eatToEndOfStatement();
3051 /// parseDirectiveModule
3052 /// ::= .module oddspreg
3053 /// ::= .module nooddspreg
3054 /// ::= .module fp=value
3055 bool MipsAsmParser::parseDirectiveModule() {
3056 MCAsmLexer &Lexer = getLexer();
3057 SMLoc L = Lexer.getLoc();
3059 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3060 // TODO : get a better message.
3061 reportParseError(".module directive must appear before any code");
3065 if (Lexer.is(AsmToken::Identifier)) {
3066 StringRef Option = Parser.getTok().getString();
3069 if (Option == "oddspreg") {
3070 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3071 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3074 reportParseError("Expected end of statement");
3079 } else if (Option == "nooddspreg") {
3081 Error(L, "'.module nooddspreg' requires the O32 ABI");
3085 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3086 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3088 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3089 reportParseError("Expected end of statement");
3094 } else if (Option == "fp") {
3095 return parseDirectiveModuleFP();
3098 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3104 /// parseDirectiveModuleFP
3108 bool MipsAsmParser::parseDirectiveModuleFP() {
3109 MCAsmLexer &Lexer = getLexer();
3111 if (Lexer.isNot(AsmToken::Equal)) {
3112 reportParseError("unexpected token in statement");
3115 Parser.Lex(); // Eat '=' token.
3117 MipsABIFlagsSection::FpABIKind FpABI;
3118 if (!parseFpABIValue(FpABI, ".module"))
3121 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3122 reportParseError("unexpected token in statement");
3126 // Emit appropriate flags.
3127 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3128 Parser.Lex(); // Consume the EndOfStatement.
3132 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3133 StringRef Directive) {
3134 MCAsmLexer &Lexer = getLexer();
3136 if (Lexer.is(AsmToken::Identifier)) {
3137 StringRef Value = Parser.getTok().getString();
3140 if (Value != "xx") {
3141 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3146 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3150 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3154 if (Lexer.is(AsmToken::Integer)) {
3155 unsigned Value = Parser.getTok().getIntVal();
3158 if (Value != 32 && Value != 64) {
3159 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3165 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3169 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3171 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3179 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3180 StringRef IDVal = DirectiveID.getString();
3182 if (IDVal == ".cpload")
3183 return parseDirectiveCPLoad(DirectiveID.getLoc());
3184 if (IDVal == ".dword") {
3185 parseDataDirective(8, DirectiveID.getLoc());
3188 if (IDVal == ".ent") {
3189 StringRef SymbolName;
3191 if (Parser.parseIdentifier(SymbolName)) {
3192 reportParseError("expected identifier after .ent");
3196 // There's an undocumented extension that allows an integer to
3197 // follow the name of the procedure which AFAICS is ignored by GAS.
3198 // Example: .ent foo,2
3199 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3200 if (getLexer().isNot(AsmToken::Comma)) {
3201 // Even though we accept this undocumented extension for compatibility
3202 // reasons, the additional integer argument does not actually change
3203 // the behaviour of the '.ent' directive, so we would like to discourage
3204 // its use. We do this by not referring to the extended version in
3205 // error messages which are not directly related to its use.
3206 reportParseError("unexpected token, expected end of statement");
3209 Parser.Lex(); // Eat the comma.
3210 const MCExpr *DummyNumber;
3211 int64_t DummyNumberVal;
3212 // If the user was explicitly trying to use the extended version,
3213 // we still give helpful extension-related error messages.
3214 if (Parser.parseExpression(DummyNumber)) {
3215 reportParseError("expected number after comma");
3218 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3219 reportParseError("expected an absolute expression after comma");
3224 // If this is not the end of the statement, report an error.
3225 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3226 reportParseError("unexpected token, expected end of statement");
3230 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3232 getTargetStreamer().emitDirectiveEnt(*Sym);
3237 if (IDVal == ".end") {
3238 StringRef SymbolName;
3240 if (Parser.parseIdentifier(SymbolName)) {
3241 reportParseError("expected identifier after .end");
3245 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3246 reportParseError("unexpected token, expected end of statement");
3250 if (CurrentFn == nullptr) {
3251 reportParseError(".end used without .ent");
3255 if ((SymbolName != CurrentFn->getName())) {
3256 reportParseError(".end symbol does not match .ent symbol");
3260 getTargetStreamer().emitDirectiveEnd(SymbolName);
3261 CurrentFn = nullptr;
3265 if (IDVal == ".frame") {
3266 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3267 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3268 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
3269 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3270 reportParseError("expected stack register");
3274 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3275 if (!StackRegOpnd.isGPRAsmReg()) {
3276 reportParseError(StackRegOpnd.getStartLoc(),
3277 "expected general purpose register");
3280 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3282 if (Parser.getTok().is(AsmToken::Comma))
3285 reportParseError("unexpected token, expected comma");
3289 // Parse the frame size.
3290 const MCExpr *FrameSize;
3291 int64_t FrameSizeVal;
3293 if (Parser.parseExpression(FrameSize)) {
3294 reportParseError("expected frame size value");
3298 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3299 reportParseError("frame size not an absolute expression");
3303 if (Parser.getTok().is(AsmToken::Comma))
3306 reportParseError("unexpected token, expected comma");
3310 // Parse the return register.
3312 ResTy = ParseAnyRegister(TmpReg);
3313 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3314 reportParseError("expected return register");
3318 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3319 if (!ReturnRegOpnd.isGPRAsmReg()) {
3320 reportParseError(ReturnRegOpnd.getStartLoc(),
3321 "expected general purpose register");
3325 // If this is not the end of the statement, report an error.
3326 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3327 reportParseError("unexpected token, expected end of statement");
3331 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3332 ReturnRegOpnd.getGPR32Reg());
3336 if (IDVal == ".set") {
3337 return parseDirectiveSet();
3340 if (IDVal == ".mask" || IDVal == ".fmask") {
3341 // .mask bitmask, frame_offset
3342 // bitmask: One bit for each register used.
3343 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3344 // first register is expected to be saved.
3346 // .mask 0x80000000, -4
3347 // .fmask 0x80000000, -4
3350 // Parse the bitmask
3351 const MCExpr *BitMask;
3354 if (Parser.parseExpression(BitMask)) {
3355 reportParseError("expected bitmask value");
3359 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3360 reportParseError("bitmask not an absolute expression");
3364 if (Parser.getTok().is(AsmToken::Comma))
3367 reportParseError("unexpected token, expected comma");
3371 // Parse the frame_offset
3372 const MCExpr *FrameOffset;
3373 int64_t FrameOffsetVal;
3375 if (Parser.parseExpression(FrameOffset)) {
3376 reportParseError("expected frame offset value");
3380 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3381 reportParseError("frame offset not an absolute expression");
3385 // If this is not the end of the statement, report an error.
3386 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3387 reportParseError("unexpected token, expected end of statement");
3391 if (IDVal == ".mask")
3392 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3394 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3398 if (IDVal == ".nan")
3399 return parseDirectiveNaN();
3401 if (IDVal == ".gpword") {
3402 parseDirectiveGpWord();
3406 if (IDVal == ".gpdword") {
3407 parseDirectiveGpDWord();
3411 if (IDVal == ".word") {
3412 parseDataDirective(4, DirectiveID.getLoc());
3416 if (IDVal == ".option")
3417 return parseDirectiveOption();
3419 if (IDVal == ".abicalls") {
3420 getTargetStreamer().emitDirectiveAbiCalls();
3421 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3422 Error(Parser.getTok().getLoc(), "unexpected token in directive");
3424 Parser.eatToEndOfStatement();
3429 if (IDVal == ".cpsetup")
3430 return parseDirectiveCPSetup();
3432 if (IDVal == ".module")
3433 return parseDirectiveModule();
3438 extern "C" void LLVMInitializeMipsAsmParser() {
3439 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3440 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3441 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3442 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3445 #define GET_REGISTER_MATCHER
3446 #define GET_MATCHER_IMPLEMENTATION
3447 #include "MipsGenAsmMatcher.inc"