1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
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/SmallVector.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/TargetRegistry.h"
31 #include <memory>
32
33 using namespace llvm;
34
35 #define DEBUG_TYPE "mips-asm-parser"
36
37 namespace llvm {
38 class MCInstrInfo;
39 }
40
41 namespace {
42 class MipsAssemblerOptions {
43 public:
MipsAssemblerOptions(uint64_t Features_)44 MipsAssemblerOptions(uint64_t Features_) :
45 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
46
MipsAssemblerOptions(const MipsAssemblerOptions * Opts)47 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
48 ATReg = Opts->getATRegNum();
49 Reorder = Opts->isReorder();
50 Macro = Opts->isMacro();
51 Features = Opts->getFeatures();
52 }
53
getATRegNum() const54 unsigned getATRegNum() const { return ATReg; }
55 bool setATReg(unsigned Reg);
56
isReorder() const57 bool isReorder() const { return Reorder; }
setReorder()58 void setReorder() { Reorder = true; }
setNoReorder()59 void setNoReorder() { Reorder = false; }
60
isMacro() const61 bool isMacro() const { return Macro; }
setMacro()62 void setMacro() { Macro = true; }
setNoMacro()63 void setNoMacro() { Macro = false; }
64
getFeatures() const65 uint64_t getFeatures() const { return Features; }
setFeatures(uint64_t Features_)66 void setFeatures(uint64_t Features_) { Features = Features_; }
67
68 // Set of features that are either architecture features or referenced
69 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
70 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
71 // The reason we need this mask is explained in the selectArch function.
72 // FIXME: Ideally we would like TableGen to generate this information.
73 static const uint64_t AllArchRelatedMask =
74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
79 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
80 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
81
82 private:
83 unsigned ATReg;
84 bool Reorder;
85 bool Macro;
86 uint64_t Features;
87 };
88 }
89
90 namespace {
91 class MipsAsmParser : public MCTargetAsmParser {
getTargetStreamer()92 MipsTargetStreamer &getTargetStreamer() {
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
95 }
96
97 MCSubtargetInfo &STI;
98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
100 // nullptr, which indicates that no function is currently
101 // selected. This usually happens after an '.end func'
102 // directive.
103
104 // Print a warning along with its fix-it message at the given range.
105 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
106 SMRange Range, bool ShowColors = true);
107
108 #define GET_ASSEMBLER_HEADER
109 #include "MipsGenAsmMatcher.inc"
110
111 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
112
113 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
114 OperandVector &Operands, MCStreamer &Out,
115 uint64_t &ErrorInfo,
116 bool MatchingInlineAsm) override;
117
118 /// Parse a register as used in CFI directives
119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
120
121 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
122
123 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
124
125 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
126 SMLoc NameLoc, OperandVector &Operands) override;
127
128 bool ParseDirective(AsmToken DirectiveID) override;
129
130 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
131
132 MipsAsmParser::OperandMatchResultTy
133 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
134 StringRef Identifier, SMLoc S);
135
136 MipsAsmParser::OperandMatchResultTy
137 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
138
139 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
140
141 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
142
143 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
144
145 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
146
147 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
148
149 MipsAsmParser::OperandMatchResultTy
150 parseRegisterPair (OperandVector &Operands);
151
152 MipsAsmParser::OperandMatchResultTy
153 parseRegisterList (OperandVector &Operands);
154
155 bool searchSymbolAlias(OperandVector &Operands);
156
157 bool parseOperand(OperandVector &, StringRef Mnemonic);
158
159 bool needsExpansion(MCInst &Inst);
160
161 // Expands assembly pseudo instructions.
162 // Returns false on success, true otherwise.
163 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
164 SmallVectorImpl<MCInst> &Instructions);
165
166 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
168
169 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
171
172 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
174
175 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
176 SmallVectorImpl<MCInst> &Instructions);
177
178 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
179 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
180 bool isImmOpnd);
181 bool reportParseError(Twine ErrorMsg);
182 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
183
184 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
185 bool parseRelocOperand(const MCExpr *&Res);
186
187 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
188
189 bool isEvaluated(const MCExpr *Expr);
190 bool parseSetMips0Directive();
191 bool parseSetArchDirective();
192 bool parseSetFeature(uint64_t Feature);
193 bool parseDirectiveCpLoad(SMLoc Loc);
194 bool parseDirectiveCPSetup();
195 bool parseDirectiveNaN();
196 bool parseDirectiveSet();
197 bool parseDirectiveOption();
198
199 bool parseSetAtDirective();
200 bool parseSetNoAtDirective();
201 bool parseSetMacroDirective();
202 bool parseSetNoMacroDirective();
203 bool parseSetMsaDirective();
204 bool parseSetNoMsaDirective();
205 bool parseSetNoDspDirective();
206 bool parseSetReorderDirective();
207 bool parseSetNoReorderDirective();
208 bool parseSetMips16Directive();
209 bool parseSetNoMips16Directive();
210 bool parseSetFpDirective();
211 bool parseSetPopDirective();
212 bool parseSetPushDirective();
213
214 bool parseSetAssignment();
215
216 bool parseDataDirective(unsigned Size, SMLoc L);
217 bool parseDirectiveGpWord();
218 bool parseDirectiveGpDWord();
219 bool parseDirectiveModule();
220 bool parseDirectiveModuleFP();
221 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
222 StringRef Directive);
223
224 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
225
226 bool eatComma(StringRef ErrorStr);
227
228 int matchCPURegisterName(StringRef Symbol);
229
230 int matchHWRegsRegisterName(StringRef Symbol);
231
232 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
233
234 int matchFPURegisterName(StringRef Name);
235
236 int matchFCCRegisterName(StringRef Name);
237
238 int matchACRegisterName(StringRef Name);
239
240 int matchMSA128RegisterName(StringRef Name);
241
242 int matchMSA128CtrlRegisterName(StringRef Name);
243
244 unsigned getReg(int RC, int RegNo);
245
246 unsigned getGPR(int RegNo);
247
248 int getATReg(SMLoc Loc);
249
250 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
251 SmallVectorImpl<MCInst> &Instructions);
252
253 // Helper function that checks if the value of a vector index is within the
254 // boundaries of accepted values for each RegisterKind
255 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
256 bool validateMSAIndex(int Val, int RegKind);
257
258 // Selects a new architecture by updating the FeatureBits with the necessary
259 // info including implied dependencies.
260 // Internally, it clears all the feature bits related to *any* architecture
261 // and selects the new one using the ToggleFeature functionality of the
262 // MCSubtargetInfo object that handles implied dependencies. The reason we
263 // clear all the arch related bits manually is because ToggleFeature only
264 // clears the features that imply the feature being cleared and not the
265 // features implied by the feature being cleared. This is easier to see
266 // with an example:
267 // --------------------------------------------------
268 // | Feature | Implies |
269 // | -------------------------------------------------|
270 // | FeatureMips1 | None |
271 // | FeatureMips2 | FeatureMips1 |
272 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
273 // | FeatureMips4 | FeatureMips3 |
274 // | ... | |
275 // --------------------------------------------------
276 //
277 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
278 // FeatureMipsGP64 | FeatureMips1)
279 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
selectArch(StringRef ArchFeature)280 void selectArch(StringRef ArchFeature) {
281 uint64_t FeatureBits = STI.getFeatureBits();
282 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
283 STI.setFeatureBits(FeatureBits);
284 setAvailableFeatures(
285 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
286 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
287 }
288
setFeatureBits(uint64_t Feature,StringRef FeatureString)289 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
290 if (!(STI.getFeatureBits() & Feature)) {
291 setAvailableFeatures(
292 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
293 }
294 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
295 }
296
clearFeatureBits(uint64_t Feature,StringRef FeatureString)297 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
298 if (STI.getFeatureBits() & Feature) {
299 setAvailableFeatures(
300 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
301 }
302 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
303 }
304
305 public:
306 enum MipsMatchResultTy {
307 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
308 #define GET_OPERAND_DIAGNOSTIC_TYPES
309 #include "MipsGenAsmMatcher.inc"
310 #undef GET_OPERAND_DIAGNOSTIC_TYPES
311
312 };
313
MipsAsmParser(MCSubtargetInfo & sti,MCAsmParser & parser,const MCInstrInfo & MII,const MCTargetOptions & Options)314 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
315 const MCInstrInfo &MII, const MCTargetOptions &Options)
316 : MCTargetAsmParser(), STI(sti) {
317 MCAsmParserExtension::Initialize(parser);
318
319 // Initialize the set of available features.
320 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
321
322 // Remember the initial assembler options. The user can not modify these.
323 AssemblerOptions.push_back(
324 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
325
326 // Create an assembler options environment for the user to modify.
327 AssemblerOptions.push_back(
328 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
329
330 getTargetStreamer().updateABIInfo(*this);
331
332 // Assert exactly one ABI was chosen.
333 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
334 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
335 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
336 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
337
338 if (!isABI_O32() && !useOddSPReg() != 0)
339 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
340
341 CurrentFn = nullptr;
342 }
343
344 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
hasEightFccRegisters() const345 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
346
isGP64bit() const347 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
isFP64bit() const348 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
isABI_N32() const349 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
isABI_N64() const350 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
isABI_O32() const351 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
isABI_FPXX() const352 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
353
useOddSPReg() const354 bool useOddSPReg() const {
355 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
356 }
357
inMicroMipsMode() const358 bool inMicroMipsMode() const {
359 return STI.getFeatureBits() & Mips::FeatureMicroMips;
360 }
hasMips1() const361 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
hasMips2() const362 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
hasMips3() const363 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
hasMips4() const364 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
hasMips5() const365 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
hasMips32() const366 bool hasMips32() const {
367 return (STI.getFeatureBits() & Mips::FeatureMips32);
368 }
hasMips64() const369 bool hasMips64() const {
370 return (STI.getFeatureBits() & Mips::FeatureMips64);
371 }
hasMips32r2() const372 bool hasMips32r2() const {
373 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
374 }
hasMips64r2() const375 bool hasMips64r2() const {
376 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
377 }
hasMips32r6() const378 bool hasMips32r6() const {
379 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
380 }
hasMips64r6() const381 bool hasMips64r6() const {
382 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
383 }
hasDSP() const384 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
hasDSPR2() const385 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
hasMSA() const386 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
387
inMips16Mode() const388 bool inMips16Mode() const {
389 return STI.getFeatureBits() & Mips::FeatureMips16;
390 }
391 // TODO: see how can we get this info.
abiUsesSoftFloat() const392 bool abiUsesSoftFloat() const { return false; }
393
394 /// Warn if RegNo is the current assembler temporary.
395 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
396 };
397 }
398
399 namespace {
400
401 /// MipsOperand - Instances of this class represent a parsed Mips machine
402 /// instruction.
403 class MipsOperand : public MCParsedAsmOperand {
404 public:
405 /// Broad categories of register classes
406 /// The exact class is finalized by the render method.
407 enum RegKind {
408 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
409 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
410 /// isFP64bit())
411 RegKind_FCC = 4, /// FCC
412 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
413 RegKind_MSACtrl = 16, /// MSA control registers
414 RegKind_COP2 = 32, /// COP2
415 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
416 /// context).
417 RegKind_CCR = 128, /// CCR
418 RegKind_HWRegs = 256, /// HWRegs
419 RegKind_COP3 = 512, /// COP3
420
421 /// Potentially any (e.g. $1)
422 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
423 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
424 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
425 };
426
427 private:
428 enum KindTy {
429 k_Immediate, /// An immediate (possibly involving symbol references)
430 k_Memory, /// Base + Offset Memory Address
431 k_PhysRegister, /// A physical register from the Mips namespace
432 k_RegisterIndex, /// A register index in one or more RegKind.
433 k_Token, /// A simple token
434 k_RegList, /// A physical register list
435 k_RegPair /// A pair of physical register
436 } Kind;
437
438 public:
MipsOperand(KindTy K,MipsAsmParser & Parser)439 MipsOperand(KindTy K, MipsAsmParser &Parser)
440 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
441
442 private:
443 /// For diagnostics, and checking the assembler temporary
444 MipsAsmParser &AsmParser;
445
446 struct Token {
447 const char *Data;
448 unsigned Length;
449 };
450
451 struct PhysRegOp {
452 unsigned Num; /// Register Number
453 };
454
455 struct RegIdxOp {
456 unsigned Index; /// Index into the register class
457 RegKind Kind; /// Bitfield of the kinds it could possibly be
458 const MCRegisterInfo *RegInfo;
459 };
460
461 struct ImmOp {
462 const MCExpr *Val;
463 };
464
465 struct MemOp {
466 MipsOperand *Base;
467 const MCExpr *Off;
468 };
469
470 struct RegListOp {
471 SmallVector<unsigned, 10> *List;
472 };
473
474 union {
475 struct Token Tok;
476 struct PhysRegOp PhysReg;
477 struct RegIdxOp RegIdx;
478 struct ImmOp Imm;
479 struct MemOp Mem;
480 struct RegListOp RegList;
481 };
482
483 SMLoc StartLoc, EndLoc;
484
485 /// Internal constructor for register kinds
CreateReg(unsigned Index,RegKind RegKind,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)486 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
487 const MCRegisterInfo *RegInfo,
488 SMLoc S, SMLoc E,
489 MipsAsmParser &Parser) {
490 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
491 Op->RegIdx.Index = Index;
492 Op->RegIdx.RegInfo = RegInfo;
493 Op->RegIdx.Kind = RegKind;
494 Op->StartLoc = S;
495 Op->EndLoc = E;
496 return Op;
497 }
498
499 public:
500 /// Coerce the register to GPR32 and return the real register for the current
501 /// target.
getGPR32Reg() const502 unsigned getGPR32Reg() const {
503 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
504 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
505 unsigned ClassID = Mips::GPR32RegClassID;
506 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
507 }
508
509 /// Coerce the register to GPR32 and return the real register for the current
510 /// target.
getGPRMM16Reg() const511 unsigned getGPRMM16Reg() const {
512 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
513 unsigned ClassID = Mips::GPR32RegClassID;
514 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
515 }
516
517 /// Coerce the register to GPR64 and return the real register for the current
518 /// target.
getGPR64Reg() const519 unsigned getGPR64Reg() const {
520 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
521 unsigned ClassID = Mips::GPR64RegClassID;
522 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
523 }
524
525 private:
526 /// Coerce the register to AFGR64 and return the real register for the current
527 /// target.
getAFGR64Reg() const528 unsigned getAFGR64Reg() const {
529 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
530 if (RegIdx.Index % 2 != 0)
531 AsmParser.Warning(StartLoc, "Float register should be even.");
532 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
533 .getRegister(RegIdx.Index / 2);
534 }
535
536 /// Coerce the register to FGR64 and return the real register for the current
537 /// target.
getFGR64Reg() const538 unsigned getFGR64Reg() const {
539 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
540 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
541 .getRegister(RegIdx.Index);
542 }
543
544 /// Coerce the register to FGR32 and return the real register for the current
545 /// target.
getFGR32Reg() const546 unsigned getFGR32Reg() const {
547 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
548 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
549 .getRegister(RegIdx.Index);
550 }
551
552 /// Coerce the register to FGRH32 and return the real register for the current
553 /// target.
getFGRH32Reg() const554 unsigned getFGRH32Reg() const {
555 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
556 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
557 .getRegister(RegIdx.Index);
558 }
559
560 /// Coerce the register to FCC and return the real register for the current
561 /// target.
getFCCReg() const562 unsigned getFCCReg() const {
563 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
564 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
565 .getRegister(RegIdx.Index);
566 }
567
568 /// Coerce the register to MSA128 and return the real register for the current
569 /// target.
getMSA128Reg() const570 unsigned getMSA128Reg() const {
571 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
572 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
573 // identical
574 unsigned ClassID = Mips::MSA128BRegClassID;
575 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
576 }
577
578 /// Coerce the register to MSACtrl and return the real register for the
579 /// current target.
getMSACtrlReg() const580 unsigned getMSACtrlReg() const {
581 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
582 unsigned ClassID = Mips::MSACtrlRegClassID;
583 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
584 }
585
586 /// Coerce the register to COP2 and return the real register for the
587 /// current target.
getCOP2Reg() const588 unsigned getCOP2Reg() const {
589 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
590 unsigned ClassID = Mips::COP2RegClassID;
591 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
592 }
593
594 /// Coerce the register to COP3 and return the real register for the
595 /// current target.
getCOP3Reg() const596 unsigned getCOP3Reg() const {
597 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
598 unsigned ClassID = Mips::COP3RegClassID;
599 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
600 }
601
602 /// Coerce the register to ACC64DSP and return the real register for the
603 /// current target.
getACC64DSPReg() const604 unsigned getACC64DSPReg() const {
605 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
606 unsigned ClassID = Mips::ACC64DSPRegClassID;
607 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
608 }
609
610 /// Coerce the register to HI32DSP and return the real register for the
611 /// current target.
getHI32DSPReg() const612 unsigned getHI32DSPReg() const {
613 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
614 unsigned ClassID = Mips::HI32DSPRegClassID;
615 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
616 }
617
618 /// Coerce the register to LO32DSP and return the real register for the
619 /// current target.
getLO32DSPReg() const620 unsigned getLO32DSPReg() const {
621 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
622 unsigned ClassID = Mips::LO32DSPRegClassID;
623 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
624 }
625
626 /// Coerce the register to CCR and return the real register for the
627 /// current target.
getCCRReg() const628 unsigned getCCRReg() const {
629 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
630 unsigned ClassID = Mips::CCRRegClassID;
631 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
632 }
633
634 /// Coerce the register to HWRegs and return the real register for the
635 /// current target.
getHWRegsReg() const636 unsigned getHWRegsReg() const {
637 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
638 unsigned ClassID = Mips::HWRegsRegClassID;
639 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
640 }
641
642 public:
addExpr(MCInst & Inst,const MCExpr * Expr) const643 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
644 // Add as immediate when possible. Null MCExpr = 0.
645 if (!Expr)
646 Inst.addOperand(MCOperand::CreateImm(0));
647 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
648 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
649 else
650 Inst.addOperand(MCOperand::CreateExpr(Expr));
651 }
652
addRegOperands(MCInst & Inst,unsigned N) const653 void addRegOperands(MCInst &Inst, unsigned N) const {
654 llvm_unreachable("Use a custom parser instead");
655 }
656
657 /// Render the operand to an MCInst as a GPR32
658 /// Asserts if the wrong number of operands are requested, or the operand
659 /// is not a k_RegisterIndex compatible with RegKind_GPR
addGPR32AsmRegOperands(MCInst & Inst,unsigned N) const660 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
661 assert(N == 1 && "Invalid number of operands!");
662 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
663 }
664
addGPRMM16AsmRegOperands(MCInst & Inst,unsigned N) const665 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
666 assert(N == 1 && "Invalid number of operands!");
667 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
668 }
669
addGPRMM16AsmRegZeroOperands(MCInst & Inst,unsigned N) const670 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
671 assert(N == 1 && "Invalid number of operands!");
672 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
673 }
674
675 /// Render the operand to an MCInst as a GPR64
676 /// Asserts if the wrong number of operands are requested, or the operand
677 /// is not a k_RegisterIndex compatible with RegKind_GPR
addGPR64AsmRegOperands(MCInst & Inst,unsigned N) const678 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
679 assert(N == 1 && "Invalid number of operands!");
680 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
681 }
682
addAFGR64AsmRegOperands(MCInst & Inst,unsigned N) const683 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
684 assert(N == 1 && "Invalid number of operands!");
685 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
686 }
687
addFGR64AsmRegOperands(MCInst & Inst,unsigned N) const688 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
689 assert(N == 1 && "Invalid number of operands!");
690 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
691 }
692
addFGR32AsmRegOperands(MCInst & Inst,unsigned N) const693 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
694 assert(N == 1 && "Invalid number of operands!");
695 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
696 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
697 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
698 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
699 "registers");
700 }
701
addFGRH32AsmRegOperands(MCInst & Inst,unsigned N) const702 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
703 assert(N == 1 && "Invalid number of operands!");
704 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
705 }
706
addFCCAsmRegOperands(MCInst & Inst,unsigned N) const707 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
708 assert(N == 1 && "Invalid number of operands!");
709 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
710 }
711
addMSA128AsmRegOperands(MCInst & Inst,unsigned N) const712 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
713 assert(N == 1 && "Invalid number of operands!");
714 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
715 }
716
addMSACtrlAsmRegOperands(MCInst & Inst,unsigned N) const717 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
718 assert(N == 1 && "Invalid number of operands!");
719 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
720 }
721
addCOP2AsmRegOperands(MCInst & Inst,unsigned N) const722 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
723 assert(N == 1 && "Invalid number of operands!");
724 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
725 }
726
addCOP3AsmRegOperands(MCInst & Inst,unsigned N) const727 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
728 assert(N == 1 && "Invalid number of operands!");
729 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
730 }
731
addACC64DSPAsmRegOperands(MCInst & Inst,unsigned N) const732 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
733 assert(N == 1 && "Invalid number of operands!");
734 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
735 }
736
addHI32DSPAsmRegOperands(MCInst & Inst,unsigned N) const737 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
738 assert(N == 1 && "Invalid number of operands!");
739 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
740 }
741
addLO32DSPAsmRegOperands(MCInst & Inst,unsigned N) const742 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
743 assert(N == 1 && "Invalid number of operands!");
744 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
745 }
746
addCCRAsmRegOperands(MCInst & Inst,unsigned N) const747 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
748 assert(N == 1 && "Invalid number of operands!");
749 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
750 }
751
addHWRegsAsmRegOperands(MCInst & Inst,unsigned N) const752 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
753 assert(N == 1 && "Invalid number of operands!");
754 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
755 }
756
addImmOperands(MCInst & Inst,unsigned N) const757 void addImmOperands(MCInst &Inst, unsigned N) const {
758 assert(N == 1 && "Invalid number of operands!");
759 const MCExpr *Expr = getImm();
760 addExpr(Inst, Expr);
761 }
762
addMemOperands(MCInst & Inst,unsigned N) const763 void addMemOperands(MCInst &Inst, unsigned N) const {
764 assert(N == 2 && "Invalid number of operands!");
765
766 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
767
768 const MCExpr *Expr = getMemOff();
769 addExpr(Inst, Expr);
770 }
771
addMicroMipsMemOperands(MCInst & Inst,unsigned N) const772 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
773 assert(N == 2 && "Invalid number of operands!");
774
775 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
776
777 const MCExpr *Expr = getMemOff();
778 addExpr(Inst, Expr);
779 }
780
addRegListOperands(MCInst & Inst,unsigned N) const781 void addRegListOperands(MCInst &Inst, unsigned N) const {
782 assert(N == 1 && "Invalid number of operands!");
783
784 for (auto RegNo : getRegList())
785 Inst.addOperand(MCOperand::CreateReg(RegNo));
786 }
787
addRegPairOperands(MCInst & Inst,unsigned N) const788 void addRegPairOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 2 && "Invalid number of operands!");
790 unsigned RegNo = getRegPair();
791 Inst.addOperand(MCOperand::CreateReg(RegNo++));
792 Inst.addOperand(MCOperand::CreateReg(RegNo));
793 }
794
isReg() const795 bool isReg() const override {
796 // As a special case until we sort out the definition of div/divu, pretend
797 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
798 if (isGPRAsmReg() && RegIdx.Index == 0)
799 return true;
800
801 return Kind == k_PhysRegister;
802 }
isRegIdx() const803 bool isRegIdx() const { return Kind == k_RegisterIndex; }
isImm() const804 bool isImm() const override { return Kind == k_Immediate; }
isConstantImm() const805 bool isConstantImm() const {
806 return isImm() && dyn_cast<MCConstantExpr>(getImm());
807 }
isToken() const808 bool isToken() const override {
809 // Note: It's not possible to pretend that other operand kinds are tokens.
810 // The matcher emitter checks tokens first.
811 return Kind == k_Token;
812 }
isMem() const813 bool isMem() const override { return Kind == k_Memory; }
isConstantMemOff() const814 bool isConstantMemOff() const {
815 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
816 }
isMemWithSimmOffset() const817 template <unsigned Bits> bool isMemWithSimmOffset() const {
818 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
819 }
isMemWithGRPMM16Base() const820 bool isMemWithGRPMM16Base() const {
821 return isMem() && getMemBase()->isMM16AsmReg();
822 }
isMemWithUimmOffsetSP() const823 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
824 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
825 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
826 }
isMemWithUimmWordAlignedOffsetSP() const827 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
828 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
829 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
830 && (getMemBase()->getGPR32Reg() == Mips::SP);
831 }
isRegList16() const832 bool isRegList16() const {
833 if (!isRegList())
834 return false;
835
836 int Size = RegList.List->size();
837 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
838 RegList.List->back() != Mips::RA)
839 return false;
840
841 int PrevReg = *RegList.List->begin();
842 for (int i = 1; i < Size - 1; i++) {
843 int Reg = (*(RegList.List))[i];
844 if ( Reg != PrevReg + 1)
845 return false;
846 PrevReg = Reg;
847 }
848
849 return true;
850 }
isInvNum() const851 bool isInvNum() const { return Kind == k_Immediate; }
isLSAImm() const852 bool isLSAImm() const {
853 if (!isConstantImm())
854 return false;
855 int64_t Val = getConstantImm();
856 return 1 <= Val && Val <= 4;
857 }
isRegList() const858 bool isRegList() const { return Kind == k_RegList; }
859
getToken() const860 StringRef getToken() const {
861 assert(Kind == k_Token && "Invalid access!");
862 return StringRef(Tok.Data, Tok.Length);
863 }
isRegPair() const864 bool isRegPair() const { return Kind == k_RegPair; }
865
getReg() const866 unsigned getReg() const override {
867 // As a special case until we sort out the definition of div/divu, pretend
868 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
869 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
870 RegIdx.Kind & RegKind_GPR)
871 return getGPR32Reg(); // FIXME: GPR64 too
872
873 assert(Kind == k_PhysRegister && "Invalid access!");
874 return PhysReg.Num;
875 }
876
getImm() const877 const MCExpr *getImm() const {
878 assert((Kind == k_Immediate) && "Invalid access!");
879 return Imm.Val;
880 }
881
getConstantImm() const882 int64_t getConstantImm() const {
883 const MCExpr *Val = getImm();
884 return static_cast<const MCConstantExpr *>(Val)->getValue();
885 }
886
getMemBase() const887 MipsOperand *getMemBase() const {
888 assert((Kind == k_Memory) && "Invalid access!");
889 return Mem.Base;
890 }
891
getMemOff() const892 const MCExpr *getMemOff() const {
893 assert((Kind == k_Memory) && "Invalid access!");
894 return Mem.Off;
895 }
896
getConstantMemOff() const897 int64_t getConstantMemOff() const {
898 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
899 }
900
getRegList() const901 const SmallVectorImpl<unsigned> &getRegList() const {
902 assert((Kind == k_RegList) && "Invalid access!");
903 return *(RegList.List);
904 }
905
getRegPair() const906 unsigned getRegPair() const {
907 assert((Kind == k_RegPair) && "Invalid access!");
908 return RegIdx.Index;
909 }
910
CreateToken(StringRef Str,SMLoc S,MipsAsmParser & Parser)911 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
912 MipsAsmParser &Parser) {
913 auto Op = make_unique<MipsOperand>(k_Token, Parser);
914 Op->Tok.Data = Str.data();
915 Op->Tok.Length = Str.size();
916 Op->StartLoc = S;
917 Op->EndLoc = S;
918 return Op;
919 }
920
921 /// Create a numeric register (e.g. $1). The exact register remains
922 /// unresolved until an instruction successfully matches
923 static std::unique_ptr<MipsOperand>
createNumericReg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)924 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
925 SMLoc E, MipsAsmParser &Parser) {
926 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
927 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
928 }
929
930 /// Create a register that is definitely a GPR.
931 /// This is typically only used for named registers such as $gp.
932 static std::unique_ptr<MipsOperand>
createGPRReg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)933 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
934 MipsAsmParser &Parser) {
935 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
936 }
937
938 /// Create a register that is definitely a FGR.
939 /// This is typically only used for named registers such as $f0.
940 static std::unique_ptr<MipsOperand>
createFGRReg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)941 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
942 MipsAsmParser &Parser) {
943 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
944 }
945
946 /// Create a register that is definitely a HWReg.
947 /// This is typically only used for named registers such as $hwr_cpunum.
948 static std::unique_ptr<MipsOperand>
createHWRegsReg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)949 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
950 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
951 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
952 }
953
954 /// Create a register that is definitely an FCC.
955 /// This is typically only used for named registers such as $fcc0.
956 static std::unique_ptr<MipsOperand>
createFCCReg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)957 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
958 MipsAsmParser &Parser) {
959 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
960 }
961
962 /// Create a register that is definitely an ACC.
963 /// This is typically only used for named registers such as $ac0.
964 static std::unique_ptr<MipsOperand>
createACCReg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)965 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
966 MipsAsmParser &Parser) {
967 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
968 }
969
970 /// Create a register that is definitely an MSA128.
971 /// This is typically only used for named registers such as $w0.
972 static std::unique_ptr<MipsOperand>
createMSA128Reg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)973 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
974 SMLoc E, MipsAsmParser &Parser) {
975 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
976 }
977
978 /// Create a register that is definitely an MSACtrl.
979 /// This is typically only used for named registers such as $msaaccess.
980 static std::unique_ptr<MipsOperand>
createMSACtrlReg(unsigned Index,const MCRegisterInfo * RegInfo,SMLoc S,SMLoc E,MipsAsmParser & Parser)981 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
982 SMLoc E, MipsAsmParser &Parser) {
983 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
984 }
985
986 static std::unique_ptr<MipsOperand>
CreateImm(const MCExpr * Val,SMLoc S,SMLoc E,MipsAsmParser & Parser)987 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
988 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
989 Op->Imm.Val = Val;
990 Op->StartLoc = S;
991 Op->EndLoc = E;
992 return Op;
993 }
994
995 static std::unique_ptr<MipsOperand>
CreateMem(std::unique_ptr<MipsOperand> Base,const MCExpr * Off,SMLoc S,SMLoc E,MipsAsmParser & Parser)996 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
997 SMLoc E, MipsAsmParser &Parser) {
998 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
999 Op->Mem.Base = Base.release();
1000 Op->Mem.Off = Off;
1001 Op->StartLoc = S;
1002 Op->EndLoc = E;
1003 return Op;
1004 }
1005
1006 static std::unique_ptr<MipsOperand>
CreateRegList(SmallVectorImpl<unsigned> & Regs,SMLoc StartLoc,SMLoc EndLoc,MipsAsmParser & Parser)1007 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1008 MipsAsmParser &Parser) {
1009 assert (Regs.size() > 0 && "Empty list not allowed");
1010
1011 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1012 Op->RegList.List = new SmallVector<unsigned, 10>();
1013 for (auto Reg : Regs)
1014 Op->RegList.List->push_back(Reg);
1015 Op->StartLoc = StartLoc;
1016 Op->EndLoc = EndLoc;
1017 return Op;
1018 }
1019
1020 static std::unique_ptr<MipsOperand>
CreateRegPair(unsigned RegNo,SMLoc S,SMLoc E,MipsAsmParser & Parser)1021 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1022 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1023 Op->RegIdx.Index = RegNo;
1024 Op->StartLoc = S;
1025 Op->EndLoc = E;
1026 return Op;
1027 }
1028
isGPRAsmReg() const1029 bool isGPRAsmReg() const {
1030 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1031 }
isMM16AsmReg() const1032 bool isMM16AsmReg() const {
1033 if (!(isRegIdx() && RegIdx.Kind))
1034 return false;
1035 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1036 || RegIdx.Index == 16 || RegIdx.Index == 17);
1037 }
isMM16AsmRegZero() const1038 bool isMM16AsmRegZero() const {
1039 if (!(isRegIdx() && RegIdx.Kind))
1040 return false;
1041 return (RegIdx.Index == 0 ||
1042 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1043 RegIdx.Index == 17);
1044 }
isFGRAsmReg() const1045 bool isFGRAsmReg() const {
1046 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1047 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1048 }
isHWRegsAsmReg() const1049 bool isHWRegsAsmReg() const {
1050 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1051 }
isCCRAsmReg() const1052 bool isCCRAsmReg() const {
1053 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1054 }
isFCCAsmReg() const1055 bool isFCCAsmReg() const {
1056 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1057 return false;
1058 if (!AsmParser.hasEightFccRegisters())
1059 return RegIdx.Index == 0;
1060 return RegIdx.Index <= 7;
1061 }
isACCAsmReg() const1062 bool isACCAsmReg() const {
1063 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1064 }
isCOP2AsmReg() const1065 bool isCOP2AsmReg() const {
1066 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1067 }
isCOP3AsmReg() const1068 bool isCOP3AsmReg() const {
1069 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1070 }
isMSA128AsmReg() const1071 bool isMSA128AsmReg() const {
1072 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1073 }
isMSACtrlAsmReg() const1074 bool isMSACtrlAsmReg() const {
1075 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1076 }
1077
1078 /// getStartLoc - Get the location of the first token of this operand.
getStartLoc() const1079 SMLoc getStartLoc() const override { return StartLoc; }
1080 /// getEndLoc - Get the location of the last token of this operand.
getEndLoc() const1081 SMLoc getEndLoc() const override { return EndLoc; }
1082
~MipsOperand()1083 virtual ~MipsOperand() {
1084 switch (Kind) {
1085 case k_Immediate:
1086 break;
1087 case k_Memory:
1088 delete Mem.Base;
1089 break;
1090 case k_RegList:
1091 delete RegList.List;
1092 case k_PhysRegister:
1093 case k_RegisterIndex:
1094 case k_Token:
1095 case k_RegPair:
1096 break;
1097 }
1098 }
1099
print(raw_ostream & OS) const1100 void print(raw_ostream &OS) const override {
1101 switch (Kind) {
1102 case k_Immediate:
1103 OS << "Imm<";
1104 Imm.Val->print(OS);
1105 OS << ">";
1106 break;
1107 case k_Memory:
1108 OS << "Mem<";
1109 Mem.Base->print(OS);
1110 OS << ", ";
1111 Mem.Off->print(OS);
1112 OS << ">";
1113 break;
1114 case k_PhysRegister:
1115 OS << "PhysReg<" << PhysReg.Num << ">";
1116 break;
1117 case k_RegisterIndex:
1118 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1119 break;
1120 case k_Token:
1121 OS << Tok.Data;
1122 break;
1123 case k_RegList:
1124 OS << "RegList< ";
1125 for (auto Reg : (*RegList.List))
1126 OS << Reg << " ";
1127 OS << ">";
1128 break;
1129 case k_RegPair:
1130 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1131 break;
1132 }
1133 }
1134 }; // class MipsOperand
1135 } // namespace
1136
1137 namespace llvm {
1138 extern const MCInstrDesc MipsInsts[];
1139 }
getInstDesc(unsigned Opcode)1140 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1141 return MipsInsts[Opcode];
1142 }
1143
hasShortDelaySlot(unsigned Opcode)1144 static bool hasShortDelaySlot(unsigned Opcode) {
1145 switch (Opcode) {
1146 case Mips::JALS_MM:
1147 case Mips::JALRS_MM:
1148 case Mips::JALRS16_MM:
1149 case Mips::BGEZALS_MM:
1150 case Mips::BLTZALS_MM:
1151 return true;
1152 default:
1153 return false;
1154 }
1155 }
1156
processInstruction(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1157 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1158 SmallVectorImpl<MCInst> &Instructions) {
1159 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1160
1161 Inst.setLoc(IDLoc);
1162
1163 if (MCID.isBranch() || MCID.isCall()) {
1164 const unsigned Opcode = Inst.getOpcode();
1165 MCOperand Offset;
1166
1167 switch (Opcode) {
1168 default:
1169 break;
1170 case Mips::BEQ:
1171 case Mips::BNE:
1172 case Mips::BEQ_MM:
1173 case Mips::BNE_MM:
1174 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1175 Offset = Inst.getOperand(2);
1176 if (!Offset.isImm())
1177 break; // We'll deal with this situation later on when applying fixups.
1178 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1179 return Error(IDLoc, "branch target out of range");
1180 if (OffsetToAlignment(Offset.getImm(),
1181 1LL << (inMicroMipsMode() ? 1 : 2)))
1182 return Error(IDLoc, "branch to misaligned address");
1183 break;
1184 case Mips::BGEZ:
1185 case Mips::BGTZ:
1186 case Mips::BLEZ:
1187 case Mips::BLTZ:
1188 case Mips::BGEZAL:
1189 case Mips::BLTZAL:
1190 case Mips::BC1F:
1191 case Mips::BC1T:
1192 case Mips::BGEZ_MM:
1193 case Mips::BGTZ_MM:
1194 case Mips::BLEZ_MM:
1195 case Mips::BLTZ_MM:
1196 case Mips::BGEZAL_MM:
1197 case Mips::BLTZAL_MM:
1198 case Mips::BC1F_MM:
1199 case Mips::BC1T_MM:
1200 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1201 Offset = Inst.getOperand(1);
1202 if (!Offset.isImm())
1203 break; // We'll deal with this situation later on when applying fixups.
1204 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1205 return Error(IDLoc, "branch target out of range");
1206 if (OffsetToAlignment(Offset.getImm(),
1207 1LL << (inMicroMipsMode() ? 1 : 2)))
1208 return Error(IDLoc, "branch to misaligned address");
1209 break;
1210 case Mips::BEQZ16_MM:
1211 case Mips::BNEZ16_MM:
1212 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1213 Offset = Inst.getOperand(1);
1214 if (!Offset.isImm())
1215 break; // We'll deal with this situation later on when applying fixups.
1216 if (!isIntN(8, Offset.getImm()))
1217 return Error(IDLoc, "branch target out of range");
1218 if (OffsetToAlignment(Offset.getImm(), 2LL))
1219 return Error(IDLoc, "branch to misaligned address");
1220 break;
1221 }
1222 }
1223
1224 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1225 // We still accept it but it is a normal nop.
1226 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1227 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1228 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1229 "nop instruction");
1230 }
1231
1232 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1233 // If this instruction has a delay slot and .set reorder is active,
1234 // emit a NOP after it.
1235 Instructions.push_back(Inst);
1236 MCInst NopInst;
1237 if (hasShortDelaySlot(Inst.getOpcode())) {
1238 NopInst.setOpcode(Mips::MOVE16_MM);
1239 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1240 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1241 } else {
1242 NopInst.setOpcode(Mips::SLL);
1243 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1244 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1245 NopInst.addOperand(MCOperand::CreateImm(0));
1246 }
1247 Instructions.push_back(NopInst);
1248 return false;
1249 }
1250
1251 if (MCID.mayLoad() || MCID.mayStore()) {
1252 // Check the offset of memory operand, if it is a symbol
1253 // reference or immediate we may have to expand instructions.
1254 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1255 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1256 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1257 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1258 MCOperand &Op = Inst.getOperand(i);
1259 if (Op.isImm()) {
1260 int MemOffset = Op.getImm();
1261 if (MemOffset < -32768 || MemOffset > 32767) {
1262 // Offset can't exceed 16bit value.
1263 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1264 return false;
1265 }
1266 } else if (Op.isExpr()) {
1267 const MCExpr *Expr = Op.getExpr();
1268 if (Expr->getKind() == MCExpr::SymbolRef) {
1269 const MCSymbolRefExpr *SR =
1270 static_cast<const MCSymbolRefExpr *>(Expr);
1271 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1272 // Expand symbol.
1273 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1274 return false;
1275 }
1276 } else if (!isEvaluated(Expr)) {
1277 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1278 return false;
1279 }
1280 }
1281 }
1282 } // for
1283 } // if load/store
1284
1285 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1286 if (inMicroMipsMode()) {
1287 MCOperand Opnd;
1288 int Imm;
1289
1290 switch (Inst.getOpcode()) {
1291 default:
1292 break;
1293 case Mips::ADDIUS5_MM:
1294 Opnd = Inst.getOperand(2);
1295 if (!Opnd.isImm())
1296 return Error(IDLoc, "expected immediate operand kind");
1297 Imm = Opnd.getImm();
1298 if (Imm < -8 || Imm > 7)
1299 return Error(IDLoc, "immediate operand value out of range");
1300 break;
1301 case Mips::ADDIUSP_MM:
1302 Opnd = Inst.getOperand(0);
1303 if (!Opnd.isImm())
1304 return Error(IDLoc, "expected immediate operand kind");
1305 Imm = Opnd.getImm();
1306 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1307 Imm % 4 != 0)
1308 return Error(IDLoc, "immediate operand value out of range");
1309 break;
1310 case Mips::SLL16_MM:
1311 case Mips::SRL16_MM:
1312 Opnd = Inst.getOperand(2);
1313 if (!Opnd.isImm())
1314 return Error(IDLoc, "expected immediate operand kind");
1315 Imm = Opnd.getImm();
1316 if (Imm < 1 || Imm > 8)
1317 return Error(IDLoc, "immediate operand value out of range");
1318 break;
1319 case Mips::LI16_MM:
1320 Opnd = Inst.getOperand(1);
1321 if (!Opnd.isImm())
1322 return Error(IDLoc, "expected immediate operand kind");
1323 Imm = Opnd.getImm();
1324 if (Imm < -1 || Imm > 126)
1325 return Error(IDLoc, "immediate operand value out of range");
1326 break;
1327 case Mips::ADDIUR2_MM:
1328 Opnd = Inst.getOperand(2);
1329 if (!Opnd.isImm())
1330 return Error(IDLoc, "expected immediate operand kind");
1331 Imm = Opnd.getImm();
1332 if (!(Imm == 1 || Imm == -1 ||
1333 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1334 return Error(IDLoc, "immediate operand value out of range");
1335 break;
1336 case Mips::ADDIUR1SP_MM:
1337 Opnd = Inst.getOperand(1);
1338 if (!Opnd.isImm())
1339 return Error(IDLoc, "expected immediate operand kind");
1340 Imm = Opnd.getImm();
1341 if (OffsetToAlignment(Imm, 4LL))
1342 return Error(IDLoc, "misaligned immediate operand value");
1343 if (Imm < 0 || Imm > 255)
1344 return Error(IDLoc, "immediate operand value out of range");
1345 break;
1346 case Mips::ANDI16_MM:
1347 Opnd = Inst.getOperand(2);
1348 if (!Opnd.isImm())
1349 return Error(IDLoc, "expected immediate operand kind");
1350 Imm = Opnd.getImm();
1351 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1352 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1353 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1354 return Error(IDLoc, "immediate operand value out of range");
1355 break;
1356 case Mips::LBU16_MM:
1357 Opnd = Inst.getOperand(2);
1358 if (!Opnd.isImm())
1359 return Error(IDLoc, "expected immediate operand kind");
1360 Imm = Opnd.getImm();
1361 if (Imm < -1 || Imm > 14)
1362 return Error(IDLoc, "immediate operand value out of range");
1363 break;
1364 case Mips::SB16_MM:
1365 Opnd = Inst.getOperand(2);
1366 if (!Opnd.isImm())
1367 return Error(IDLoc, "expected immediate operand kind");
1368 Imm = Opnd.getImm();
1369 if (Imm < 0 || Imm > 15)
1370 return Error(IDLoc, "immediate operand value out of range");
1371 break;
1372 case Mips::LHU16_MM:
1373 case Mips::SH16_MM:
1374 Opnd = Inst.getOperand(2);
1375 if (!Opnd.isImm())
1376 return Error(IDLoc, "expected immediate operand kind");
1377 Imm = Opnd.getImm();
1378 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1379 return Error(IDLoc, "immediate operand value out of range");
1380 break;
1381 case Mips::LW16_MM:
1382 case Mips::SW16_MM:
1383 Opnd = Inst.getOperand(2);
1384 if (!Opnd.isImm())
1385 return Error(IDLoc, "expected immediate operand kind");
1386 Imm = Opnd.getImm();
1387 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1388 return Error(IDLoc, "immediate operand value out of range");
1389 break;
1390 case Mips::CACHE:
1391 case Mips::PREF:
1392 Opnd = Inst.getOperand(2);
1393 if (!Opnd.isImm())
1394 return Error(IDLoc, "expected immediate operand kind");
1395 Imm = Opnd.getImm();
1396 if (!isUInt<5>(Imm))
1397 return Error(IDLoc, "immediate operand value out of range");
1398 break;
1399 }
1400 }
1401
1402 if (needsExpansion(Inst))
1403 return expandInstruction(Inst, IDLoc, Instructions);
1404 else
1405 Instructions.push_back(Inst);
1406
1407 return false;
1408 }
1409
needsExpansion(MCInst & Inst)1410 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1411
1412 switch (Inst.getOpcode()) {
1413 case Mips::LoadImm32Reg:
1414 case Mips::LoadAddr32Imm:
1415 case Mips::LoadAddr32Reg:
1416 case Mips::LoadImm64Reg:
1417 return true;
1418 default:
1419 return false;
1420 }
1421 }
1422
expandInstruction(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1423 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1424 SmallVectorImpl<MCInst> &Instructions) {
1425 switch (Inst.getOpcode()) {
1426 default: llvm_unreachable("unimplemented expansion");
1427 case Mips::LoadImm32Reg:
1428 return expandLoadImm(Inst, IDLoc, Instructions);
1429 case Mips::LoadImm64Reg:
1430 if (!isGP64bit()) {
1431 Error(IDLoc, "instruction requires a 64-bit architecture");
1432 return true;
1433 }
1434 return expandLoadImm(Inst, IDLoc, Instructions);
1435 case Mips::LoadAddr32Imm:
1436 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1437 case Mips::LoadAddr32Reg:
1438 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1439 }
1440 }
1441
1442 namespace {
1443 template <bool PerformShift>
createShiftOr(MCOperand Operand,unsigned RegNo,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1444 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1445 SmallVectorImpl<MCInst> &Instructions) {
1446 MCInst tmpInst;
1447 if (PerformShift) {
1448 tmpInst.setOpcode(Mips::DSLL);
1449 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1450 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1451 tmpInst.addOperand(MCOperand::CreateImm(16));
1452 tmpInst.setLoc(IDLoc);
1453 Instructions.push_back(tmpInst);
1454 tmpInst.clear();
1455 }
1456 tmpInst.setOpcode(Mips::ORi);
1457 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1458 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1459 tmpInst.addOperand(Operand);
1460 tmpInst.setLoc(IDLoc);
1461 Instructions.push_back(tmpInst);
1462 }
1463
1464 template <int Shift, bool PerformShift>
createShiftOr(int64_t Value,unsigned RegNo,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1465 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1466 SmallVectorImpl<MCInst> &Instructions) {
1467 createShiftOr<PerformShift>(
1468 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1469 IDLoc, Instructions);
1470 }
1471 }
1472
expandLoadImm(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1473 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1474 SmallVectorImpl<MCInst> &Instructions) {
1475 MCInst tmpInst;
1476 const MCOperand &ImmOp = Inst.getOperand(1);
1477 assert(ImmOp.isImm() && "expected immediate operand kind");
1478 const MCOperand &RegOp = Inst.getOperand(0);
1479 assert(RegOp.isReg() && "expected register operand kind");
1480
1481 int64_t ImmValue = ImmOp.getImm();
1482 tmpInst.setLoc(IDLoc);
1483 // FIXME: gas has a special case for values that are 000...1111, which
1484 // becomes a li -1 and then a dsrl
1485 if (0 <= ImmValue && ImmValue <= 65535) {
1486 // For 0 <= j <= 65535.
1487 // li d,j => ori d,$zero,j
1488 tmpInst.setOpcode(Mips::ORi);
1489 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1490 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1491 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1492 Instructions.push_back(tmpInst);
1493 } else if (ImmValue < 0 && ImmValue >= -32768) {
1494 // For -32768 <= j < 0.
1495 // li d,j => addiu d,$zero,j
1496 tmpInst.setOpcode(Mips::ADDiu);
1497 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1498 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1499 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1500 Instructions.push_back(tmpInst);
1501 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1502 // For any value of j that is representable as a 32-bit integer, create
1503 // a sequence of:
1504 // li d,j => lui d,hi16(j)
1505 // ori d,d,lo16(j)
1506 tmpInst.setOpcode(Mips::LUi);
1507 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1508 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1509 Instructions.push_back(tmpInst);
1510 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1511 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1512 if (!isGP64bit()) {
1513 Error(IDLoc, "instruction requires a 64-bit architecture");
1514 return true;
1515 }
1516
1517 // <------- lo32 ------>
1518 // <------- hi32 ------>
1519 // <- hi16 -> <- lo16 ->
1520 // _________________________________
1521 // | | | |
1522 // | 16-bytes | 16-bytes | 16-bytes |
1523 // |__________|__________|__________|
1524 //
1525 // For any value of j that is representable as a 48-bit integer, create
1526 // a sequence of:
1527 // li d,j => lui d,hi16(j)
1528 // ori d,d,hi16(lo32(j))
1529 // dsll d,d,16
1530 // ori d,d,lo16(lo32(j))
1531 tmpInst.setOpcode(Mips::LUi);
1532 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1533 tmpInst.addOperand(
1534 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1535 Instructions.push_back(tmpInst);
1536 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1537 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1538 } else {
1539 if (!isGP64bit()) {
1540 Error(IDLoc, "instruction requires a 64-bit architecture");
1541 return true;
1542 }
1543
1544 // <------- hi32 ------> <------- lo32 ------>
1545 // <- hi16 -> <- lo16 ->
1546 // ___________________________________________
1547 // | | | | |
1548 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1549 // |__________|__________|__________|__________|
1550 //
1551 // For any value of j that isn't representable as a 48-bit integer.
1552 // li d,j => lui d,hi16(j)
1553 // ori d,d,lo16(hi32(j))
1554 // dsll d,d,16
1555 // ori d,d,hi16(lo32(j))
1556 // dsll d,d,16
1557 // ori d,d,lo16(lo32(j))
1558 tmpInst.setOpcode(Mips::LUi);
1559 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1560 tmpInst.addOperand(
1561 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1562 Instructions.push_back(tmpInst);
1563 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1564 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1565 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1566 }
1567 return false;
1568 }
1569
1570 bool
expandLoadAddressReg(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1571 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1572 SmallVectorImpl<MCInst> &Instructions) {
1573 MCInst tmpInst;
1574 const MCOperand &ImmOp = Inst.getOperand(2);
1575 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1576 "expected immediate operand kind");
1577 if (!ImmOp.isImm()) {
1578 expandLoadAddressSym(Inst, IDLoc, Instructions);
1579 return false;
1580 }
1581 const MCOperand &SrcRegOp = Inst.getOperand(1);
1582 assert(SrcRegOp.isReg() && "expected register operand kind");
1583 const MCOperand &DstRegOp = Inst.getOperand(0);
1584 assert(DstRegOp.isReg() && "expected register operand kind");
1585 int ImmValue = ImmOp.getImm();
1586 if (-32768 <= ImmValue && ImmValue <= 65535) {
1587 // For -32768 <= j <= 65535.
1588 // la d,j(s) => addiu d,s,j
1589 tmpInst.setOpcode(Mips::ADDiu);
1590 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1591 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1592 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1593 Instructions.push_back(tmpInst);
1594 } else {
1595 // For any other value of j that is representable as a 32-bit integer.
1596 // la d,j(s) => lui d,hi16(j)
1597 // ori d,d,lo16(j)
1598 // addu d,d,s
1599 tmpInst.setOpcode(Mips::LUi);
1600 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1601 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1602 Instructions.push_back(tmpInst);
1603 tmpInst.clear();
1604 tmpInst.setOpcode(Mips::ORi);
1605 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1606 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1607 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1608 Instructions.push_back(tmpInst);
1609 tmpInst.clear();
1610 tmpInst.setOpcode(Mips::ADDu);
1611 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1612 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1613 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1614 Instructions.push_back(tmpInst);
1615 }
1616 return false;
1617 }
1618
1619 bool
expandLoadAddressImm(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1620 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1621 SmallVectorImpl<MCInst> &Instructions) {
1622 MCInst tmpInst;
1623 const MCOperand &ImmOp = Inst.getOperand(1);
1624 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1625 "expected immediate operand kind");
1626 if (!ImmOp.isImm()) {
1627 expandLoadAddressSym(Inst, IDLoc, Instructions);
1628 return false;
1629 }
1630 const MCOperand &RegOp = Inst.getOperand(0);
1631 assert(RegOp.isReg() && "expected register operand kind");
1632 int ImmValue = ImmOp.getImm();
1633 if (-32768 <= ImmValue && ImmValue <= 65535) {
1634 // For -32768 <= j <= 65535.
1635 // la d,j => addiu d,$zero,j
1636 tmpInst.setOpcode(Mips::ADDiu);
1637 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1638 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1639 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1640 Instructions.push_back(tmpInst);
1641 } else {
1642 // For any other value of j that is representable as a 32-bit integer.
1643 // la d,j => lui d,hi16(j)
1644 // ori d,d,lo16(j)
1645 tmpInst.setOpcode(Mips::LUi);
1646 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1647 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1648 Instructions.push_back(tmpInst);
1649 tmpInst.clear();
1650 tmpInst.setOpcode(Mips::ORi);
1651 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1652 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1653 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1654 Instructions.push_back(tmpInst);
1655 }
1656 return false;
1657 }
1658
1659 void
expandLoadAddressSym(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions)1660 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1661 SmallVectorImpl<MCInst> &Instructions) {
1662 // FIXME: If we do have a valid at register to use, we should generate a
1663 // slightly shorter sequence here.
1664 MCInst tmpInst;
1665 int ExprOperandNo = 1;
1666 // Sometimes the assembly parser will get the immediate expression as
1667 // a $zero + an immediate.
1668 if (Inst.getNumOperands() == 3) {
1669 assert(Inst.getOperand(1).getReg() ==
1670 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1671 ExprOperandNo = 2;
1672 }
1673 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1674 assert(SymOp.isExpr() && "expected symbol operand kind");
1675 const MCOperand &RegOp = Inst.getOperand(0);
1676 unsigned RegNo = RegOp.getReg();
1677 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1678 const MCSymbolRefExpr *HiExpr =
1679 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1680 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1681 const MCSymbolRefExpr *LoExpr =
1682 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1683 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1684 if (isGP64bit()) {
1685 // If it's a 64-bit architecture, expand to:
1686 // la d,sym => lui d,highest(sym)
1687 // ori d,d,higher(sym)
1688 // dsll d,d,16
1689 // ori d,d,hi16(sym)
1690 // dsll d,d,16
1691 // ori d,d,lo16(sym)
1692 const MCSymbolRefExpr *HighestExpr =
1693 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1694 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1695 const MCSymbolRefExpr *HigherExpr =
1696 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1697 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1698
1699 tmpInst.setOpcode(Mips::LUi);
1700 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1701 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1702 Instructions.push_back(tmpInst);
1703
1704 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1705 Instructions);
1706 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1707 Instructions);
1708 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1709 Instructions);
1710 } else {
1711 // Otherwise, expand to:
1712 // la d,sym => lui d,hi16(sym)
1713 // ori d,d,lo16(sym)
1714 tmpInst.setOpcode(Mips::LUi);
1715 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1716 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1717 Instructions.push_back(tmpInst);
1718
1719 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1720 Instructions);
1721 }
1722 }
1723
expandMemInst(MCInst & Inst,SMLoc IDLoc,SmallVectorImpl<MCInst> & Instructions,bool isLoad,bool isImmOpnd)1724 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1725 SmallVectorImpl<MCInst> &Instructions,
1726 bool isLoad, bool isImmOpnd) {
1727 const MCSymbolRefExpr *SR;
1728 MCInst TempInst;
1729 unsigned ImmOffset, HiOffset, LoOffset;
1730 const MCExpr *ExprOffset;
1731 unsigned TmpRegNum;
1732 // 1st operand is either the source or destination register.
1733 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1734 unsigned RegOpNum = Inst.getOperand(0).getReg();
1735 // 2nd operand is the base register.
1736 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1737 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1738 // 3rd operand is either an immediate or expression.
1739 if (isImmOpnd) {
1740 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1741 ImmOffset = Inst.getOperand(2).getImm();
1742 LoOffset = ImmOffset & 0x0000ffff;
1743 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1744 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1745 if (LoOffset & 0x8000)
1746 HiOffset++;
1747 } else
1748 ExprOffset = Inst.getOperand(2).getExpr();
1749 // All instructions will have the same location.
1750 TempInst.setLoc(IDLoc);
1751 // These are some of the types of expansions we perform here:
1752 // 1) lw $8, sym => lui $8, %hi(sym)
1753 // lw $8, %lo(sym)($8)
1754 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1755 // add $8, $8, $9
1756 // lw $8, %lo(offset)($9)
1757 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1758 // add $at, $at, $8
1759 // lw $8, %lo(offset)($at)
1760 // 4) sw $8, sym => lui $at, %hi(sym)
1761 // sw $8, %lo(sym)($at)
1762 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1763 // add $at, $at, $8
1764 // sw $8, %lo(offset)($at)
1765 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1766 // ldc1 $f0, %lo(sym)($at)
1767 //
1768 // For load instructions we can use the destination register as a temporary
1769 // if base and dst are different (examples 1 and 2) and if the base register
1770 // is general purpose otherwise we must use $at (example 6) and error if it's
1771 // not available. For stores we must use $at (examples 4 and 5) because we
1772 // must not clobber the source register setting up the offset.
1773 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1774 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1775 unsigned RegClassIDOp0 =
1776 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1777 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1778 (RegClassIDOp0 == Mips::GPR64RegClassID);
1779 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1780 TmpRegNum = RegOpNum;
1781 else {
1782 int AT = getATReg(IDLoc);
1783 // At this point we need AT to perform the expansions and we exit if it is
1784 // not available.
1785 if (!AT)
1786 return;
1787 TmpRegNum = getReg(
1788 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1789 }
1790
1791 TempInst.setOpcode(Mips::LUi);
1792 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1793 if (isImmOpnd)
1794 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1795 else {
1796 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1797 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1798 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1799 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1800 getContext());
1801 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1802 } else {
1803 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1804 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1805 }
1806 }
1807 // Add the instruction to the list.
1808 Instructions.push_back(TempInst);
1809 // Prepare TempInst for next instruction.
1810 TempInst.clear();
1811 // Add temp register to base.
1812 TempInst.setOpcode(Mips::ADDu);
1813 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1814 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1815 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1816 Instructions.push_back(TempInst);
1817 TempInst.clear();
1818 // And finally, create original instruction with low part
1819 // of offset and new base.
1820 TempInst.setOpcode(Inst.getOpcode());
1821 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1822 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1823 if (isImmOpnd)
1824 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1825 else {
1826 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1827 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1828 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1829 getContext());
1830 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1831 } else {
1832 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1833 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1834 }
1835 }
1836 Instructions.push_back(TempInst);
1837 TempInst.clear();
1838 }
1839
checkTargetMatchPredicate(MCInst & Inst)1840 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1841 // As described by the Mips32r2 spec, the registers Rd and Rs for
1842 // jalr.hb must be different.
1843 unsigned Opcode = Inst.getOpcode();
1844
1845 if (Opcode == Mips::JALR_HB &&
1846 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1847 return Match_RequiresDifferentSrcAndDst;
1848
1849 return Match_Success;
1850 }
1851
MatchAndEmitInstruction(SMLoc IDLoc,unsigned & Opcode,OperandVector & Operands,MCStreamer & Out,uint64_t & ErrorInfo,bool MatchingInlineAsm)1852 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1853 OperandVector &Operands,
1854 MCStreamer &Out,
1855 uint64_t &ErrorInfo,
1856 bool MatchingInlineAsm) {
1857
1858 MCInst Inst;
1859 SmallVector<MCInst, 8> Instructions;
1860 unsigned MatchResult =
1861 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1862
1863 switch (MatchResult) {
1864 case Match_Success: {
1865 if (processInstruction(Inst, IDLoc, Instructions))
1866 return true;
1867 for (unsigned i = 0; i < Instructions.size(); i++)
1868 Out.EmitInstruction(Instructions[i], STI);
1869 return false;
1870 }
1871 case Match_MissingFeature:
1872 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1873 return true;
1874 case Match_InvalidOperand: {
1875 SMLoc ErrorLoc = IDLoc;
1876 if (ErrorInfo != ~0ULL) {
1877 if (ErrorInfo >= Operands.size())
1878 return Error(IDLoc, "too few operands for instruction");
1879
1880 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1881 if (ErrorLoc == SMLoc())
1882 ErrorLoc = IDLoc;
1883 }
1884
1885 return Error(ErrorLoc, "invalid operand for instruction");
1886 }
1887 case Match_MnemonicFail:
1888 return Error(IDLoc, "invalid instruction");
1889 case Match_RequiresDifferentSrcAndDst:
1890 return Error(IDLoc, "source and destination must be different");
1891 }
1892
1893 llvm_unreachable("Implement any new match types added!");
1894 }
1895
warnIfAssemblerTemporary(int RegIndex,SMLoc Loc)1896 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1897 if ((RegIndex != 0) &&
1898 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1899 if (RegIndex == 1)
1900 Warning(Loc, "used $at without \".set noat\"");
1901 else
1902 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1903 Twine(RegIndex) + "\"");
1904 }
1905 }
1906
1907 void
printWarningWithFixIt(const Twine & Msg,const Twine & FixMsg,SMRange Range,bool ShowColors)1908 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1909 SMRange Range, bool ShowColors) {
1910 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1911 Range, SMFixIt(Range, FixMsg),
1912 ShowColors);
1913 }
1914
matchCPURegisterName(StringRef Name)1915 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1916 int CC;
1917
1918 CC = StringSwitch<unsigned>(Name)
1919 .Case("zero", 0)
1920 .Case("at", 1)
1921 .Case("a0", 4)
1922 .Case("a1", 5)
1923 .Case("a2", 6)
1924 .Case("a3", 7)
1925 .Case("v0", 2)
1926 .Case("v1", 3)
1927 .Case("s0", 16)
1928 .Case("s1", 17)
1929 .Case("s2", 18)
1930 .Case("s3", 19)
1931 .Case("s4", 20)
1932 .Case("s5", 21)
1933 .Case("s6", 22)
1934 .Case("s7", 23)
1935 .Case("k0", 26)
1936 .Case("k1", 27)
1937 .Case("gp", 28)
1938 .Case("sp", 29)
1939 .Case("fp", 30)
1940 .Case("s8", 30)
1941 .Case("ra", 31)
1942 .Case("t0", 8)
1943 .Case("t1", 9)
1944 .Case("t2", 10)
1945 .Case("t3", 11)
1946 .Case("t4", 12)
1947 .Case("t5", 13)
1948 .Case("t6", 14)
1949 .Case("t7", 15)
1950 .Case("t8", 24)
1951 .Case("t9", 25)
1952 .Default(-1);
1953
1954 if (!(isABI_N32() || isABI_N64()))
1955 return CC;
1956
1957 if (12 <= CC && CC <= 15) {
1958 // Name is one of t4-t7
1959 AsmToken RegTok = getLexer().peekTok();
1960 SMRange RegRange = RegTok.getLocRange();
1961
1962 StringRef FixedName = StringSwitch<StringRef>(Name)
1963 .Case("t4", "t0")
1964 .Case("t5", "t1")
1965 .Case("t6", "t2")
1966 .Case("t7", "t3")
1967 .Default("");
1968 assert(FixedName != "" && "Register name is not one of t4-t7.");
1969
1970 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1971 "Did you mean $" + FixedName + "?", RegRange);
1972 }
1973
1974 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1975 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1976 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1977 if (8 <= CC && CC <= 11)
1978 CC += 4;
1979
1980 if (CC == -1)
1981 CC = StringSwitch<unsigned>(Name)
1982 .Case("a4", 8)
1983 .Case("a5", 9)
1984 .Case("a6", 10)
1985 .Case("a7", 11)
1986 .Case("kt0", 26)
1987 .Case("kt1", 27)
1988 .Default(-1);
1989
1990 return CC;
1991 }
1992
matchHWRegsRegisterName(StringRef Name)1993 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
1994 int CC;
1995
1996 CC = StringSwitch<unsigned>(Name)
1997 .Case("hwr_cpunum", 0)
1998 .Case("hwr_synci_step", 1)
1999 .Case("hwr_cc", 2)
2000 .Case("hwr_ccres", 3)
2001 .Case("hwr_ulr", 29)
2002 .Default(-1);
2003
2004 return CC;
2005 }
2006
matchFPURegisterName(StringRef Name)2007 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2008
2009 if (Name[0] == 'f') {
2010 StringRef NumString = Name.substr(1);
2011 unsigned IntVal;
2012 if (NumString.getAsInteger(10, IntVal))
2013 return -1; // This is not an integer.
2014 if (IntVal > 31) // Maximum index for fpu register.
2015 return -1;
2016 return IntVal;
2017 }
2018 return -1;
2019 }
2020
matchFCCRegisterName(StringRef Name)2021 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2022
2023 if (Name.startswith("fcc")) {
2024 StringRef NumString = Name.substr(3);
2025 unsigned IntVal;
2026 if (NumString.getAsInteger(10, IntVal))
2027 return -1; // This is not an integer.
2028 if (IntVal > 7) // There are only 8 fcc registers.
2029 return -1;
2030 return IntVal;
2031 }
2032 return -1;
2033 }
2034
matchACRegisterName(StringRef Name)2035 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2036
2037 if (Name.startswith("ac")) {
2038 StringRef NumString = Name.substr(2);
2039 unsigned IntVal;
2040 if (NumString.getAsInteger(10, IntVal))
2041 return -1; // This is not an integer.
2042 if (IntVal > 3) // There are only 3 acc registers.
2043 return -1;
2044 return IntVal;
2045 }
2046 return -1;
2047 }
2048
matchMSA128RegisterName(StringRef Name)2049 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2050 unsigned IntVal;
2051
2052 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2053 return -1;
2054
2055 if (IntVal > 31)
2056 return -1;
2057
2058 return IntVal;
2059 }
2060
matchMSA128CtrlRegisterName(StringRef Name)2061 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2062 int CC;
2063
2064 CC = StringSwitch<unsigned>(Name)
2065 .Case("msair", 0)
2066 .Case("msacsr", 1)
2067 .Case("msaaccess", 2)
2068 .Case("msasave", 3)
2069 .Case("msamodify", 4)
2070 .Case("msarequest", 5)
2071 .Case("msamap", 6)
2072 .Case("msaunmap", 7)
2073 .Default(-1);
2074
2075 return CC;
2076 }
2077
setATReg(unsigned Reg)2078 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2079 if (Reg > 31)
2080 return false;
2081
2082 ATReg = Reg;
2083 return true;
2084 }
2085
getATReg(SMLoc Loc)2086 int MipsAsmParser::getATReg(SMLoc Loc) {
2087 int AT = AssemblerOptions.back()->getATRegNum();
2088 if (AT == 0)
2089 reportParseError(Loc,
2090 "pseudo-instruction requires $at, which is not available");
2091 return AT;
2092 }
2093
getReg(int RC,int RegNo)2094 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2095 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2096 }
2097
getGPR(int RegNo)2098 unsigned MipsAsmParser::getGPR(int RegNo) {
2099 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2100 RegNo);
2101 }
2102
matchRegisterByNumber(unsigned RegNum,unsigned RegClass)2103 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2104 if (RegNum >
2105 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2106 return -1;
2107
2108 return getReg(RegClass, RegNum);
2109 }
2110
parseOperand(OperandVector & Operands,StringRef Mnemonic)2111 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2112 MCAsmParser &Parser = getParser();
2113 DEBUG(dbgs() << "parseOperand\n");
2114
2115 // Check if the current operand has a custom associated parser, if so, try to
2116 // custom parse the operand, or fallback to the general approach.
2117 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2118 if (ResTy == MatchOperand_Success)
2119 return false;
2120 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2121 // there was a match, but an error occurred, in which case, just return that
2122 // the operand parsing failed.
2123 if (ResTy == MatchOperand_ParseFail)
2124 return true;
2125
2126 DEBUG(dbgs() << ".. Generic Parser\n");
2127
2128 switch (getLexer().getKind()) {
2129 default:
2130 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2131 return true;
2132 case AsmToken::Dollar: {
2133 // Parse the register.
2134 SMLoc S = Parser.getTok().getLoc();
2135
2136 // Almost all registers have been parsed by custom parsers. There is only
2137 // one exception to this. $zero (and it's alias $0) will reach this point
2138 // for div, divu, and similar instructions because it is not an operand
2139 // to the instruction definition but an explicit register. Special case
2140 // this situation for now.
2141 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2142 return false;
2143
2144 // Maybe it is a symbol reference.
2145 StringRef Identifier;
2146 if (Parser.parseIdentifier(Identifier))
2147 return true;
2148
2149 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2150 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2151 // Otherwise create a symbol reference.
2152 const MCExpr *Res =
2153 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2154
2155 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2156 return false;
2157 }
2158 // Else drop to expression parsing.
2159 case AsmToken::LParen:
2160 case AsmToken::Minus:
2161 case AsmToken::Plus:
2162 case AsmToken::Integer:
2163 case AsmToken::Tilde:
2164 case AsmToken::String: {
2165 DEBUG(dbgs() << ".. generic integer\n");
2166 OperandMatchResultTy ResTy = parseImm(Operands);
2167 return ResTy != MatchOperand_Success;
2168 }
2169 case AsmToken::Percent: {
2170 // It is a symbol reference or constant expression.
2171 const MCExpr *IdVal;
2172 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2173 if (parseRelocOperand(IdVal))
2174 return true;
2175
2176 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2177
2178 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2179 return false;
2180 } // case AsmToken::Percent
2181 } // switch(getLexer().getKind())
2182 return true;
2183 }
2184
evaluateRelocExpr(const MCExpr * Expr,StringRef RelocStr)2185 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2186 StringRef RelocStr) {
2187 const MCExpr *Res;
2188 // Check the type of the expression.
2189 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2190 // It's a constant, evaluate reloc value.
2191 int16_t Val;
2192 switch (getVariantKind(RelocStr)) {
2193 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2194 // Get the 1st 16-bits.
2195 Val = MCE->getValue() & 0xffff;
2196 break;
2197 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2198 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2199 // 16 bits being negative.
2200 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2201 break;
2202 case MCSymbolRefExpr::VK_Mips_HIGHER:
2203 // Get the 3rd 16-bits.
2204 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2205 break;
2206 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2207 // Get the 4th 16-bits.
2208 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2209 break;
2210 default:
2211 report_fatal_error("unsupported reloc value");
2212 }
2213 return MCConstantExpr::Create(Val, getContext());
2214 }
2215
2216 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2217 // It's a symbol, create a symbolic expression from the symbol.
2218 StringRef Symbol = MSRE->getSymbol().getName();
2219 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2220 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2221 return Res;
2222 }
2223
2224 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2225 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2226
2227 // Try to create target expression.
2228 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2229 return MipsMCExpr::Create(VK, Expr, getContext());
2230
2231 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2232 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2233 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2234 return Res;
2235 }
2236
2237 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2238 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2239 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2240 return Res;
2241 }
2242 // Just return the original expression.
2243 return Expr;
2244 }
2245
isEvaluated(const MCExpr * Expr)2246 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2247
2248 switch (Expr->getKind()) {
2249 case MCExpr::Constant:
2250 return true;
2251 case MCExpr::SymbolRef:
2252 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2253 case MCExpr::Binary:
2254 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2255 if (!isEvaluated(BE->getLHS()))
2256 return false;
2257 return isEvaluated(BE->getRHS());
2258 }
2259 case MCExpr::Unary:
2260 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2261 case MCExpr::Target:
2262 return true;
2263 }
2264 return false;
2265 }
2266
parseRelocOperand(const MCExpr * & Res)2267 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2268 MCAsmParser &Parser = getParser();
2269 Parser.Lex(); // Eat the % token.
2270 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2271 if (Tok.isNot(AsmToken::Identifier))
2272 return true;
2273
2274 std::string Str = Tok.getIdentifier().str();
2275
2276 Parser.Lex(); // Eat the identifier.
2277 // Now make an expression from the rest of the operand.
2278 const MCExpr *IdVal;
2279 SMLoc EndLoc;
2280
2281 if (getLexer().getKind() == AsmToken::LParen) {
2282 while (1) {
2283 Parser.Lex(); // Eat the '(' token.
2284 if (getLexer().getKind() == AsmToken::Percent) {
2285 Parser.Lex(); // Eat the % token.
2286 const AsmToken &nextTok = Parser.getTok();
2287 if (nextTok.isNot(AsmToken::Identifier))
2288 return true;
2289 Str += "(%";
2290 Str += nextTok.getIdentifier();
2291 Parser.Lex(); // Eat the identifier.
2292 if (getLexer().getKind() != AsmToken::LParen)
2293 return true;
2294 } else
2295 break;
2296 }
2297 if (getParser().parseParenExpression(IdVal, EndLoc))
2298 return true;
2299
2300 while (getLexer().getKind() == AsmToken::RParen)
2301 Parser.Lex(); // Eat the ')' token.
2302
2303 } else
2304 return true; // Parenthesis must follow the relocation operand.
2305
2306 Res = evaluateRelocExpr(IdVal, Str);
2307 return false;
2308 }
2309
ParseRegister(unsigned & RegNo,SMLoc & StartLoc,SMLoc & EndLoc)2310 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2311 SMLoc &EndLoc) {
2312 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2313 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2314 if (ResTy == MatchOperand_Success) {
2315 assert(Operands.size() == 1);
2316 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2317 StartLoc = Operand.getStartLoc();
2318 EndLoc = Operand.getEndLoc();
2319
2320 // AFAIK, we only support numeric registers and named GPR's in CFI
2321 // directives.
2322 // Don't worry about eating tokens before failing. Using an unrecognised
2323 // register is a parse error.
2324 if (Operand.isGPRAsmReg()) {
2325 // Resolve to GPR32 or GPR64 appropriately.
2326 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2327 }
2328
2329 return (RegNo == (unsigned)-1);
2330 }
2331
2332 assert(Operands.size() == 0);
2333 return (RegNo == (unsigned)-1);
2334 }
2335
parseMemOffset(const MCExpr * & Res,bool isParenExpr)2336 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2337 MCAsmParser &Parser = getParser();
2338 SMLoc S;
2339 bool Result = true;
2340
2341 while (getLexer().getKind() == AsmToken::LParen)
2342 Parser.Lex();
2343
2344 switch (getLexer().getKind()) {
2345 default:
2346 return true;
2347 case AsmToken::Identifier:
2348 case AsmToken::LParen:
2349 case AsmToken::Integer:
2350 case AsmToken::Minus:
2351 case AsmToken::Plus:
2352 if (isParenExpr)
2353 Result = getParser().parseParenExpression(Res, S);
2354 else
2355 Result = (getParser().parseExpression(Res));
2356 while (getLexer().getKind() == AsmToken::RParen)
2357 Parser.Lex();
2358 break;
2359 case AsmToken::Percent:
2360 Result = parseRelocOperand(Res);
2361 }
2362 return Result;
2363 }
2364
2365 MipsAsmParser::OperandMatchResultTy
parseMemOperand(OperandVector & Operands)2366 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2367 MCAsmParser &Parser = getParser();
2368 DEBUG(dbgs() << "parseMemOperand\n");
2369 const MCExpr *IdVal = nullptr;
2370 SMLoc S;
2371 bool isParenExpr = false;
2372 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2373 // First operand is the offset.
2374 S = Parser.getTok().getLoc();
2375
2376 if (getLexer().getKind() == AsmToken::LParen) {
2377 Parser.Lex();
2378 isParenExpr = true;
2379 }
2380
2381 if (getLexer().getKind() != AsmToken::Dollar) {
2382 if (parseMemOffset(IdVal, isParenExpr))
2383 return MatchOperand_ParseFail;
2384
2385 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2386 if (Tok.isNot(AsmToken::LParen)) {
2387 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2388 if (Mnemonic.getToken() == "la") {
2389 SMLoc E =
2390 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2391 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2392 return MatchOperand_Success;
2393 }
2394 if (Tok.is(AsmToken::EndOfStatement)) {
2395 SMLoc E =
2396 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2397
2398 // Zero register assumed, add a memory operand with ZERO as its base.
2399 // "Base" will be managed by k_Memory.
2400 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2401 S, E, *this);
2402 Operands.push_back(
2403 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2404 return MatchOperand_Success;
2405 }
2406 Error(Parser.getTok().getLoc(), "'(' expected");
2407 return MatchOperand_ParseFail;
2408 }
2409
2410 Parser.Lex(); // Eat the '(' token.
2411 }
2412
2413 Res = parseAnyRegister(Operands);
2414 if (Res != MatchOperand_Success)
2415 return Res;
2416
2417 if (Parser.getTok().isNot(AsmToken::RParen)) {
2418 Error(Parser.getTok().getLoc(), "')' expected");
2419 return MatchOperand_ParseFail;
2420 }
2421
2422 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2423
2424 Parser.Lex(); // Eat the ')' token.
2425
2426 if (!IdVal)
2427 IdVal = MCConstantExpr::Create(0, getContext());
2428
2429 // Replace the register operand with the memory operand.
2430 std::unique_ptr<MipsOperand> op(
2431 static_cast<MipsOperand *>(Operands.back().release()));
2432 // Remove the register from the operands.
2433 // "op" will be managed by k_Memory.
2434 Operands.pop_back();
2435 // Add the memory operand.
2436 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2437 int64_t Imm;
2438 if (IdVal->EvaluateAsAbsolute(Imm))
2439 IdVal = MCConstantExpr::Create(Imm, getContext());
2440 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2441 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2442 getContext());
2443 }
2444
2445 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2446 return MatchOperand_Success;
2447 }
2448
searchSymbolAlias(OperandVector & Operands)2449 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2450 MCAsmParser &Parser = getParser();
2451 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2452 if (Sym) {
2453 SMLoc S = Parser.getTok().getLoc();
2454 const MCExpr *Expr;
2455 if (Sym->isVariable())
2456 Expr = Sym->getVariableValue();
2457 else
2458 return false;
2459 if (Expr->getKind() == MCExpr::SymbolRef) {
2460 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2461 StringRef DefSymbol = Ref->getSymbol().getName();
2462 if (DefSymbol.startswith("$")) {
2463 OperandMatchResultTy ResTy =
2464 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2465 if (ResTy == MatchOperand_Success) {
2466 Parser.Lex();
2467 return true;
2468 } else if (ResTy == MatchOperand_ParseFail)
2469 llvm_unreachable("Should never ParseFail");
2470 return false;
2471 }
2472 } else if (Expr->getKind() == MCExpr::Constant) {
2473 Parser.Lex();
2474 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2475 Operands.push_back(
2476 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2477 return true;
2478 }
2479 }
2480 return false;
2481 }
2482
2483 MipsAsmParser::OperandMatchResultTy
matchAnyRegisterNameWithoutDollar(OperandVector & Operands,StringRef Identifier,SMLoc S)2484 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2485 StringRef Identifier,
2486 SMLoc S) {
2487 int Index = matchCPURegisterName(Identifier);
2488 if (Index != -1) {
2489 Operands.push_back(MipsOperand::createGPRReg(
2490 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2491 return MatchOperand_Success;
2492 }
2493
2494 Index = matchHWRegsRegisterName(Identifier);
2495 if (Index != -1) {
2496 Operands.push_back(MipsOperand::createHWRegsReg(
2497 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2498 return MatchOperand_Success;
2499 }
2500
2501 Index = matchFPURegisterName(Identifier);
2502 if (Index != -1) {
2503 Operands.push_back(MipsOperand::createFGRReg(
2504 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2505 return MatchOperand_Success;
2506 }
2507
2508 Index = matchFCCRegisterName(Identifier);
2509 if (Index != -1) {
2510 Operands.push_back(MipsOperand::createFCCReg(
2511 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2512 return MatchOperand_Success;
2513 }
2514
2515 Index = matchACRegisterName(Identifier);
2516 if (Index != -1) {
2517 Operands.push_back(MipsOperand::createACCReg(
2518 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2519 return MatchOperand_Success;
2520 }
2521
2522 Index = matchMSA128RegisterName(Identifier);
2523 if (Index != -1) {
2524 Operands.push_back(MipsOperand::createMSA128Reg(
2525 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2526 return MatchOperand_Success;
2527 }
2528
2529 Index = matchMSA128CtrlRegisterName(Identifier);
2530 if (Index != -1) {
2531 Operands.push_back(MipsOperand::createMSACtrlReg(
2532 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2533 return MatchOperand_Success;
2534 }
2535
2536 return MatchOperand_NoMatch;
2537 }
2538
2539 MipsAsmParser::OperandMatchResultTy
matchAnyRegisterWithoutDollar(OperandVector & Operands,SMLoc S)2540 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2541 MCAsmParser &Parser = getParser();
2542 auto Token = Parser.getLexer().peekTok(false);
2543
2544 if (Token.is(AsmToken::Identifier)) {
2545 DEBUG(dbgs() << ".. identifier\n");
2546 StringRef Identifier = Token.getIdentifier();
2547 OperandMatchResultTy ResTy =
2548 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2549 return ResTy;
2550 } else if (Token.is(AsmToken::Integer)) {
2551 DEBUG(dbgs() << ".. integer\n");
2552 Operands.push_back(MipsOperand::createNumericReg(
2553 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2554 *this));
2555 return MatchOperand_Success;
2556 }
2557
2558 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2559
2560 return MatchOperand_NoMatch;
2561 }
2562
2563 MipsAsmParser::OperandMatchResultTy
parseAnyRegister(OperandVector & Operands)2564 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2565 MCAsmParser &Parser = getParser();
2566 DEBUG(dbgs() << "parseAnyRegister\n");
2567
2568 auto Token = Parser.getTok();
2569
2570 SMLoc S = Token.getLoc();
2571
2572 if (Token.isNot(AsmToken::Dollar)) {
2573 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2574 if (Token.is(AsmToken::Identifier)) {
2575 if (searchSymbolAlias(Operands))
2576 return MatchOperand_Success;
2577 }
2578 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2579 return MatchOperand_NoMatch;
2580 }
2581 DEBUG(dbgs() << ".. $\n");
2582
2583 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2584 if (ResTy == MatchOperand_Success) {
2585 Parser.Lex(); // $
2586 Parser.Lex(); // identifier
2587 }
2588 return ResTy;
2589 }
2590
2591 MipsAsmParser::OperandMatchResultTy
parseImm(OperandVector & Operands)2592 MipsAsmParser::parseImm(OperandVector &Operands) {
2593 MCAsmParser &Parser = getParser();
2594 switch (getLexer().getKind()) {
2595 default:
2596 return MatchOperand_NoMatch;
2597 case AsmToken::LParen:
2598 case AsmToken::Minus:
2599 case AsmToken::Plus:
2600 case AsmToken::Integer:
2601 case AsmToken::Tilde:
2602 case AsmToken::String:
2603 break;
2604 }
2605
2606 const MCExpr *IdVal;
2607 SMLoc S = Parser.getTok().getLoc();
2608 if (getParser().parseExpression(IdVal))
2609 return MatchOperand_ParseFail;
2610
2611 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2612 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2613 return MatchOperand_Success;
2614 }
2615
2616 MipsAsmParser::OperandMatchResultTy
parseJumpTarget(OperandVector & Operands)2617 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2618 MCAsmParser &Parser = getParser();
2619 DEBUG(dbgs() << "parseJumpTarget\n");
2620
2621 SMLoc S = getLexer().getLoc();
2622
2623 // Integers and expressions are acceptable
2624 OperandMatchResultTy ResTy = parseImm(Operands);
2625 if (ResTy != MatchOperand_NoMatch)
2626 return ResTy;
2627
2628 // Registers are a valid target and have priority over symbols.
2629 ResTy = parseAnyRegister(Operands);
2630 if (ResTy != MatchOperand_NoMatch)
2631 return ResTy;
2632
2633 const MCExpr *Expr = nullptr;
2634 if (Parser.parseExpression(Expr)) {
2635 // We have no way of knowing if a symbol was consumed so we must ParseFail
2636 return MatchOperand_ParseFail;
2637 }
2638 Operands.push_back(
2639 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2640 return MatchOperand_Success;
2641 }
2642
2643 MipsAsmParser::OperandMatchResultTy
parseInvNum(OperandVector & Operands)2644 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2645 MCAsmParser &Parser = getParser();
2646 const MCExpr *IdVal;
2647 // If the first token is '$' we may have register operand.
2648 if (Parser.getTok().is(AsmToken::Dollar))
2649 return MatchOperand_NoMatch;
2650 SMLoc S = Parser.getTok().getLoc();
2651 if (getParser().parseExpression(IdVal))
2652 return MatchOperand_ParseFail;
2653 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2654 assert(MCE && "Unexpected MCExpr type.");
2655 int64_t Val = MCE->getValue();
2656 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2657 Operands.push_back(MipsOperand::CreateImm(
2658 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2659 return MatchOperand_Success;
2660 }
2661
2662 MipsAsmParser::OperandMatchResultTy
parseLSAImm(OperandVector & Operands)2663 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2664 MCAsmParser &Parser = getParser();
2665 switch (getLexer().getKind()) {
2666 default:
2667 return MatchOperand_NoMatch;
2668 case AsmToken::LParen:
2669 case AsmToken::Plus:
2670 case AsmToken::Minus:
2671 case AsmToken::Integer:
2672 break;
2673 }
2674
2675 const MCExpr *Expr;
2676 SMLoc S = Parser.getTok().getLoc();
2677
2678 if (getParser().parseExpression(Expr))
2679 return MatchOperand_ParseFail;
2680
2681 int64_t Val;
2682 if (!Expr->EvaluateAsAbsolute(Val)) {
2683 Error(S, "expected immediate value");
2684 return MatchOperand_ParseFail;
2685 }
2686
2687 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2688 // and because the CPU always adds one to the immediate field, the allowed
2689 // range becomes 1..4. We'll only check the range here and will deal
2690 // with the addition/subtraction when actually decoding/encoding
2691 // the instruction.
2692 if (Val < 1 || Val > 4) {
2693 Error(S, "immediate not in range (1..4)");
2694 return MatchOperand_ParseFail;
2695 }
2696
2697 Operands.push_back(
2698 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2699 return MatchOperand_Success;
2700 }
2701
2702 MipsAsmParser::OperandMatchResultTy
parseRegisterList(OperandVector & Operands)2703 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2704 MCAsmParser &Parser = getParser();
2705 SmallVector<unsigned, 10> Regs;
2706 unsigned RegNo;
2707 unsigned PrevReg = Mips::NoRegister;
2708 bool RegRange = false;
2709 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2710
2711 if (Parser.getTok().isNot(AsmToken::Dollar))
2712 return MatchOperand_ParseFail;
2713
2714 SMLoc S = Parser.getTok().getLoc();
2715 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2716 SMLoc E = getLexer().getLoc();
2717 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2718 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2719 if (RegRange) {
2720 // Remove last register operand because registers from register range
2721 // should be inserted first.
2722 if (RegNo == Mips::RA) {
2723 Regs.push_back(RegNo);
2724 } else {
2725 unsigned TmpReg = PrevReg + 1;
2726 while (TmpReg <= RegNo) {
2727 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2728 Error(E, "invalid register operand");
2729 return MatchOperand_ParseFail;
2730 }
2731
2732 PrevReg = TmpReg;
2733 Regs.push_back(TmpReg++);
2734 }
2735 }
2736
2737 RegRange = false;
2738 } else {
2739 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2740 (RegNo != Mips::RA)) {
2741 Error(E, "$16 or $31 expected");
2742 return MatchOperand_ParseFail;
2743 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2744 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2745 Error(E, "invalid register operand");
2746 return MatchOperand_ParseFail;
2747 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2748 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2749 Error(E, "consecutive register numbers expected");
2750 return MatchOperand_ParseFail;
2751 }
2752
2753 Regs.push_back(RegNo);
2754 }
2755
2756 if (Parser.getTok().is(AsmToken::Minus))
2757 RegRange = true;
2758
2759 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2760 !Parser.getTok().isNot(AsmToken::Comma)) {
2761 Error(E, "',' or '-' expected");
2762 return MatchOperand_ParseFail;
2763 }
2764
2765 Lex(); // Consume comma or minus
2766 if (Parser.getTok().isNot(AsmToken::Dollar))
2767 break;
2768
2769 PrevReg = RegNo;
2770 }
2771
2772 SMLoc E = Parser.getTok().getLoc();
2773 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2774 parseMemOperand(Operands);
2775 return MatchOperand_Success;
2776 }
2777
2778 MipsAsmParser::OperandMatchResultTy
parseRegisterPair(OperandVector & Operands)2779 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
2780 MCAsmParser &Parser = getParser();
2781
2782 SMLoc S = Parser.getTok().getLoc();
2783 if (parseAnyRegister(Operands) != MatchOperand_Success)
2784 return MatchOperand_ParseFail;
2785
2786 SMLoc E = Parser.getTok().getLoc();
2787 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
2788 unsigned Reg = Op.getGPR32Reg();
2789 Operands.pop_back();
2790 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
2791 return MatchOperand_Success;
2792 }
2793
getVariantKind(StringRef Symbol)2794 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2795
2796 MCSymbolRefExpr::VariantKind VK =
2797 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2798 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2799 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2800 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2801 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2802 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2803 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2804 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2805 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2806 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2807 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2808 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2809 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2810 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2811 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2812 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2813 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2814 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2815 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2816 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2817 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2818 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2819 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2820 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2821 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2822 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2823 .Default(MCSymbolRefExpr::VK_None);
2824
2825 assert(VK != MCSymbolRefExpr::VK_None);
2826
2827 return VK;
2828 }
2829
2830 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2831 /// either this.
2832 /// ::= '(', register, ')'
2833 /// handle it before we iterate so we don't get tripped up by the lack of
2834 /// a comma.
parseParenSuffix(StringRef Name,OperandVector & Operands)2835 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2836 MCAsmParser &Parser = getParser();
2837 if (getLexer().is(AsmToken::LParen)) {
2838 Operands.push_back(
2839 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2840 Parser.Lex();
2841 if (parseOperand(Operands, Name)) {
2842 SMLoc Loc = getLexer().getLoc();
2843 Parser.eatToEndOfStatement();
2844 return Error(Loc, "unexpected token in argument list");
2845 }
2846 if (Parser.getTok().isNot(AsmToken::RParen)) {
2847 SMLoc Loc = getLexer().getLoc();
2848 Parser.eatToEndOfStatement();
2849 return Error(Loc, "unexpected token, expected ')'");
2850 }
2851 Operands.push_back(
2852 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2853 Parser.Lex();
2854 }
2855 return false;
2856 }
2857
2858 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2859 /// either one of these.
2860 /// ::= '[', register, ']'
2861 /// ::= '[', integer, ']'
2862 /// handle it before we iterate so we don't get tripped up by the lack of
2863 /// a comma.
parseBracketSuffix(StringRef Name,OperandVector & Operands)2864 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2865 OperandVector &Operands) {
2866 MCAsmParser &Parser = getParser();
2867 if (getLexer().is(AsmToken::LBrac)) {
2868 Operands.push_back(
2869 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2870 Parser.Lex();
2871 if (parseOperand(Operands, Name)) {
2872 SMLoc Loc = getLexer().getLoc();
2873 Parser.eatToEndOfStatement();
2874 return Error(Loc, "unexpected token in argument list");
2875 }
2876 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2877 SMLoc Loc = getLexer().getLoc();
2878 Parser.eatToEndOfStatement();
2879 return Error(Loc, "unexpected token, expected ']'");
2880 }
2881 Operands.push_back(
2882 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2883 Parser.Lex();
2884 }
2885 return false;
2886 }
2887
ParseInstruction(ParseInstructionInfo & Info,StringRef Name,SMLoc NameLoc,OperandVector & Operands)2888 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2889 SMLoc NameLoc, OperandVector &Operands) {
2890 MCAsmParser &Parser = getParser();
2891 DEBUG(dbgs() << "ParseInstruction\n");
2892
2893 // We have reached first instruction, module directive are now forbidden.
2894 getTargetStreamer().forbidModuleDirective();
2895
2896 // Check if we have valid mnemonic
2897 if (!mnemonicIsValid(Name, 0)) {
2898 Parser.eatToEndOfStatement();
2899 return Error(NameLoc, "unknown instruction");
2900 }
2901 // First operand in MCInst is instruction mnemonic.
2902 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2903
2904 // Read the remaining operands.
2905 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2906 // Read the first operand.
2907 if (parseOperand(Operands, Name)) {
2908 SMLoc Loc = getLexer().getLoc();
2909 Parser.eatToEndOfStatement();
2910 return Error(Loc, "unexpected token in argument list");
2911 }
2912 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2913 return true;
2914 // AFAIK, parenthesis suffixes are never on the first operand
2915
2916 while (getLexer().is(AsmToken::Comma)) {
2917 Parser.Lex(); // Eat the comma.
2918 // Parse and remember the operand.
2919 if (parseOperand(Operands, Name)) {
2920 SMLoc Loc = getLexer().getLoc();
2921 Parser.eatToEndOfStatement();
2922 return Error(Loc, "unexpected token in argument list");
2923 }
2924 // Parse bracket and parenthesis suffixes before we iterate
2925 if (getLexer().is(AsmToken::LBrac)) {
2926 if (parseBracketSuffix(Name, Operands))
2927 return true;
2928 } else if (getLexer().is(AsmToken::LParen) &&
2929 parseParenSuffix(Name, Operands))
2930 return true;
2931 }
2932 }
2933 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2934 SMLoc Loc = getLexer().getLoc();
2935 Parser.eatToEndOfStatement();
2936 return Error(Loc, "unexpected token in argument list");
2937 }
2938 Parser.Lex(); // Consume the EndOfStatement.
2939 return false;
2940 }
2941
reportParseError(Twine ErrorMsg)2942 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2943 MCAsmParser &Parser = getParser();
2944 SMLoc Loc = getLexer().getLoc();
2945 Parser.eatToEndOfStatement();
2946 return Error(Loc, ErrorMsg);
2947 }
2948
reportParseError(SMLoc Loc,Twine ErrorMsg)2949 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2950 return Error(Loc, ErrorMsg);
2951 }
2952
parseSetNoAtDirective()2953 bool MipsAsmParser::parseSetNoAtDirective() {
2954 MCAsmParser &Parser = getParser();
2955 // Line should look like: ".set noat".
2956 // set at reg to 0.
2957 AssemblerOptions.back()->setATReg(0);
2958 // eat noat
2959 Parser.Lex();
2960 // If this is not the end of the statement, report an error.
2961 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2962 reportParseError("unexpected token, expected end of statement");
2963 return false;
2964 }
2965 Parser.Lex(); // Consume the EndOfStatement.
2966 return false;
2967 }
2968
parseSetAtDirective()2969 bool MipsAsmParser::parseSetAtDirective() {
2970 MCAsmParser &Parser = getParser();
2971 // Line can be .set at - defaults to $1
2972 // or .set at=$reg
2973 int AtRegNo;
2974 getParser().Lex();
2975 if (getLexer().is(AsmToken::EndOfStatement)) {
2976 AssemblerOptions.back()->setATReg(1);
2977 Parser.Lex(); // Consume the EndOfStatement.
2978 return false;
2979 } else if (getLexer().is(AsmToken::Equal)) {
2980 getParser().Lex(); // Eat the '='.
2981 if (getLexer().isNot(AsmToken::Dollar)) {
2982 reportParseError("unexpected token, expected dollar sign '$'");
2983 return false;
2984 }
2985 Parser.Lex(); // Eat the '$'.
2986 const AsmToken &Reg = Parser.getTok();
2987 if (Reg.is(AsmToken::Identifier)) {
2988 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2989 } else if (Reg.is(AsmToken::Integer)) {
2990 AtRegNo = Reg.getIntVal();
2991 } else {
2992 reportParseError("unexpected token, expected identifier or integer");
2993 return false;
2994 }
2995
2996 if (AtRegNo < 0 || AtRegNo > 31) {
2997 reportParseError("unexpected token in statement");
2998 return false;
2999 }
3000
3001 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3002 reportParseError("invalid register");
3003 return false;
3004 }
3005 getParser().Lex(); // Eat the register.
3006
3007 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3008 reportParseError("unexpected token, expected end of statement");
3009 return false;
3010 }
3011 Parser.Lex(); // Consume the EndOfStatement.
3012 return false;
3013 } else {
3014 reportParseError("unexpected token in statement");
3015 return false;
3016 }
3017 }
3018
parseSetReorderDirective()3019 bool MipsAsmParser::parseSetReorderDirective() {
3020 MCAsmParser &Parser = getParser();
3021 Parser.Lex();
3022 // If this is not the end of the statement, report an error.
3023 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3024 reportParseError("unexpected token, expected end of statement");
3025 return false;
3026 }
3027 AssemblerOptions.back()->setReorder();
3028 getTargetStreamer().emitDirectiveSetReorder();
3029 Parser.Lex(); // Consume the EndOfStatement.
3030 return false;
3031 }
3032
parseSetNoReorderDirective()3033 bool MipsAsmParser::parseSetNoReorderDirective() {
3034 MCAsmParser &Parser = getParser();
3035 Parser.Lex();
3036 // If this is not the end of the statement, report an error.
3037 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3038 reportParseError("unexpected token, expected end of statement");
3039 return false;
3040 }
3041 AssemblerOptions.back()->setNoReorder();
3042 getTargetStreamer().emitDirectiveSetNoReorder();
3043 Parser.Lex(); // Consume the EndOfStatement.
3044 return false;
3045 }
3046
parseSetMacroDirective()3047 bool MipsAsmParser::parseSetMacroDirective() {
3048 MCAsmParser &Parser = getParser();
3049 Parser.Lex();
3050 // If this is not the end of the statement, report an error.
3051 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3052 reportParseError("unexpected token, expected end of statement");
3053 return false;
3054 }
3055 AssemblerOptions.back()->setMacro();
3056 Parser.Lex(); // Consume the EndOfStatement.
3057 return false;
3058 }
3059
parseSetNoMacroDirective()3060 bool MipsAsmParser::parseSetNoMacroDirective() {
3061 MCAsmParser &Parser = getParser();
3062 Parser.Lex();
3063 // If this is not the end of the statement, report an error.
3064 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3065 reportParseError("unexpected token, expected end of statement");
3066 return false;
3067 }
3068 if (AssemblerOptions.back()->isReorder()) {
3069 reportParseError("`noreorder' must be set before `nomacro'");
3070 return false;
3071 }
3072 AssemblerOptions.back()->setNoMacro();
3073 Parser.Lex(); // Consume the EndOfStatement.
3074 return false;
3075 }
3076
parseSetMsaDirective()3077 bool MipsAsmParser::parseSetMsaDirective() {
3078 MCAsmParser &Parser = getParser();
3079 Parser.Lex();
3080
3081 // If this is not the end of the statement, report an error.
3082 if (getLexer().isNot(AsmToken::EndOfStatement))
3083 return reportParseError("unexpected token, expected end of statement");
3084
3085 setFeatureBits(Mips::FeatureMSA, "msa");
3086 getTargetStreamer().emitDirectiveSetMsa();
3087 return false;
3088 }
3089
parseSetNoMsaDirective()3090 bool MipsAsmParser::parseSetNoMsaDirective() {
3091 MCAsmParser &Parser = getParser();
3092 Parser.Lex();
3093
3094 // If this is not the end of the statement, report an error.
3095 if (getLexer().isNot(AsmToken::EndOfStatement))
3096 return reportParseError("unexpected token, expected end of statement");
3097
3098 clearFeatureBits(Mips::FeatureMSA, "msa");
3099 getTargetStreamer().emitDirectiveSetNoMsa();
3100 return false;
3101 }
3102
parseSetNoDspDirective()3103 bool MipsAsmParser::parseSetNoDspDirective() {
3104 MCAsmParser &Parser = getParser();
3105 Parser.Lex(); // Eat "nodsp".
3106
3107 // If this is not the end of the statement, report an error.
3108 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3109 reportParseError("unexpected token, expected end of statement");
3110 return false;
3111 }
3112
3113 clearFeatureBits(Mips::FeatureDSP, "dsp");
3114 getTargetStreamer().emitDirectiveSetNoDsp();
3115 return false;
3116 }
3117
parseSetMips16Directive()3118 bool MipsAsmParser::parseSetMips16Directive() {
3119 MCAsmParser &Parser = getParser();
3120 Parser.Lex(); // Eat "mips16".
3121
3122 // If this is not the end of the statement, report an error.
3123 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3124 reportParseError("unexpected token, expected end of statement");
3125 return false;
3126 }
3127
3128 setFeatureBits(Mips::FeatureMips16, "mips16");
3129 getTargetStreamer().emitDirectiveSetMips16();
3130 Parser.Lex(); // Consume the EndOfStatement.
3131 return false;
3132 }
3133
parseSetNoMips16Directive()3134 bool MipsAsmParser::parseSetNoMips16Directive() {
3135 MCAsmParser &Parser = getParser();
3136 Parser.Lex(); // Eat "nomips16".
3137
3138 // If this is not the end of the statement, report an error.
3139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3140 reportParseError("unexpected token, expected end of statement");
3141 return false;
3142 }
3143
3144 clearFeatureBits(Mips::FeatureMips16, "mips16");
3145 getTargetStreamer().emitDirectiveSetNoMips16();
3146 Parser.Lex(); // Consume the EndOfStatement.
3147 return false;
3148 }
3149
parseSetFpDirective()3150 bool MipsAsmParser::parseSetFpDirective() {
3151 MCAsmParser &Parser = getParser();
3152 MipsABIFlagsSection::FpABIKind FpAbiVal;
3153 // Line can be: .set fp=32
3154 // .set fp=xx
3155 // .set fp=64
3156 Parser.Lex(); // Eat fp token
3157 AsmToken Tok = Parser.getTok();
3158 if (Tok.isNot(AsmToken::Equal)) {
3159 reportParseError("unexpected token, expected equals sign '='");
3160 return false;
3161 }
3162 Parser.Lex(); // Eat '=' token.
3163 Tok = Parser.getTok();
3164
3165 if (!parseFpABIValue(FpAbiVal, ".set"))
3166 return false;
3167
3168 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3169 reportParseError("unexpected token, expected end of statement");
3170 return false;
3171 }
3172 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3173 Parser.Lex(); // Consume the EndOfStatement.
3174 return false;
3175 }
3176
parseSetPopDirective()3177 bool MipsAsmParser::parseSetPopDirective() {
3178 MCAsmParser &Parser = getParser();
3179 SMLoc Loc = getLexer().getLoc();
3180
3181 Parser.Lex();
3182 if (getLexer().isNot(AsmToken::EndOfStatement))
3183 return reportParseError("unexpected token, expected end of statement");
3184
3185 // Always keep an element on the options "stack" to prevent the user
3186 // from changing the initial options. This is how we remember them.
3187 if (AssemblerOptions.size() == 2)
3188 return reportParseError(Loc, ".set pop with no .set push");
3189
3190 AssemblerOptions.pop_back();
3191 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3192
3193 getTargetStreamer().emitDirectiveSetPop();
3194 return false;
3195 }
3196
parseSetPushDirective()3197 bool MipsAsmParser::parseSetPushDirective() {
3198 MCAsmParser &Parser = getParser();
3199 Parser.Lex();
3200 if (getLexer().isNot(AsmToken::EndOfStatement))
3201 return reportParseError("unexpected token, expected end of statement");
3202
3203 // Create a copy of the current assembler options environment and push it.
3204 AssemblerOptions.push_back(
3205 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3206
3207 getTargetStreamer().emitDirectiveSetPush();
3208 return false;
3209 }
3210
parseSetAssignment()3211 bool MipsAsmParser::parseSetAssignment() {
3212 StringRef Name;
3213 const MCExpr *Value;
3214 MCAsmParser &Parser = getParser();
3215
3216 if (Parser.parseIdentifier(Name))
3217 reportParseError("expected identifier after .set");
3218
3219 if (getLexer().isNot(AsmToken::Comma))
3220 return reportParseError("unexpected token, expected comma");
3221 Lex(); // Eat comma
3222
3223 if (Parser.parseExpression(Value))
3224 return reportParseError("expected valid expression after comma");
3225
3226 // Check if the Name already exists as a symbol.
3227 MCSymbol *Sym = getContext().LookupSymbol(Name);
3228 if (Sym)
3229 return reportParseError("symbol already defined");
3230 Sym = getContext().GetOrCreateSymbol(Name);
3231 Sym->setVariableValue(Value);
3232
3233 return false;
3234 }
3235
parseSetMips0Directive()3236 bool MipsAsmParser::parseSetMips0Directive() {
3237 MCAsmParser &Parser = getParser();
3238 Parser.Lex();
3239 if (getLexer().isNot(AsmToken::EndOfStatement))
3240 return reportParseError("unexpected token, expected end of statement");
3241
3242 // Reset assembler options to their initial values.
3243 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3244 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3245
3246 getTargetStreamer().emitDirectiveSetMips0();
3247 return false;
3248 }
3249
parseSetArchDirective()3250 bool MipsAsmParser::parseSetArchDirective() {
3251 MCAsmParser &Parser = getParser();
3252 Parser.Lex();
3253 if (getLexer().isNot(AsmToken::Equal))
3254 return reportParseError("unexpected token, expected equals sign");
3255
3256 Parser.Lex();
3257 StringRef Arch;
3258 if (Parser.parseIdentifier(Arch))
3259 return reportParseError("expected arch identifier");
3260
3261 StringRef ArchFeatureName =
3262 StringSwitch<StringRef>(Arch)
3263 .Case("mips1", "mips1")
3264 .Case("mips2", "mips2")
3265 .Case("mips3", "mips3")
3266 .Case("mips4", "mips4")
3267 .Case("mips5", "mips5")
3268 .Case("mips32", "mips32")
3269 .Case("mips32r2", "mips32r2")
3270 .Case("mips32r6", "mips32r6")
3271 .Case("mips64", "mips64")
3272 .Case("mips64r2", "mips64r2")
3273 .Case("mips64r6", "mips64r6")
3274 .Case("cnmips", "cnmips")
3275 .Case("r4000", "mips3") // This is an implementation of Mips3.
3276 .Default("");
3277
3278 if (ArchFeatureName.empty())
3279 return reportParseError("unsupported architecture");
3280
3281 selectArch(ArchFeatureName);
3282 getTargetStreamer().emitDirectiveSetArch(Arch);
3283 return false;
3284 }
3285
parseSetFeature(uint64_t Feature)3286 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3287 MCAsmParser &Parser = getParser();
3288 Parser.Lex();
3289 if (getLexer().isNot(AsmToken::EndOfStatement))
3290 return reportParseError("unexpected token, expected end of statement");
3291
3292 switch (Feature) {
3293 default:
3294 llvm_unreachable("Unimplemented feature");
3295 case Mips::FeatureDSP:
3296 setFeatureBits(Mips::FeatureDSP, "dsp");
3297 getTargetStreamer().emitDirectiveSetDsp();
3298 break;
3299 case Mips::FeatureMicroMips:
3300 getTargetStreamer().emitDirectiveSetMicroMips();
3301 break;
3302 case Mips::FeatureMips1:
3303 selectArch("mips1");
3304 getTargetStreamer().emitDirectiveSetMips1();
3305 break;
3306 case Mips::FeatureMips2:
3307 selectArch("mips2");
3308 getTargetStreamer().emitDirectiveSetMips2();
3309 break;
3310 case Mips::FeatureMips3:
3311 selectArch("mips3");
3312 getTargetStreamer().emitDirectiveSetMips3();
3313 break;
3314 case Mips::FeatureMips4:
3315 selectArch("mips4");
3316 getTargetStreamer().emitDirectiveSetMips4();
3317 break;
3318 case Mips::FeatureMips5:
3319 selectArch("mips5");
3320 getTargetStreamer().emitDirectiveSetMips5();
3321 break;
3322 case Mips::FeatureMips32:
3323 selectArch("mips32");
3324 getTargetStreamer().emitDirectiveSetMips32();
3325 break;
3326 case Mips::FeatureMips32r2:
3327 selectArch("mips32r2");
3328 getTargetStreamer().emitDirectiveSetMips32R2();
3329 break;
3330 case Mips::FeatureMips32r6:
3331 selectArch("mips32r6");
3332 getTargetStreamer().emitDirectiveSetMips32R6();
3333 break;
3334 case Mips::FeatureMips64:
3335 selectArch("mips64");
3336 getTargetStreamer().emitDirectiveSetMips64();
3337 break;
3338 case Mips::FeatureMips64r2:
3339 selectArch("mips64r2");
3340 getTargetStreamer().emitDirectiveSetMips64R2();
3341 break;
3342 case Mips::FeatureMips64r6:
3343 selectArch("mips64r6");
3344 getTargetStreamer().emitDirectiveSetMips64R6();
3345 break;
3346 }
3347 return false;
3348 }
3349
eatComma(StringRef ErrorStr)3350 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3351 MCAsmParser &Parser = getParser();
3352 if (getLexer().isNot(AsmToken::Comma)) {
3353 SMLoc Loc = getLexer().getLoc();
3354 Parser.eatToEndOfStatement();
3355 return Error(Loc, ErrorStr);
3356 }
3357
3358 Parser.Lex(); // Eat the comma.
3359 return true;
3360 }
3361
parseDirectiveCpLoad(SMLoc Loc)3362 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3363 if (AssemblerOptions.back()->isReorder())
3364 Warning(Loc, ".cpload should be inside a noreorder section");
3365
3366 if (inMips16Mode()) {
3367 reportParseError(".cpload is not supported in Mips16 mode");
3368 return false;
3369 }
3370
3371 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3372 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3373 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3374 reportParseError("expected register containing function address");
3375 return false;
3376 }
3377
3378 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3379 if (!RegOpnd.isGPRAsmReg()) {
3380 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3381 return false;
3382 }
3383
3384 // If this is not the end of the statement, report an error.
3385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3386 reportParseError("unexpected token, expected end of statement");
3387 return false;
3388 }
3389
3390 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3391 return false;
3392 }
3393
parseDirectiveCPSetup()3394 bool MipsAsmParser::parseDirectiveCPSetup() {
3395 MCAsmParser &Parser = getParser();
3396 unsigned FuncReg;
3397 unsigned Save;
3398 bool SaveIsReg = true;
3399
3400 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3401 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3402 if (ResTy == MatchOperand_NoMatch) {
3403 reportParseError("expected register containing function address");
3404 Parser.eatToEndOfStatement();
3405 return false;
3406 }
3407
3408 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3409 if (!FuncRegOpnd.isGPRAsmReg()) {
3410 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3411 Parser.eatToEndOfStatement();
3412 return false;
3413 }
3414
3415 FuncReg = FuncRegOpnd.getGPR32Reg();
3416 TmpReg.clear();
3417
3418 if (!eatComma("unexpected token, expected comma"))
3419 return true;
3420
3421 ResTy = parseAnyRegister(TmpReg);
3422 if (ResTy == MatchOperand_NoMatch) {
3423 const AsmToken &Tok = Parser.getTok();
3424 if (Tok.is(AsmToken::Integer)) {
3425 Save = Tok.getIntVal();
3426 SaveIsReg = false;
3427 Parser.Lex();
3428 } else {
3429 reportParseError("expected save register or stack offset");
3430 Parser.eatToEndOfStatement();
3431 return false;
3432 }
3433 } else {
3434 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3435 if (!SaveOpnd.isGPRAsmReg()) {
3436 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3437 Parser.eatToEndOfStatement();
3438 return false;
3439 }
3440 Save = SaveOpnd.getGPR32Reg();
3441 }
3442
3443 if (!eatComma("unexpected token, expected comma"))
3444 return true;
3445
3446 StringRef Name;
3447 if (Parser.parseIdentifier(Name))
3448 reportParseError("expected identifier");
3449 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3450
3451 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3452 return false;
3453 }
3454
parseDirectiveNaN()3455 bool MipsAsmParser::parseDirectiveNaN() {
3456 MCAsmParser &Parser = getParser();
3457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3458 const AsmToken &Tok = Parser.getTok();
3459
3460 if (Tok.getString() == "2008") {
3461 Parser.Lex();
3462 getTargetStreamer().emitDirectiveNaN2008();
3463 return false;
3464 } else if (Tok.getString() == "legacy") {
3465 Parser.Lex();
3466 getTargetStreamer().emitDirectiveNaNLegacy();
3467 return false;
3468 }
3469 }
3470 // If we don't recognize the option passed to the .nan
3471 // directive (e.g. no option or unknown option), emit an error.
3472 reportParseError("invalid option in .nan directive");
3473 return false;
3474 }
3475
parseDirectiveSet()3476 bool MipsAsmParser::parseDirectiveSet() {
3477 MCAsmParser &Parser = getParser();
3478 // Get the next token.
3479 const AsmToken &Tok = Parser.getTok();
3480
3481 if (Tok.getString() == "noat") {
3482 return parseSetNoAtDirective();
3483 } else if (Tok.getString() == "at") {
3484 return parseSetAtDirective();
3485 } else if (Tok.getString() == "arch") {
3486 return parseSetArchDirective();
3487 } else if (Tok.getString() == "fp") {
3488 return parseSetFpDirective();
3489 } else if (Tok.getString() == "pop") {
3490 return parseSetPopDirective();
3491 } else if (Tok.getString() == "push") {
3492 return parseSetPushDirective();
3493 } else if (Tok.getString() == "reorder") {
3494 return parseSetReorderDirective();
3495 } else if (Tok.getString() == "noreorder") {
3496 return parseSetNoReorderDirective();
3497 } else if (Tok.getString() == "macro") {
3498 return parseSetMacroDirective();
3499 } else if (Tok.getString() == "nomacro") {
3500 return parseSetNoMacroDirective();
3501 } else if (Tok.getString() == "mips16") {
3502 return parseSetMips16Directive();
3503 } else if (Tok.getString() == "nomips16") {
3504 return parseSetNoMips16Directive();
3505 } else if (Tok.getString() == "nomicromips") {
3506 getTargetStreamer().emitDirectiveSetNoMicroMips();
3507 Parser.eatToEndOfStatement();
3508 return false;
3509 } else if (Tok.getString() == "micromips") {
3510 return parseSetFeature(Mips::FeatureMicroMips);
3511 } else if (Tok.getString() == "mips0") {
3512 return parseSetMips0Directive();
3513 } else if (Tok.getString() == "mips1") {
3514 return parseSetFeature(Mips::FeatureMips1);
3515 } else if (Tok.getString() == "mips2") {
3516 return parseSetFeature(Mips::FeatureMips2);
3517 } else if (Tok.getString() == "mips3") {
3518 return parseSetFeature(Mips::FeatureMips3);
3519 } else if (Tok.getString() == "mips4") {
3520 return parseSetFeature(Mips::FeatureMips4);
3521 } else if (Tok.getString() == "mips5") {
3522 return parseSetFeature(Mips::FeatureMips5);
3523 } else if (Tok.getString() == "mips32") {
3524 return parseSetFeature(Mips::FeatureMips32);
3525 } else if (Tok.getString() == "mips32r2") {
3526 return parseSetFeature(Mips::FeatureMips32r2);
3527 } else if (Tok.getString() == "mips32r6") {
3528 return parseSetFeature(Mips::FeatureMips32r6);
3529 } else if (Tok.getString() == "mips64") {
3530 return parseSetFeature(Mips::FeatureMips64);
3531 } else if (Tok.getString() == "mips64r2") {
3532 return parseSetFeature(Mips::FeatureMips64r2);
3533 } else if (Tok.getString() == "mips64r6") {
3534 return parseSetFeature(Mips::FeatureMips64r6);
3535 } else if (Tok.getString() == "dsp") {
3536 return parseSetFeature(Mips::FeatureDSP);
3537 } else if (Tok.getString() == "nodsp") {
3538 return parseSetNoDspDirective();
3539 } else if (Tok.getString() == "msa") {
3540 return parseSetMsaDirective();
3541 } else if (Tok.getString() == "nomsa") {
3542 return parseSetNoMsaDirective();
3543 } else {
3544 // It is just an identifier, look for an assignment.
3545 parseSetAssignment();
3546 return false;
3547 }
3548
3549 return true;
3550 }
3551
3552 /// parseDataDirective
3553 /// ::= .word [ expression (, expression)* ]
parseDataDirective(unsigned Size,SMLoc L)3554 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3555 MCAsmParser &Parser = getParser();
3556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3557 for (;;) {
3558 const MCExpr *Value;
3559 if (getParser().parseExpression(Value))
3560 return true;
3561
3562 getParser().getStreamer().EmitValue(Value, Size);
3563
3564 if (getLexer().is(AsmToken::EndOfStatement))
3565 break;
3566
3567 if (getLexer().isNot(AsmToken::Comma))
3568 return Error(L, "unexpected token, expected comma");
3569 Parser.Lex();
3570 }
3571 }
3572
3573 Parser.Lex();
3574 return false;
3575 }
3576
3577 /// parseDirectiveGpWord
3578 /// ::= .gpword local_sym
parseDirectiveGpWord()3579 bool MipsAsmParser::parseDirectiveGpWord() {
3580 MCAsmParser &Parser = getParser();
3581 const MCExpr *Value;
3582 // EmitGPRel32Value requires an expression, so we are using base class
3583 // method to evaluate the expression.
3584 if (getParser().parseExpression(Value))
3585 return true;
3586 getParser().getStreamer().EmitGPRel32Value(Value);
3587
3588 if (getLexer().isNot(AsmToken::EndOfStatement))
3589 return Error(getLexer().getLoc(),
3590 "unexpected token, expected end of statement");
3591 Parser.Lex(); // Eat EndOfStatement token.
3592 return false;
3593 }
3594
3595 /// parseDirectiveGpDWord
3596 /// ::= .gpdword local_sym
parseDirectiveGpDWord()3597 bool MipsAsmParser::parseDirectiveGpDWord() {
3598 MCAsmParser &Parser = getParser();
3599 const MCExpr *Value;
3600 // EmitGPRel64Value requires an expression, so we are using base class
3601 // method to evaluate the expression.
3602 if (getParser().parseExpression(Value))
3603 return true;
3604 getParser().getStreamer().EmitGPRel64Value(Value);
3605
3606 if (getLexer().isNot(AsmToken::EndOfStatement))
3607 return Error(getLexer().getLoc(),
3608 "unexpected token, expected end of statement");
3609 Parser.Lex(); // Eat EndOfStatement token.
3610 return false;
3611 }
3612
parseDirectiveOption()3613 bool MipsAsmParser::parseDirectiveOption() {
3614 MCAsmParser &Parser = getParser();
3615 // Get the option token.
3616 AsmToken Tok = Parser.getTok();
3617 // At the moment only identifiers are supported.
3618 if (Tok.isNot(AsmToken::Identifier)) {
3619 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3620 Parser.eatToEndOfStatement();
3621 return false;
3622 }
3623
3624 StringRef Option = Tok.getIdentifier();
3625
3626 if (Option == "pic0") {
3627 getTargetStreamer().emitDirectiveOptionPic0();
3628 Parser.Lex();
3629 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3630 Error(Parser.getTok().getLoc(),
3631 "unexpected token, expected end of statement");
3632 Parser.eatToEndOfStatement();
3633 }
3634 return false;
3635 }
3636
3637 if (Option == "pic2") {
3638 getTargetStreamer().emitDirectiveOptionPic2();
3639 Parser.Lex();
3640 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3641 Error(Parser.getTok().getLoc(),
3642 "unexpected token, expected end of statement");
3643 Parser.eatToEndOfStatement();
3644 }
3645 return false;
3646 }
3647
3648 // Unknown option.
3649 Warning(Parser.getTok().getLoc(),
3650 "unknown option, expected 'pic0' or 'pic2'");
3651 Parser.eatToEndOfStatement();
3652 return false;
3653 }
3654
3655 /// parseDirectiveModule
3656 /// ::= .module oddspreg
3657 /// ::= .module nooddspreg
3658 /// ::= .module fp=value
parseDirectiveModule()3659 bool MipsAsmParser::parseDirectiveModule() {
3660 MCAsmParser &Parser = getParser();
3661 MCAsmLexer &Lexer = getLexer();
3662 SMLoc L = Lexer.getLoc();
3663
3664 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3665 // TODO : get a better message.
3666 reportParseError(".module directive must appear before any code");
3667 return false;
3668 }
3669
3670 StringRef Option;
3671 if (Parser.parseIdentifier(Option)) {
3672 reportParseError("expected .module option identifier");
3673 return false;
3674 }
3675
3676 if (Option == "oddspreg") {
3677 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3678 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3679
3680 // If this is not the end of the statement, report an error.
3681 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3682 reportParseError("unexpected token, expected end of statement");
3683 return false;
3684 }
3685
3686 return false; // parseDirectiveModule has finished successfully.
3687 } else if (Option == "nooddspreg") {
3688 if (!isABI_O32()) {
3689 Error(L, "'.module nooddspreg' requires the O32 ABI");
3690 return false;
3691 }
3692
3693 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3694 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3695
3696 // If this is not the end of the statement, report an error.
3697 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3698 reportParseError("unexpected token, expected end of statement");
3699 return false;
3700 }
3701
3702 return false; // parseDirectiveModule has finished successfully.
3703 } else if (Option == "fp") {
3704 return parseDirectiveModuleFP();
3705 } else {
3706 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3707 }
3708 }
3709
3710 /// parseDirectiveModuleFP
3711 /// ::= =32
3712 /// ::= =xx
3713 /// ::= =64
parseDirectiveModuleFP()3714 bool MipsAsmParser::parseDirectiveModuleFP() {
3715 MCAsmParser &Parser = getParser();
3716 MCAsmLexer &Lexer = getLexer();
3717
3718 if (Lexer.isNot(AsmToken::Equal)) {
3719 reportParseError("unexpected token, expected equals sign '='");
3720 return false;
3721 }
3722 Parser.Lex(); // Eat '=' token.
3723
3724 MipsABIFlagsSection::FpABIKind FpABI;
3725 if (!parseFpABIValue(FpABI, ".module"))
3726 return false;
3727
3728 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3729 reportParseError("unexpected token, expected end of statement");
3730 return false;
3731 }
3732
3733 // Emit appropriate flags.
3734 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3735 Parser.Lex(); // Consume the EndOfStatement.
3736 return false;
3737 }
3738
parseFpABIValue(MipsABIFlagsSection::FpABIKind & FpABI,StringRef Directive)3739 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3740 StringRef Directive) {
3741 MCAsmParser &Parser = getParser();
3742 MCAsmLexer &Lexer = getLexer();
3743
3744 if (Lexer.is(AsmToken::Identifier)) {
3745 StringRef Value = Parser.getTok().getString();
3746 Parser.Lex();
3747
3748 if (Value != "xx") {
3749 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3750 return false;
3751 }
3752
3753 if (!isABI_O32()) {
3754 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3755 return false;
3756 }
3757
3758 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3759 return true;
3760 }
3761
3762 if (Lexer.is(AsmToken::Integer)) {
3763 unsigned Value = Parser.getTok().getIntVal();
3764 Parser.Lex();
3765
3766 if (Value != 32 && Value != 64) {
3767 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3768 return false;
3769 }
3770
3771 if (Value == 32) {
3772 if (!isABI_O32()) {
3773 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3774 return false;
3775 }
3776
3777 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3778 } else
3779 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3780
3781 return true;
3782 }
3783
3784 return false;
3785 }
3786
ParseDirective(AsmToken DirectiveID)3787 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3788 MCAsmParser &Parser = getParser();
3789 StringRef IDVal = DirectiveID.getString();
3790
3791 if (IDVal == ".cpload")
3792 return parseDirectiveCpLoad(DirectiveID.getLoc());
3793 if (IDVal == ".dword") {
3794 parseDataDirective(8, DirectiveID.getLoc());
3795 return false;
3796 }
3797 if (IDVal == ".ent") {
3798 StringRef SymbolName;
3799
3800 if (Parser.parseIdentifier(SymbolName)) {
3801 reportParseError("expected identifier after .ent");
3802 return false;
3803 }
3804
3805 // There's an undocumented extension that allows an integer to
3806 // follow the name of the procedure which AFAICS is ignored by GAS.
3807 // Example: .ent foo,2
3808 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3809 if (getLexer().isNot(AsmToken::Comma)) {
3810 // Even though we accept this undocumented extension for compatibility
3811 // reasons, the additional integer argument does not actually change
3812 // the behaviour of the '.ent' directive, so we would like to discourage
3813 // its use. We do this by not referring to the extended version in
3814 // error messages which are not directly related to its use.
3815 reportParseError("unexpected token, expected end of statement");
3816 return false;
3817 }
3818 Parser.Lex(); // Eat the comma.
3819 const MCExpr *DummyNumber;
3820 int64_t DummyNumberVal;
3821 // If the user was explicitly trying to use the extended version,
3822 // we still give helpful extension-related error messages.
3823 if (Parser.parseExpression(DummyNumber)) {
3824 reportParseError("expected number after comma");
3825 return false;
3826 }
3827 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3828 reportParseError("expected an absolute expression after comma");
3829 return false;
3830 }
3831 }
3832
3833 // If this is not the end of the statement, report an error.
3834 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3835 reportParseError("unexpected token, expected end of statement");
3836 return false;
3837 }
3838
3839 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3840
3841 getTargetStreamer().emitDirectiveEnt(*Sym);
3842 CurrentFn = Sym;
3843 return false;
3844 }
3845
3846 if (IDVal == ".end") {
3847 StringRef SymbolName;
3848
3849 if (Parser.parseIdentifier(SymbolName)) {
3850 reportParseError("expected identifier after .end");
3851 return false;
3852 }
3853
3854 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3855 reportParseError("unexpected token, expected end of statement");
3856 return false;
3857 }
3858
3859 if (CurrentFn == nullptr) {
3860 reportParseError(".end used without .ent");
3861 return false;
3862 }
3863
3864 if ((SymbolName != CurrentFn->getName())) {
3865 reportParseError(".end symbol does not match .ent symbol");
3866 return false;
3867 }
3868
3869 getTargetStreamer().emitDirectiveEnd(SymbolName);
3870 CurrentFn = nullptr;
3871 return false;
3872 }
3873
3874 if (IDVal == ".frame") {
3875 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3876 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3877 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3878 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3879 reportParseError("expected stack register");
3880 return false;
3881 }
3882
3883 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3884 if (!StackRegOpnd.isGPRAsmReg()) {
3885 reportParseError(StackRegOpnd.getStartLoc(),
3886 "expected general purpose register");
3887 return false;
3888 }
3889 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3890
3891 if (Parser.getTok().is(AsmToken::Comma))
3892 Parser.Lex();
3893 else {
3894 reportParseError("unexpected token, expected comma");
3895 return false;
3896 }
3897
3898 // Parse the frame size.
3899 const MCExpr *FrameSize;
3900 int64_t FrameSizeVal;
3901
3902 if (Parser.parseExpression(FrameSize)) {
3903 reportParseError("expected frame size value");
3904 return false;
3905 }
3906
3907 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3908 reportParseError("frame size not an absolute expression");
3909 return false;
3910 }
3911
3912 if (Parser.getTok().is(AsmToken::Comma))
3913 Parser.Lex();
3914 else {
3915 reportParseError("unexpected token, expected comma");
3916 return false;
3917 }
3918
3919 // Parse the return register.
3920 TmpReg.clear();
3921 ResTy = parseAnyRegister(TmpReg);
3922 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3923 reportParseError("expected return register");
3924 return false;
3925 }
3926
3927 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3928 if (!ReturnRegOpnd.isGPRAsmReg()) {
3929 reportParseError(ReturnRegOpnd.getStartLoc(),
3930 "expected general purpose register");
3931 return false;
3932 }
3933
3934 // If this is not the end of the statement, report an error.
3935 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3936 reportParseError("unexpected token, expected end of statement");
3937 return false;
3938 }
3939
3940 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3941 ReturnRegOpnd.getGPR32Reg());
3942 return false;
3943 }
3944
3945 if (IDVal == ".set") {
3946 return parseDirectiveSet();
3947 }
3948
3949 if (IDVal == ".mask" || IDVal == ".fmask") {
3950 // .mask bitmask, frame_offset
3951 // bitmask: One bit for each register used.
3952 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3953 // first register is expected to be saved.
3954 // Examples:
3955 // .mask 0x80000000, -4
3956 // .fmask 0x80000000, -4
3957 //
3958
3959 // Parse the bitmask
3960 const MCExpr *BitMask;
3961 int64_t BitMaskVal;
3962
3963 if (Parser.parseExpression(BitMask)) {
3964 reportParseError("expected bitmask value");
3965 return false;
3966 }
3967
3968 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3969 reportParseError("bitmask not an absolute expression");
3970 return false;
3971 }
3972
3973 if (Parser.getTok().is(AsmToken::Comma))
3974 Parser.Lex();
3975 else {
3976 reportParseError("unexpected token, expected comma");
3977 return false;
3978 }
3979
3980 // Parse the frame_offset
3981 const MCExpr *FrameOffset;
3982 int64_t FrameOffsetVal;
3983
3984 if (Parser.parseExpression(FrameOffset)) {
3985 reportParseError("expected frame offset value");
3986 return false;
3987 }
3988
3989 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3990 reportParseError("frame offset not an absolute expression");
3991 return false;
3992 }
3993
3994 // If this is not the end of the statement, report an error.
3995 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3996 reportParseError("unexpected token, expected end of statement");
3997 return false;
3998 }
3999
4000 if (IDVal == ".mask")
4001 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4002 else
4003 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4004 return false;
4005 }
4006
4007 if (IDVal == ".nan")
4008 return parseDirectiveNaN();
4009
4010 if (IDVal == ".gpword") {
4011 parseDirectiveGpWord();
4012 return false;
4013 }
4014
4015 if (IDVal == ".gpdword") {
4016 parseDirectiveGpDWord();
4017 return false;
4018 }
4019
4020 if (IDVal == ".word") {
4021 parseDataDirective(4, DirectiveID.getLoc());
4022 return false;
4023 }
4024
4025 if (IDVal == ".option")
4026 return parseDirectiveOption();
4027
4028 if (IDVal == ".abicalls") {
4029 getTargetStreamer().emitDirectiveAbiCalls();
4030 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4031 Error(Parser.getTok().getLoc(),
4032 "unexpected token, expected end of statement");
4033 // Clear line
4034 Parser.eatToEndOfStatement();
4035 }
4036 return false;
4037 }
4038
4039 if (IDVal == ".cpsetup")
4040 return parseDirectiveCPSetup();
4041
4042 if (IDVal == ".module")
4043 return parseDirectiveModule();
4044
4045 return true;
4046 }
4047
LLVMInitializeMipsAsmParser()4048 extern "C" void LLVMInitializeMipsAsmParser() {
4049 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4050 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4051 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4052 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4053 }
4054
4055 #define GET_REGISTER_MATCHER
4056 #define GET_MATCHER_IMPLEMENTATION
4057 #include "MipsGenAsmMatcher.inc"
4058