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