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